# Minesweeper: 2D Feld von JButtons anlegen



## Nikolas (15. Aug 2007)

Hallo

Ich bin letztens von Windows auf Mac umgestiegen und habe deswegen von Pascal zu Java wechseln müssen. 
Um jetzt etwas in das GUI Programmieren reinzukommen, wollte ich mir ein kleines MineSweeper bauen.


```
import javax.swing.*; 
import java.util.Random; 
import java.awt.event.*; 
 

public class MineSweeper {


	public static void main( String[] args ) 
	  { 
		
		int x=5; // Anzahl Kästchen
		int y=3;
		int mineCount = 50; // Bomben im Feld
		double mineProb = x*y / mineCount; // zu Testen
		
		boolean[][] Bomb = new boolean[ x ][ y ];
		int[][] Zahlen = new int[ x ][ y ];
		

	    JFrame f = new JFrame( "MineSweeper"); 
	    f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 
	    int frameWidth = 500;
	    int frameHeight = 500;
		int xOffset = 15;
		int yOffset = 15;
		
	    f.setSize(frameWidth , frameHeight ); 
	    
	    f.setVisible( true ); 
	    
	    // Die MinenButtons
		JButton[][] Buttons = new JButton[x][y];
		
	
		int bWidth = (frameWidth - 2*xOffset) / x;
		int bHeight = (frameHeight - 2*yOffset) / y; 
	    
		// Setzen der Buttons:
		for (int i=0; i<x; i++) {
			for (int j=0;j<y; j++) {
				Buttons[i][j] = new JButton();
				f.add(Buttons[i][j]);
				
				Buttons[i][j].setSize(bWidth,bHeight);

				Buttons[i][j].setLocation(xOffset + i*bWidth,yOffset + j* bHeight);
			
				Buttons[i][j].setText("x="+i+"y="+j);
				
				}
		}
		
	  } 
 
}
```

Also eigentlich nichts spektakuläres. (Die Größen sind noch nicht perfekt, aber egal). Wenn ich das jetzt laufen lasse, bauen sich fast alle Buttons passend auf. Nur der letzte Button hat die Größe des Frames und überdeckt die anderen, sobald ich auf ihn klicke.  
Kann mir da jemand weiterhelfen?

Nikolas


----------



## Wildcard (15. Aug 2007)

Spar dir das ganze setSize und setLocation zeug und nimm GridLayout.


----------



## SlaterB (15. Aug 2007)

f.getContentPane().setLayout(new GridLayout(5, 3));


----------



## Nikolas (15. Aug 2007)

Davon habe ich bis gerade eben noch nie etwas gehört. Und da ich auf dieses Problem gestoßen bin, würde ich es gerne lösen. Mir gehts nicht so sehr darum, ein Minesweeper zu haben, als die auftretenden Probleme zu lösen.


----------



## SlaterB (15. Aug 2007)

nun, das Standard-Layout des ContentPanes, BorderLayout,
interessiert sich für setLocation und ähnliches nicht die Bohne,

setLocation ist sowieso eine fragwürdige Taktik
und zudem ist Layout in Swing allgemein eine sehr komische Sache,

versuche da gerade anfangs nichts von alleine, sondern orientiere dich an funktionierenden Vorgaben,
siehe auch
http://java.sun.com/docs/books/tutorial/uiswing/layout/index.html


----------



## Nikolas (15. Aug 2007)

Warum ist SetLocation eine fragwürdige Taktik? Bei fast allen Buttons wird genau das gemacht was ich will. Und was soll man machen, wenn man die Buttons in einen Kreis anordnen will, oder sonstwie?


----------



## SlaterB (15. Aug 2007)

>  Bei fast allen Buttons wird genau das gemacht 

was sind denn 'fast alle Buttons'?
meinst du fast alle Beispiele? also ich kann mich spontan an keins erinnern,

ich lese z.B. oft die oben angegeben Sun-Doku, da wird das wohl auch nicht benutzt,

Buttons in einem Kreis habe ich auch noch nie angeordnet,
dafür wäre das vielleicht passend, das mag gerne sein, ein Spezialfall,

aber gerade bei so ordentlichen Tabellenstrukturen ist das der falsche Ansatz,
ein simples new GridLayout(5, 3); erspart 15 Koordinaten-Berechnungen + Co.

es hindert dich natürlich niemand, das dennoch zu tun,
interessant dann:
es gibt noch setLayout(null) + setBounds(x,y,width,height)


----------



## Nikolas (15. Aug 2007)

>was sind denn 'fast alle Buttons'? 

fast alle Buttons heisst, alle bis auf endlich viele Ausnahmen. Wenn ich 3*5 Buttons habe, ist der Button an Koordinate 3,5 so groß wie das ganze Frame. Das CodeStück oben ist kompilierbar, da kannst du es am Besten sehen. 

Danke für deine Hilfe 

// Ich habe jetzt noch das Layout auf Null gesetzt und jetzt sieht es genau so aus, wie ich es haben wollte  :toll:


----------



## Wildcard (15. Aug 2007)

null-'Layout' ist für alles ausser einer freien Zeichenfläche falsch bis bestenfalls fragwürdig.
Gewöhn dir LayoutManager an.


----------



## Nikolas (15. Aug 2007)

Warum soll das Vorgehen denn falsch sein?


----------



## Wildcard (15. Aug 2007)

1. Mehr Arbeit
2. Unflexibel
3. Das Layout kann sich nicht anpassen wenn sich die Fenstergröße ändert
4. ScrollPanes funktionieren nicht richtig
5. Ändert sich das Look and Feel (oder auch nur die Schriftart oder Größe) zerbröselt dein mühsam erstelltes Layout.


----------



## merlin2 (17. Aug 2007)

Wobei 3. und 5. Unterpunkte von 2. sein sollten. :bae:


----------



## Kaladial (17. Aug 2007)

also eigentlich geb ich wildcard recht... 
finde null an und für sich nicht so toll ... 

wenn ich mir dann aber meine programme anguck ... 90 % meine layouts sind trotzdem xyLayouts (oder jetzt halt null-Layouts) ich bekomm jedesmal aufs neue ne kriese mit den Layout-Managern... nie machen sie das was sie sollen... is echt zum haare raufen...


----------



## Wildcard (17. Aug 2007)

Ich würde auf PEBKAC tippen  :wink:


----------



## Kaladial (17. Aug 2007)

PEBKAC ?


----------



## SlaterB (17. Aug 2007)

google? (äh: Suchmaschine?)


----------



## Nikolas (17. Aug 2007)

Die Punkte von Wildcard finde ich etwas komisch. 
Mehr Arbeit: kann sein, dafür sieht es aber so aus, wie ich es will, und nicht wie Java will, und genau das will ich als Programmierer doch erreichen. 

Unflexibel, kann sich nicht einer neuen Fenstergröße anpassen: Sobald man sauber programmiert, ist das wohl wirklich kein Problem. Wenn man also nicht stupide einen Button auf die Größe 10,10 setzt, sondern eher auf 10Prozent der Breite des Containers, kann man da wunderbar das Formular durch die Gegend ziehen. 

zu 4 und 5 kann ich mangels Erfahrung mit Java noch nichts sagen. 

Von da her finde ich es etwas komisch, ein legitimes Vorgehen, dass sauber angewand sehr gut funktionieren kann als falsch abzutun, nur weil man selbst etwas anders macht. Vielleicht werde ich später auch auf den Layout Manager benutzen, aber nicht wegen der Argumente von Wildcard.


----------



## SlaterB (17. Aug 2007)

> Wenn man also nicht stupide einen Button auf die Größe 10,10 setzt, sondern eher auf 10Prozent der Breite des Containers, kann man da wunderbar das Formular durch die Gegend ziehen.

wie willst du denn das machen? zum Programmstart, klar,
aber dann bei jeder Größenänderung neuberechnen, neu anordnen?

gratuliere, ein Schritt weiter auf dem Weg, die Standardlayouts Punkt für Punkt nachzubauen,
aber wieso nicht gleich die fertigen Endprodukte verwenden?

> ein legitimes Vorgehen, dass sauber angewand sehr gut funktionieren kann als falsch abzutun

das Abtun bezieht sich nur auf die 5 Zeilen Code setLayout(null) + setBounds/ setLocation, 
wie es der Erfahrung nach in 99% aller Fälle für immer bleiben wird (oder man zu einem Java-Layout wechselt)

wenn du natürlich ein riesiges Framework baust, dann kann man das nicht mehr als 'unflexibel' abtun, richtig,
sondern höchstens noch als 'nachbauen' abtun 

für Speziallayouts wie Buttons im Kreis mag das natürlich unausweichlich sein, keine Frage


----------



## Nikolas (17. Aug 2007)

>aber wieso nicht gleich die fertigen Endprodukte verwenden?

Damit ich beim nachbauen noch etwas mehr über die Komponenten lernen kann. Ausserdem will ich schon wissen, wie das ganze intern funktioniert. Irgendwann werde ich sicher mal ein eigenes Layout anwenden wollen und dann bringt es mir wenig, wenn ich nur den Layout Manager bedienen wollen.


----------



## SlaterB (17. Aug 2007)

na das ist natürlich immer ein Sonderargument, 
von dem Standpunkt aus darfst du niemanden etwas vorwerfen, das kann man nicht per Default berücksichtigen

sonst könnte man ja nicht mal mehr meckern, wenn jemand mit einer leeren Zeichfläche anfängt und da alle Komponenten per Hand malt,
statt die vergleichsweise hochwertigen JPanels, JButtons & Co. zu verwenden, mit vergleichesweise komfortablen simplen setLocation()


----------

