GUI-Klasse aufräumen

rull_ger

Grünschnabel
Moin moin,

hab ein kleines programmiertechnische Problem!

Habe einen schönen GUI mit Hilfe von SWT erstellt. Diese GUI-Klasse ist eine sehr mächtige Klasse mit viel Code.
Es gibt in diesem GUI einen "Enter"-Button, der eigentlich die Hauptaufgaben des Programms übernimmt, wenn dieser gedrückt wird!
Diesen ActionListener würde ich gerne in eine eigene Klasse stecken. Im Prinzip kein Problem! ABER! Ich muß an viele Objekte rankommen, die in der GUI-Klasse vorhanden sind (Text-Fields, andere Buttons...).
Jetzt kann ich natürlich, jedesmal wenn dieser Button gedrückt wurde das aktuelle Objekt mit this dem Konstruktor von der "Button"-Klasse übergeben.
Aber das ist nicht das was ich mir vorstelle, vorallem weil ich dann die gesamten Klassenobjekt und Variablen des GUIs public machen muß!

Gibt es da vielleicht eine elegantere Lösung?

Wäre super, wenn jemand ne Idee hätte.

Danke schonmal im Voraus :-)
 
Du solltest deine Applikation so strukturieren, dass deine Darstellungslogik strikt von deiner Ablauflogik getrennt ist.

Dies erreichst du dadurch, das du dir eine Model-Klasse erstellst, in die du deine gesammte Logik deines Fensters auslagerst. Um eine Kommunikation zuwischen Model und GUI zu ermöglichen, bietet sich ein Observerpattern an. Dazu erbt dein Model von Observable und dein GUI implementiert Observer. Nun kannst du deine GUI-Klasse bei dem Model mit addObserver registrieren.
 
Okay supi!
Vielen vielen Dank schonmal!!

Das hört sich sehr gut an!
Aber...

Meine "Model"-Klasse sieht nun so:

public class EnterButton extends Observable {
...
}
aus

Meine Gui-Klasse:
public class Layout implements Observer{
...
}

So schön und gut!

Nun geh ich in die "Model" Klasse und schreibe in einer Funktion:

addObserver(new Layout());

So...! So habe ich das verstanden! Nur kann ich so noch nicht auf Variablen & Objekte von Layout zugreifen!

Was mach ich da falsch?
 
Also - eine kurze Einführung in das Observerpattern:


Du hast 2 Klassen - nennen wir sie einmal View und Model. Dein Model enthält eine Funktion zum addieren zweier Zahlen (int).

public class Model extends Observable {

/** statische Instanz des Models - Singleton */
private static Model model = null;

/** Ergebnis einer Operation */
private int result;

/** Konstruktor */
private Model() {
this.result = 0;
}

/**
* Singleton - liefert eine einzigartige Instanz
* @return Model Objekt der Model-Klasse
*/
public static getInstance() {
if (Model.model == null) {
Model.model = new Model();
}
return Model.model;
}

/**
* addiert zwei Zahlen
* @param number1 Zahl1
* @param number2 Zahl2
*/
public void addNumbers(int number1, int number 2) {
this.result = number1 + number2;
this.setChanged();
this.notifyObservers("add");

}

/**
* Getter für result
* @return int der Wert von result
*/
public int getResult() {
return this.result;
}

}

public class View implements Observer() {

private Model model = null;

/** Konstruktor */
public View() {
this.model = Model.getInstance();
model.addObserver(this);
model.addNumbers(3, 5);
}


/**
* Update-Methode des Observerpatterns
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
* @param arg0 Klasse, die das Update-Event ausgelöst hat
* @param obj Optionaler wert, kann null sein
*/
public void update(Observable arg0 Object arg1) {
if (arg1.instanceof String) {
String cmd = (String) arg1();
if (cmd.equals("add")) {
System.out.println("Ergebnis = " + model.getResult());
}
}
}

}


So - was machen nun diese beiden Klassen?

Zuerst einmal das Model:
Das Model selber ist als Singleton ausgelegt. Das heisst, das nur ein Objekt der Klasse Model erzeugt werden kann. Die statische Methode getInstance prüft dabei, ob bereits eine Instanz existiert und gibt diese dann zurück.
Neben den Instanziierungsmethoden getInstance und dem privaten Konstruktor besitzt die Klasse noch eine Methode addNumbers. Diese addiert zwei übergebene Parameter und speichert das Ergebnis im statischen Member result.
Danach werden die beiden Methoden des Observerpatterns aufgerufen:

this.setChanged(); Hierdurch wird im grunde genommen Signalisiert: "Hallo, es gibt Änderungen"


this.notifyObservers("add"); Diese Zeile hingegen veranlasst die registrirten Observer, eine Aktion auszuführen. Der Parameter - hier mit dem String "add" befüllt - kann dabei genutzt werden, um die auszuführenden Aktionen näher zu präzisieren.

Kommen wir zur View-Klasse:
Im Konstruktor holen wir uns über Model.getInstance() eine Instanz unserer Model-Klasse und speichern diese im privaten Member model.
Da View Observer implementiert können wir uns mit model.addObserver(this) beim Model registrieren.

Durch die Implementierung von Observer muss die Klasse View die Methode void update(Observable arg0, Object arg1) implentieren.
Diese wird aufgerufen, wenn im Observable setChanged() und notifyObserver(Object arg0) ausgeführt werden.
Im beschriebenen Beispiel ist update folgendermaßen implementiert:

zuerst wird geprüft, ob arg1 ein String ist. Trifft dies zu, wird geprüft, ob der String gleich "add" ist. In diesem Fall wird über model.getResult das neue Ergebnis abgeholt.
Der Parameter Observable arg0 ist übrigens wieder dein Model-Objekt.

Weitere Informationen zum Observerpattern findest du auch unter:

http://www.galileocomputing.de/openbook/javainsel5/javainsel11_012.htm#Xxx999389

und

http://www.uni-koblenz.de/~admin/Doku/g2j/html/k100068.html#ixa100648
 
Ich bin völlig begeistert!

Ich Danke Dir tausendmal für Deine große Mühe.

Echt super! Damit versteht ich, wie das funktioniert und werd das ausprobieren!
 
Zurück