Klassenübergreifende Methoden

Status
Nicht offen für weitere Antworten.

Zenic

Mitglied
Hi,

Ich vermute zwar, dass die Erklärung zu den absoluten Basics gehört, aber ich komme einfach nicht drauf. Also wir haben 2 Klassen, die erste ist die „Main“ Klasse in der, im Konstruktor, die GUI erstellt wird. Jetzt möchte ich in der 2. Klasse eine Methode der ersten Klasse aufrufen. Ich gehe in dem Fall immer wie folgt vor:

FirstClass variablenName = new FirstClass();
variablenName.methodenName();

Jetzt wird jedoch der Konstruktor erneut aufgerufen und die GUI ein zweites mal erzeugt. Initialisiere ich die Variable jedoch nicht oder mit „null“ lässt sich, logischer Weise, die Methode nicht ausführen.

Hier ein kleines Beispiel (KSKB), welches mein Problem verdeutlicht:
Java:
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;


@SuppressWarnings("serial")
public class MainClass extends JPanel{
	
	CardLayout layout;
	
	public static void main(String[] args){
		new MainClass();
	}
	
	public MainClass(){
		JFrame startFrame = new JFrame();
		startFrame.setLayout(new FlowLayout());
		layout = new CardLayout();
		this.setLayout(layout);
		this.setPreferredSize(new Dimension(300,300));		
		this.add(createPanel(300,300,Color.red),"redPanel");
		this.add(createPanel(300,300,Color.blue),"bluePanel");
		TestClass tc = new TestClass();
		startFrame.add(this);
		startFrame.add(tc);
		startFrame.pack();
		startFrame.setVisible(true);
	}
	
	public void changePanel(){
		layout.next(this);
	}
	
	private JPanel createPanel(int x, int y, Color c){
		JPanel cachePanel = new JPanel();
		cachePanel.setPreferredSize(new Dimension(x,y));
		cachePanel.setBackground(c);
		
		return cachePanel;
	}
}
Java:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JPanel;


@SuppressWarnings("serial")
public class TestClass extends JPanel implements ActionListener{
	
	JButton button;
	
	public TestClass(){
		this.setPreferredSize(new Dimension(100,300));
		button = new JButton("Next");
		button.addActionListener(this);
		this.add(button);
	}

	public void actionPerformed(ActionEvent e) {
		if(e.getSource().equals(button)){
			MainClass cLT = new MainClass();
			cLT.changePanel();
		}
		
	}
}


Nun zu meiner Frage, ist das ein Design Problem oder gibt es eine andere Möglichkeit ein Objekt zu initialisieren? Bzw. vielleicht sogar die Möglichkeit auf die „Ur-Instanz“ zu referenzieren?

Danke
Zenic
 
Ich gehe in dem Fall immer wie folgt vor:

FirstClass variablenName = new FirstClass();
variablenName.methodenName();
Solltest du dir abgewöhnen und stattdessen nachdenken, ob eine neue Instanz Sinn macht oder nicht.

Nun zu meiner Frage, ist das ein Design Problem oder gibt es eine andere Möglichkeit ein Objekt zu initialisieren? Bzw. vielleicht sogar die Möglichkeit auf die „Ur-Instanz“ zu referenzieren?
Wenn du etwas mit der Urinstanz machen willst, musst du diese benutzen. Es geht nicht anders, wenn du mit new ein neue Instanz erschaffst hat dieses nichts mit der Urinstanz zu tun.


=> Die Instanz von "TestClass" braucht eine Referenz auf die Instanz von "MainClass". Diese kannst du z.b. im Konstruktor übergeben und innerhalb von "TestClass" als Membervariable abspeichern. Um die Instanz von "TestClass" in "MainClass" zu erstellen:
Code:
new TestClass(this)
 
Zuletzt bearbeitet:
Und davon mal ab ist es in dem gezeigten Beispiel auch ein Design-Problem. Es gibt mehrere Wege das zu umgehen. Den ActionListener in die MainClass packen und der Testclass zuweisen (da sollte man die Überprüfung woher es kommt allerdings vielleicht über das ActionCommand vornehmen), eine Referenz der MainClass an die TestClass übergeben, ganz dirty Parent von TestClass holen und nach MainClass casten...viele Wege führen nach Rom, was Sinn macht, da kann man sich leider drüber streiten. Einen Königsweg für alle Lebenslagen gibt es nicht.

Gruß FatFire
 
Ich dachte mir schon, dass das Anlegen immer neuer Instanzen keinen Sinn macht, doch ich habe die Möglichkeit des Übergebens anscheinend verdrängt und sah deshalb keine andere Möglichkeit.

Nach FatFires Post hat sich eine neue Frage aufgetan. Nehmen wir an, wir haben ein Programm mit einem Frame(CardLayout), jede Card besitzt Buttons, sollte man in dieser Konstruktion nur einen ActionListener, KeyListener, etc. verwenden (Frame) oder soll jede Card ihren eigenen haben?

Danke
 
Kommt ganz darauf an, wie "eigenständig" deine Container-Komponenten sind. Sind sie nur zur übersichtlichen Gliederung da? Dann Listener in die übergeordnete Instanz. Bilden sie eine logische Einheit, könnten sie auch in einem anderen Kontext "funktionieren"? Dann die Listener im Container selber.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben