Java GUIs und MVC, etc.

monsterhaus

Cadet 4th Year
Registriert
Feb. 2009
Beiträge
94
Hallo,

zur Zeit beschäftige ich mich mit GUIs und dem MVC-Model.
Ich kann einzelne GUI-Objekte ohne Probleme erzeugen und mit Listener ausstatten. Probleme bereiten mir dabei am meisten die Layouts und die korrekte Anordnung der einzelnen Components auf dem JFrame und den einzelnen JPanel's. Auch habe ich große Probleme mit der JTable und deren einzelnen Modelle.

Desweiteren möchte ich gerne einmal hinter das MVC-Modell "steigen" und es endlich mal verstehen und anwenden können.

Nun meine Frage, ob hier jemand ist, der mir gute Erklärungen oder Anleitungen zu diesen einzelnen Problemen empfehlen kann?

P.s.: Bisher habe ich mich sehr lange Zeit nur mit Konsolenbasierenden Programmen beschäftigt, es ist also schon relativ viel Grundwissen vorhanden.

Gruß
 
Generelles MVC:

Model
- enthält die eigentlichen Daten und Methoden für Modifikationen etc.
- hat Liste von Observern (Beobachtern), dies sind in der Regel die Views
diesen Observern sagt das Model bei einer Änderung bescheid, sodass diese evtl. die View aktualisieren oder was auch immer tun

View
- registriert sich als Observer bei Model
- bietet ggf. Methoden an um View zu ändern
bei Änderung wird ggf. Model angefragt nach aktuellen Daten
- erstellt den Controller

Controller
- kann Observer sein bei Model, aber nicht notwendig
- kann Methoden bei Model aufrufen wie "lösche xy", "tue das und dies"
- wird initialisiert mit Model und View
- kann Nachrichten an View schicken falls "ändere Ansicht"
Ergänzung ()

Also mal konkret könnte es irgendwie so ausschauen:

Legst erst einmal ein Interface ein

Observer
mit Methode public void update();

Dann als Beispiel

Model Benutzer:
- List<Observer>
Methode attach/detach um sich als Observer an und abzumelden
entspricht dann einfach entfernen und hinzufügen zur Liste

- eigentlichen Daten, Attribute
- Methoden zum ändern, lesen etc, der Daten
- Methode notify:
public void notify() {
for (Observer o: Liste_observer) {
o.update();
}
}

Erstellung der View
new View(model)

Konstruktor etwa so:
public View(Model m) {
this.m = m;
this.controller = new Controller(m, this);
}
View impelemtiert Interface Observer, muss also die Methode update() implemtieren
wird diese aufgerufen, ruft es aktuellen Daten vom Model und aktualisiert Ansicht
Ferner kann View noch Methoden angeben um Ansicht zu ändern, die würde man vom Controller aufrufen
 
Ich kann deinem Post nicht so ganz zustimmen Skully. Dies hat mehrere Gründe:

Zum einen ist MVC nichts anderes als ein Paradigma, welches in mehreren unterschiedlichen Ausführungen realisierbar ist. Was du beschreibst Skully, ist ein Observer in dem schlichtweg die Klassen "Subjekt" (wie es generell formuliert wird) ausgetauscht wurden und Model genannt wurden. Man kann es so machen, muss es aber sicherlich nicht so umsetzen. Dagegen spricht in meinen Augen definitiv die nicht vorhandene Kontrolle des Controllers, obwohl dieser mit der View und dem Model initialisiert wird. Das ist ein Widerspruch in sich.

@monsterhaus:
Wenn du ein MVC einsetzen willst (wovon ich ein großer Fan bin, allerdings eher Richtung MVP gehend), musst du dir zunächst über die Zuordnungen deiner Klassen Gedanken machen.
Fakt ist, dass folgende Klassen IMMER folgende Zuständigkeiten besitzen:

Model:
Enhält die Daten, bzw. die Business Logik, also den Zugriff auf die Daten. Ausserdem für die Datenmanipulation zuständig.

Controller:
Verarbeitung und Weiterleitung der Anfragen an entsprechende Klassen. Ist im klassischen MVC die Klasse, welche die View und das Model kennt und entsprechende Anfragen und Requests an beide weiterleitet.

View:
Ist für das Anzeigen der Daten zuständig.

So wenn du nun eine Zuordnung getroffen hast, überleg dir wer wen beobachten/kennen soll. Wie ich oben schon beschrieben habe, kennt im klassischen MVC das Model und die View sich untereinander nicht. Nur der Controller kennt beide.
Man könnte sich durchaus auch eine Abwandlung vorstellen, in der die View observed wird oder ähnliches.
Es geht nur darum dass du dir selbst klar machst, kann es kein Gesetz gibt wie man das MVC anwenden soll. Die Anwendung ist in der Regel unterschiedlich und kann nicht pauschal gesehen werden.

An deiner Stelle würde ich nun versuchen mir anhand eines einfachen Beispiels (bsp. ein Würfel mit dem gewürfelt werden kann) ein MVC umzusetzen.

http://www.phpwact.org/pattern/model_view_controller für mehr Infos (find ich rel. passend)
 
@monsterhaus,

das MVC wurde nun ja erklärt. (Ich finde beide Posts oben treffen zu. Bin allerdings noch knapp Anfänger)

Bezüglich Layout:
http://download.oracle.com/javase/tutorial/uiswing/layout/using.html

Auch wenn das auf den ersten Blick schwierig aussieht ist es wichtig zu verstehen.. Grundsätzlich sind die Layouts nicht derart schwierig wenn du nicht derart spezielle Dinge machen willst..

Wichtig ist einfach zu verstehen dass jedes Layout seine eigenen Eigenschaften besitzt und die Layouts verschachtelt werden können..

Ich nutze meistens das BoxLayout (mit Y-Achse) für Dinge die wie ein Turm gestapelt sind.. Also z.b. eine Art Tabelle mit einer Spalte (Wichtig!)

Das BorderLayout ist auch sehr interessant. Du kennst es hier vom Internet. Es sind 5 Bereiche (oben, rechts, unten, links und mitte). Beim Vergrössern des Fensters vergrössert sich dann nur die Mitte. Der Rest bleibt gleich gross...

Wenn es wie eine Tabelle sein soll, mit mehreren Zeilen und Spalten schau dir mal das GridBagLayout an.. (Achtung das ist komplexer als die anderen..)

Am besten wirfst du auch mal einen Blick hierauf:
http://download.oracle.com/javase/tutorial/uiswing/layout/layoutlist.html

Öffne die Beispiele, vergrössere und verkleinere sie und schau dir danach mal den Code an..
Ich bin ein ziemlicher Fan dieser Beispiele da Sie ohne etwas wichtiges zu vergessen auf das wesentliche konzentriert sind..
 
Danke schon mal an alle drei Antworten!

@Firestorm-:

Ich habe nur noch eine Frage:

Wie kann man der View dann mitteilen, dass sich etwas geändert hat?
Einfaches Szenario ( nur im Prinzip ):
Das Modell berechnet einen gewissen Wert immer genauer (zum Beispiel pi-Näherung). Dies geschieht automatisch und nebenher (Thread), direkt nachdem das Model-Objekt erstellt wurde.
Nebenbei soll die View immer den gerade aktuell berechneten Näherungswert anzeigen.
Wie kann also der Controller, ohne ständiges Abfragen (zum Beispiel in einem Thread oder ähnlichem) der aktuellen Berechnung der View mitteilen, dass sich etwas geändert hat? Da würde man dann eine Version mit einem Observer erstellen, also eine Version, in der das Model die View kennt und diese benachrichtigt, wenn sich etwas geändert hat, oder?
 
Ich versuchs mal vereinfacht, die anderen haben deine Frage ja eigentlich schon beantwortet.

Du hast ein Objekt D mit Daten und wo meinetwegen auch was berechnet wird.

Alle Sichten/Views, die das "interessiert" melden sich da an. In Java: addListener ...
Wenn sich in D was ändert, also Daten aktualisiert bzw. neu berechnet wurden, werden alle Interessenten benachrichtigt (Stichwort Observer in Java, siehe oben)

Die Views müssen also nichts abfragen, denn sie werden benachrichtigt (sofern sie sich angemeldet haben) und können sich dann ihrerseits aktualisieren.
 
monsterhaus schrieb:
Wie kann man der View dann mitteilen, dass sich etwas geändert hat?

Gemäß der Datentrennung und dem Prinzip der Zuordnung des MVC hat der Controller in deinem beschrieben Fall die "Kontrolle". Dieser würde in deinem Beispiel zu der datenhaltenden Klasse (Model) sagen "berechne irgendwas und gib mir das Ergebnis zurück, in jeder Iteration()". Dieses Ergebnis würde der Controller erhalten und gleich an die View weiterleiten, welche es anzeigt.
Somit sind strenggenommen alle Listener, die einen bestimmten Control auf der View oder die View selbst beobachten im Controller zu finden und vielleicht nur Methoden um diese an die Controls zu binden, direkt in der View (beispielsweise). Ausnahmen können dabei allein View spezifische Methoden sein, wie z.B. "dispose()" oder ähnliches. Diese gehören in der Regel zwangsweise in die View. Je nachdem wie viel deine View weiss oder können soll kann man sie charakterisieren.
Nochmals: Mein eben beschriebener Weg ist einer von vielen das MVC sinnvoll umzusetzen!
 
Konkret in Java verwendet man üblicherweise Bound Properties für das Databinding. Sprich, die View meldet sich als Listener auf Änderungen sämtlicher oder bestimmter Properties an und erhält somit die Daten.
Am besten erstellt man dazu einen Mediator, welcher sowohl die View als auch das Model kennt. Über die üblichen Modified-Listener kann man damit auch ein Read-Write-Updatestrategie realisieren, d.h. Änderung im Model werden in der View reflektiert und umgekehrt.
 
Vielen Dank an alle,

ich habe es jetzt geschafft, MVC in meinem Projekt zu realisieren und hoffe, dass das mir auch gut gelungen ist.
Funktionieren tut auf jeden Fall alles schonmal:)
 
Zurück
Oben