Hallo Lars,
Ich habe ein
Hauptfenster in dem mehrere Panels sitzen: Meinetwegen ein
JPanel für die linke Seite des Hauptfensters und ein JPanel
für die rechte Hälfte des Hauptfensters.
Wenn jetzt die Panels jeweils eine Klasse
TabellenPanel
extends JPanel
und eine Klasse
TextPanel extends
JPanel
sind, wie kann ich aus der Klasse TabellenPanel
auf den Text in der Klasse TextPanel zugreifen?
In der GUI-Entwicklung ist es keine gute Idee, wenn
einzelne Unterkomponenten explizite Annahmen über andere
Unterkomponenten in der Anwendung machen. Dies führt
zur harten Kopplung der Komponenten untereinander, was
zum Einen die zukünftige Erweiterung der Anwendung
behindert und zum Zweiten die Testbarkeit der
Unterkomponenten erschwert.
Besser ist es, den Zugriff auf die Unterkomponenten
über ein Interface zu machen.
Die Vaterklasse kann dann all Ihren Unterkomponenten
dieses Interface zur Verfügung stellen und den Aufruf
an die jeweils betroffene Komponente weiterleiten.
Bsp.
public interface InterfaceA {
public void setA(int i);
public int getA();
}
public interface InterfaceB {
public void setB(String s)
public String getB();
}
public TabellenPanel extends JPanel implements InterfaceA {
// wir übergeben den die Tabelle interessierenden
// Teilaspekt in Form eines Interfaces im Konstruktor
// und keine konkrete Elternklasse mehr:
public TabellenPanel(InterfaceB interfaceB) {
...
}
}
public TextPanel extends JPanel implements InterfaceB
// analog:
public TextPanel(InterfaceA interfaceA) {
...
}
public ApplicationFrame extends JFrame
implements InterfaceA, InterfaceB {
protected TabellenPanel \_tabellenPanel = null;
protected TextPanel \_textPanel = null;
public ApplicationFrame() {
// Da der ApplicationFrame die beiden Interfaces implementiert,
// kann er sich selbst als Referenz an seine Unterkomponenten
// übergeben.
// Diese "sehen" wegen der Aufteilung der Funktionen in Interfaces
// nur den sie interessierenden Teil und nicht mehr alle seine
// Funktionen, einem Austausch der konkreten Implementierung
// steht damit nichts mehr im Wege
\_tabellenPanel = new TabellenPanel(this);
\_textPanel = new TextPanel(this);
}
// delegiere die Interface-Aufrufe
// an die konkreten Komponenten:
public void setA(int i) {
\_tabellenPanel.setA(i);
}
public int getA() {
\_tabellenPanel.getA();
}
public void setB(String s) {
\_textPanel.setB(s);
}
public String getB() {
\_textPanel.getB();
}
}
Noch besser im Sinne der losen Kopplung wird es, wenn die Subkomponenten das Oberserver-Pattern verwenden, und bei
Zustandsänderungen all ihren Interessenten (=Listenern)
eine Benachrichtigung senden mit sich selbst bzw. dem
interessierenden Interface(!) als Auslöser.
Der Listener kann dann nach der Benachrichtigung
die Zustandsänderung direkt vom Auslöser-Interface erfragen.
dass ich eigentlich wissen will, wie der Sohn den Vater
FRAGEN kann, ohne eine Kopie vom Vater zu besitzen.
Mögliche Lösungen sind also:
- Übergabe von Interface-Implementierungen
- Benachrichtigung per Observer-Pattern
Gruß,
-Andreas.