# Animiertes JPanel dynamisch wechseln



## elGurko (25. Jul 2012)

Hallo,
ich bin relativ neu in der Programmiering von graphischen Oberflächen und habe ein Problem. Ich habe einen kleinen Sidescroller programmiert, in dem man mit einer Figur auf Zombiejagd geht. Das Spiel an sich funktioniert wunderbar, nur wollte ich zur Krönung noch ein schönes Menü einbauen.

Meine Fensterklasse sieht so aus

```
public class GameFrame extends JFrame{
	
	private Menu menu = new Menu(this); 
	private World world = new World();
	
	public GameFrame(String name) {
		super(name);
		this.setPreferredSize(new Dimension(1100,625));
		this.setResizable(false);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		
		this.add(menu);
		this.pack();
	}
	
	public void startNewGame() {
		this.remove(menu);
		this.add(world);
		this.pack();
		world.startGame();
	}
	

}
```

Ich habe zwei Klassen die von JPanel abgeleitet sind: World (die eigentliche Spielfläche) und Menu.
World ist ist ein KeyListener hinzugefügt, der die Steuerung des Helden übernimmt. Die startGame() Methode von world startet die Gameloop inkl. der Neuzeichnung des JPanles alle 10 Millisekunden (die Zeichnung in einem eigenen Thread).
Das Spiel startet mit dem Menü. Menu wird im Konstruktor das GameFrame Object übergeben, weil es dessen Inhalt auf Knopfdruck ändern muss. Dem Menü sind mehrere Buttons hinzugefügt, darunter auch ein "new Game" Button. Dessen ActionListener ruft die startNewGame() methode von GameFrame auf.

Menu:

```
public class Menu extends JPanel {

	private final Image background = new ImageIcon(Menu.class.getResource("../images/menu.jpeg")).getImage();
	private ArrayList<Cloud> clouds = new ArrayList<>();

	private GameFrame mother;

	public Menu(GameFrame mother) {

		this.mother = mother;

		this.setPreferredSize(new Dimension(1100, 600));
		this.setLayout(null);

		JButton newGame = new JButton("New Game");
		newGame.addActionListener(new NewGameListener());
		newGame.setBounds(800, 150, 200, 30);
		this.add(newGame);

		JButton options = new JButton("Options");
		options.setBounds(800, 220, 200, 30);
		this.add(options);

		JButton credits = new JButton("Credits");
		credits.setBounds(800, 290, 200, 30);
		this.add(credits);

		JButton quit = new JButton("Quit");
		quit.addActionListener(new QuitListener());
		quit.setBounds(800, 360, 200, 30);
		this.add(quit);


		for (int i = 0; i < 7; i++) {
			this.clouds.add(new Cloud(new Random().nextInt(1100), new Random().nextInt(50) + 20));
		}		
	}
	
	public void paint(Graphics g) {
		g.drawImage(background, 0, 0, null);
		for (Cloud c : this.clouds) {
			g.drawImage(Cloud.CLOUD_PIC, c.getXCoor(), c.getYCoor(), null);
		}
		super.paintComponents(g);
	}

	private class QuitListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent arg0) {
			mother.dispose();
		}

	}

	private class NewGameListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			mother.startNewGame();
		}
	}

}
```

Was dann passiert ist seltsam: 
Die Logik des Spiels läuft, es werden auch Statusinformationen ausgegeben. Jedoch ist hat sich das Panel nicht verändert. Der Button ist quasi eingefroren. Ich kann auch meinen Helden auch nicht bewegen, der KeyListener funktioniert also auch irgendwie nicht. 
Am Ende, wenn mich meine Gegner getötet haben, wird das letzte Game-over Bild des World-Panels allerdings angezeigt. 

Ich hoffe ihr könnt mir helfen und meine Beschreibung war ausführlich genug. Wenn ich mehr Code posten soll, einfach schreiben


----------



## Bile Demon (25. Jul 2012)

Deine Paint-Methode sieht schonmal falsch aus. Du meinst wohl 
	
	
	
	





```
super.paintComponent(g)
```
. Außerdem sollte dieser Aufruf VOR deinen eigenen Zeichenoperationen stehen und nicht dahinter.


----------



## elGurko (25. Jul 2012)

Hi,
nein, ich habe mehrer Buttons in meinem Panel Container, also super.paintComponents(g). Und dovor schreiben würde sie ja mit dem Hintergrundbild übermalen.


----------



## Bile Demon (25. Jul 2012)

```
this.setVisible(true);
this.add(menu);
this.pack();
```

Das würde ich so z.B. nicht machen. Normalerweise sollte setVisible(true) als letztes aufgerufen werden, wenn das Objekt fertig konfiguriert ist.


----------

