# Menü für Snakespiel in einzelnem JFrame



## Javaanfänger12 (9. Dez 2012)

Hallo,
ich versuche gerade ein JFrame (Menü) zu erstellen, in dem ein Button ist, mit dem man wiederum ein neues JFrame (Spielfeld) öffnen kann.
Der Ansatz funktioniert auch soweit, jedoch bleibt das neue JFrame (Spielfeld) leer.
Eigentlich sollten darin 30 x 30 Buttons sein, die mit ihrer Hintergrundfarbe eine Schlange darstellen (Snakespiel).
Erst wenn die Schlange (die leider nicht zu sehen ist) eine Wand erreicht hat und eine Meldung aufgeht, dass man verloren hat, erscheint das ganze Spielfeld.
Öffne ich das JFrame (Spielfeld) jedoch direkt aus der public static void main(), dann funktioniert alles einwandfrei.

Wie kann ich es schaffen, dass der Inhalt des Spielfeldfensters auch angezeigt wird, wenn es aus einer anderen als der main() Klasse heraus aufgerufen wird?

IDE: Eclipse


```
private class klickclassstart implements ActionListener		{
		
		public void actionPerformed(ActionEvent event)	{
			

			Schlange.schlange();
			Labyrinth.feldinhalt();
			Essen.essen();
		
			Spielfeld spielfeld = new Spielfeld();
			spielfeld.setLocation(425, 150);
			spielfeld.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			spielfeld.setSize(380, 400);
			spielfeld.setVisible(true);
			
			Steuern steuern = new Steuern();
			steuern.setLocation(490, 550);
			steuern.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			steuern.setSize(250, 150);
			steuern.setVisible(true);
			
			Tick.tick();	
			
			
		}
		
	}
```

Das ist die Klasse des Buttons (im Menü), der das eigentliche Spielfeld und zusätzlich ein Steuerungsfenster öffnen soll. Die Fenster gehen zwar in der richtigen Größe und Position auf jedoch bleiben sie vorerst leer.
Eigentlich kann es ja nur daran liegen, dass die JFrames nicht aktualisiert werden, da die Schlage anscheinend im Hintergrund weiterläuft (Sonst könnte sie ja nicht an die Wand laufen)

Vielen dank für jede Hilfe.


----------



## Fab1 (9. Dez 2012)

Auf die Idee eine Schlange mit Buttons darzustellen bin ich auch noch nicht gekommen 

Wenn sich die Buttons bewegen rufst du dann repaint() und auch validate() auf dem JFrame auf? Wäre so meine erste Vermutung, dass es an dem Validate also neu ausrichten der Komponenten liegt.


----------



## Kevin94 (9. Dez 2012)

Die Signatur von Volvagia drückt dein Problem ziemlich genau aus:


> Javanische Bauernregel: Wenn das GUI nicht reagiert, wahrscheinlich der EDT blockiert.



Du musst das ganze in einem eigenen Thread ausführen. Genauer gesagt nur den GameLoop, also den Teil des Codes, der die Schlange bewegt und dann mit sleep den EDT blockiert (auf dem EventListener und das Rendering ausgeführt werden), aber ich blicke nicht ganz welche Methode das bei dir sein soll.


----------



## Javaanfänger12 (9. Dez 2012)

Danke für die schnelle Antwort!

Die Klasse, die die Schlange ( Buttonfarbe ) bewegt ist dieser: 


```
public class Tick{
	
	static int wiederholen = 1;
	static int speed = 500;
	
	public static  void tick()  {
		
		while (wiederholen == 1) {
			
			Schlangenbewegung.bewegen();      //Schlangenarray erneuern							  	
			
			Spielfeld.spielfeldrepaint();    	//Spielfeld erneuern
												
			Steuern.scorelabel();
					
					try {
						
						Thread.sleep(speed);									//Geschwindigkeit der Schlange
						
					} 
					catch (InterruptedException e) {
						
						e.printStackTrace();
						
					}
							
		}
		
	}
```

Ich habe zwei Arrays: Das eine ist ein Buttonarray und das andere ein Integerarray, beide haben 900 Plätze 

Die Klasse Schlangenbewegung (s.o.) verändert die Zahlen im Integerarray je nach dem welche Richtung im Steuerungsframe zuletzt gedrückt wurde.

Danach wird in Abhängigkeit zu den Werten im Integerarray die jeweilige Farbe der Buttons des Buttonarrays angepasst.
Aktualisieren tue ich das indem ich alle Buttons in ein Panel eingefügt habe und dieses dann mit 


```
Spielfeld.panel.repaint();
```

erneuere.

vaidate() habe ich nicht benutzt. Wo müsste ich das dann einbauen? 
Komisch ist eben nur, das aktualisieren ohne das vorgeschaltete Menüfenster funktioniert.

Der Loop ist bei mir die Klasse Tick (s.o.). Wie mache ich diese in einen einzelnen Thread?
Ich kenne mich da noch nicht so aus.


----------



## Kevin94 (9. Dez 2012)

Hatte ich mir gedacht. Der GameLoop wird auf dem EDT ausgeführt. Du musst das ganze in einen eigenen Thread packen, z.B. so:


```
public class Tick{
    
    static int wiederholen = 1;
    static int speed = 500;
    
    public static  void tick()  {
        new Thread(new Runnable(){
        public void run(){ 
        while (wiederholen == 1) {
            Schlangenbewegung.bewegen();      //Schlangenarray erneuern                             
            Spielfeld.spielfeldrepaint();       //Spielfeld erneuern
            Steuern.scorelabel();
                    try {
                        Thread.sleep(speed);                                    //Geschwindigkeit der Schlange
                    } 
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
        }
        }}).start();
        
    }
}
```


----------



## Javaanfänger12 (9. Dez 2012)

Vielen Dank Kevin94!

Genau das war das Problem.

Jetzt funktioniert es genau wie es soll.

Wenn ich jetzt auf den Startbutton im Menü drücke öffnet sich das Spielfeld und wird richtig angezeigt.
Das Menüfenster (Startscreen) soll sich jetzt zusätzlich glechzeitig schließen. 
Ich habe es schon mit startscreen.setVisible(false) und startscreen.dispose() probiert aber Eclipse zeigt immer einen Error (bei beiden Varianten wird "startscreen" rot unterstrichen). 

Wie schließe ich das JFrame Startscreen sobald ich den Startbutton betätige?


----------

