# Zugriff auf übergeordnete Klasse



## tdc (3. Apr 2010)

Hi!
Ich versuche derzeit ein kleines Spiel zu programmieren. Dabei habe ich folgendes Problem: Ich habe eine Klasse GameFrame, dass die zwei JPanels GamePanel und MenuPanel beinhaltet, die jeweils eigene Klassen sind.

```
...

public class GameFrame
	extends JFrame
{
	GameFrame()
	{
		GamePanel myGamePanel = new GamePanel(650,600);
		MenuPanel myMenuPanel = new MenuPanel();
		
		...
		
		JPanel MainPanel = new JPanel();
		MainPanel.add(myGamePanel);
		MainPanel.add(myMenuPanel);
		
		this.add(MainPanel);
                ...
```
Wenn im MenuPanel ein Button angeklickt wird, soll eine Variable im GamePanel geändert werden (ein boolean von false auf true bzw. umgekehrt).
Es ist ja kein Problem vom GameFrame aus auf das GamePanel zuzugreifen und dort die Variable zu ändern. Wie kann ich allerdings vom MenuPanel aus auf das GamePanel zugreifen?


----------



## Final_Striker (3. Apr 2010)

Du kannst z.B. dem MenuPanel eine Referenz auf das GamePanel mitgeben.


----------



## André Uhres (3. Apr 2010)

Man kann eine neue Klasse (M) machen, die eine solche Variable enthält und seine Listener informiert, wenn sie ändert (Model). GamePanel registriert sich dort als Listener. Dann macht man noch eine neue Klasse (C), die (M) kennt um dessen Variable auf Anfrage ändern zu können (Controller). Der Controller (C) muss dem MenuPanel bekannt sein. Über sie kann MenuPanel dann bequem die Variable im Model (M) ändern. Sowie das geschieht, informiert das Model (M) seine Listener, also das GamePanel. So einfach ist das


----------



## tdc (3. Apr 2010)

Final_Striker hat gesagt.:


> Du kannst z.B. dem MenuPanel eine Referenz auf das GamePanel mitgeben.



Das habe ich schon probiert, das Problem ist nur, ich habe in der Klasse GamePanel eine Methode setPause(boolean pause) mit der man die Variable ändern kann. Wenn ich sie dann allerdings in der Klasse MenuPanel mit GamePanel.setPause(true); aufrufen will, ist die Methode nicht bekannt.


```
...
public class GamePanel
	extends JPanel implements Runnable, KeyListener
{
        ...
	public void setPause(boolean pause)
	{
		this.pause = pause;
	}
        ...
```


```
...
public class MenuPanel
	extends JPanel implements ActionListener
{
	JPanel GamePanel;
	
	MenuPanel(JPanel GamePanel)
	{
		this.setPreferredSize(new Dimension(150,600));
		this.setLayout(null);
		this.add(BallsLabel());
		this.add(ScoreLabel());
		this.add(ButtonLevelEditor());
		this.add(ButtonEndGame());
		for(int i = 0; i < this.getComponents().length; i++)
		{
			this.getComponents()[i].setFocusable(false);
		}
		this.GamePanel = GamePanel;
	}
	...
	public void actionPerformed(ActionEvent e)
	{
		JButton mysource = (JButton) e.getSource();
		if(mysource.getText() == "Level Editor")
		{
			LevelEditor myLevelEditor = new LevelEditor();
			GamePanel.setPause(true);
		}
		if(mysource.getText() == "Spiel Beenden")
		{
			System.exit(0);
		}
	}
}
```



André Uhres hat gesagt.:


> Man kann eine neue Klasse (M) machen, die eine solche Variable enthält und seine Listener informiert, wenn sie ändert (Model). GamePanel registriert sich dort als Listener. Dann macht man noch eine neue Klasse (C), die (M) kennt um dessen Variable auf Anfrage ändern zu können (Controller). Der Controller (C) muss dem MenuPanel bekannt sein. Über sie kann MenuPanel dann bequem die Variable im Model (M) ändern. Sowie das geschieht, informiert das Model (M) seine Listener, also das GamePanel. So einfach ist das


Ok... ich probiere das mal aus.


----------



## André Uhres (4. Apr 2010)

tdc hat gesagt.:


> Wenn ich sie dann allerdings in der Klasse MenuPanel mit GamePanel.setPause(true); aufrufen will, ist die Methode nicht bekannt.
> 
> ```
> JPanel GamePanel;
> ```


Klar, weil du's als einfaches "JPanel" deklarierst. "JPanel" kennt ja keine Methode "setPause". Versuch's mal als "*GamePanel myGamePanel*" ins *MenuPanel *zu setzen.

```
GamePanel myGamePanel;
...
myGamePanel.setPause(true);
```


----------



## tdc (4. Apr 2010)

André Uhres hat gesagt.:


> Klar, weil du's als einfaches "JPanel" deklarierst. "JPanel" kennt ja keine Methode "setPause". Versuch's mal als "*GamePanel myGamePanel*" ins *MenuPanel *zu setzen.
> 
> ```
> GamePanel myGamePanel;
> ...



Oh, danke. Jetzt kommt in Eclipse keine Fehlermeldung mehr. Nur wenn ich dann den Button anklicke kommt eine Null-Pointer Exception mit einem Verweis auf

```
myGamePanel.setPause(true);
```
Nur warum sie kommt habe ich keine Ahnung. :bahnhof:


----------



## Final_Striker (4. Apr 2010)

poste mal deinen aktuellen code.


----------



## tdc (5. Apr 2010)

```
...
public class GamePanel
	extends JPanel implements Runnable, KeyListener
{
	...
	boolean pause = false;
	...
	public void setPause(boolean pause)
	{
		this.pause = pause;
	}
	...
}
```


```
...
public class MenuPanel
	extends JPanel implements ActionListener
{
	...
	public JButton ButtonLevelEditor()
	{
		JButton ButtonLevelEditor = new JButton("Level Editor");
		ButtonLevelEditor.setBounds(10, 510, 130, 40);
		ButtonLevelEditor.addActionListener(this);
		
		return ButtonLevelEditor;
	}
        ...
	public void actionPerformed(ActionEvent e)
	{
		JButton mysource = (JButton) e.getSource();
		if(mysource.getText() == "Level Editor")
		{
			LevelEditor myLevelEditor = new LevelEditor();
			myGamePanel.setPause(true);
		}
		if(mysource.getText() == "Spiel Beenden")
		{
			System.exit(0);
		}
	}
}
```


----------



## eRaaaa (5. Apr 2010)

Der Codeausschnitt hilft wahrscheinlich nicht viel, da du den relevanten Teil weg lässt *g*
Sieht ja so aus als wenn [c]myGamePanel[/c] null ist.

Paar Posts vorher hattest du ja stehen

```
MenuPanel(JPanel GamePanel)
    {
      //.....
        this.GamePanel = GamePanel;
    }
```

hast du die Zeilen umgeändert ? 

 MenuPanel(GamePanel gamePanel)
    {
      //.....
        this.myGamePanel = gamePanel;
    }

Bzw, zeige doch mal deine aktuelle komplette Klasse MenuPanel!


----------



## tdc (5. Apr 2010)

eRaaaa hat gesagt.:


> Der Codeausschnitt hilft wahrscheinlich nicht viel, da du den relevanten Teil weg lässt *g*


Stimmt sry.


eRaaaa hat gesagt.:


> Bzw, zeige doch mal deine aktuelle komplette Klasse MenuPanel!


Ok.

```
package game;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class MenuPanel
	extends JPanel implements ActionListener
{
	GamePanel myGamePanel;
	
	MenuPanel(JPanel GamePanel)
	{
		this.setPreferredSize(new Dimension(150,600));
		this.setLayout(null);
		this.add(BallsLabel());
		this.add(ScoreLabel());
		this.add(ButtonLevelEditor());
		this.add(ButtonEndGame());
		for(int i = 0; i < this.getComponents().length; i++)
		{
			this.getComponents()[i].setFocusable(false);
		}
	}
	
	public JLabel BallsLabel()
	{
		JLabel BallsLabel = new JLabel("Bälle:");
		BallsLabel.setBounds(10, 10, 100, 20);
		
		return BallsLabel;
	}
	
	public JLabel ScoreLabel()
	{
		JLabel ScoreLabel = new JLabel("Punkte:");
		ScoreLabel.setBounds(10, 30, 100, 20);
		
		return ScoreLabel;
	}
	
	public JButton ButtonLevelEditor()
	{
		JButton ButtonLevelEditor = new JButton("Level Editor");
		ButtonLevelEditor.setBounds(10, 510, 130, 40);
		ButtonLevelEditor.addActionListener(this);
		
		return ButtonLevelEditor;
	}
	
	public JButton ButtonEndGame()
	{
		JButton ButtonEndGame = new JButton("Spiel Beenden");
		ButtonEndGame.setBounds(10, 560, 130, 40);
		ButtonEndGame.addActionListener(this);
		
		return ButtonEndGame;
	}

	public void actionPerformed(ActionEvent e)
	{
		JButton mysource = (JButton) e.getSource();
		if(mysource.getText() == "Level Editor")
		{
			LevelEditor myLevelEditor = new LevelEditor();
			myGamePanel.setPause(true);
		}
		if(mysource.getText() == "Spiel Beenden")
		{
			System.exit(0);
		}
	}
}
```


----------



## Final_Striker (5. Apr 2010)

Du gibst dem MenuPanel Konstruktor zwar den GamePanel mit, machst aber nichts damit.


```
MenuPanel(JPanel GamePanel)
    {
        this.myGamePanel = GamePanel;

        ...
        ...
        ...
    }
```

Tipp: Variablen Namen fangen mir einem kleinen Buchstaben an, auch als Parameter.
Anstatt MenuPanel(JPanel GamePanel) lieber MenuPanel(JPanel gamePanel). ;-)


----------



## tdc (5. Apr 2010)

Final_Striker hat gesagt.:


> Du gibst dem MenuPanel Konstruktor zwar den GamePanel mit, machst aber nichts damit.



Wirklich? ich rufe doch die Methode setPause() vom GamePanel auf... ???:L


```
...
    GamePanel myGamePanel;
    
    MenuPanel(JPanel GamePanel)
        ...
            myGamePanel.setPause(true);
        ...
```


----------



## eRaaaa (5. Apr 2010)

tdc hat gesagt.:


> Wirklich? ich rufe doch die Methode setPause() vom GamePanel auf... ???:L



aber dein GamePanel ist null(du deklarierst das nur) ! Im Moment ist myGamePanel != GamePanel(also das was übergeben wird)


Wie gesagt, ändere deinen Konstruktor wie folgt ab

```
MenuPanel(GamePanel gamePanel)
{
//.....
this.myGamePanel = gamePanel;
}
```


----------



## tdc (5. Apr 2010)

Danke, es geht jetzt!


----------

