GEF-Tutorial Kapitel 5


Aus Wirthi's Wiki
Wechseln zu: Navigation, Suche
GEF-Tutorial
Eclipse Graphical Editor Framework
Allgemeines
Kapitel 1 (Überblick)
Kapitel 2 (Model-View-Controller)
Kapitel 3 (Model)
Kapitel 4 (Controller)
Kapitel 5 (View)
Kapitel 6 (Editor-Hauptklasse)
Kapitel 7 (Einsatz und Zusammenfassung)

Im Kapitel 5 des GEF-Tutorials wird der View-Teil der MVC-Architektur eines GEF-Editors beschrieben. Die View beschreibt, wie ein Element grafisch am Bildschirm angezeigt wird.

Aufgaben

Eine View ist für die grafische Darstellung von Elementen am Bildschirm zuständig. Sie definiert, durch welche Formen, Farben, Texte oder komplexe Steuerelemente ein Model-Objekt visuell repräsentiert wird.

Der typische Fall ist folgender: Für jeden Typ von Model-Objekten (d.h. für jede Klasse) gibt es genau einen View-Typ (d.h. eine View-Klasse); während der Darstellung wird jedes Model-Objekt durch genau ein View-Objekt dargestellt. Häufig wird dieses Grundmodell jedoch abgewandelt:

  • So kann etwa ein Model-Objekt durchaus mehrfach (gleichzeitig) angezeigt werden. Es werden dafür mehrere View-Objekte für ein Model-Objekt angelegt. Wie wir bereits wissen, werden dabei auch mehrere EditPart-Objekte angelegt. Die Beziehung zwischen EditPart- und View-Objekten ist immer 1:1
  • Auch kann ein Model-Typ auf unterschiedliche Weise dargestellt werden. Dies wird üblicherweise über unterschiedliche View-Klassen gelöst. So kann eine Model-Klasse mehrere View-Klassen haben, von denen vom EditPart je nach Bedarf die richtige ausgewählt wird.

Hierarchische Schachtelung

Auch Views bilden die hierarchische Schachtelung der Model-Objekte ab. Eine View stellt jeweils einen rechteckigen Bereich auf dem Bildschirm dar. In diesem Bereich kann die View ihre eigenen Daten darstellen. Die Daten ihrer Kind-Objekte hingegen werden von ihr selber NICHT visualisiert. Sie muss aber einen (oder mehrere) Bereich(e) zur Verfügung stellen, in die die Views iher Kind-Objekt eingefügt werden können.

Implementierung

View-Klassen müssen das Interface org.eclipse.draw2d.IFigure implementieren; meist werden sie aber direkt der Klasse org.eclipse.draw2d.Figure abgeleitet. Diese Figure repräsentiert den Zeichenbereich, auf dem die View darstellen kann was auch immer sie will. Dies funktioniert so, wie Sie es etwa von AWT, Swing oder SWT bereits kennen: Die Figure ist ein Element, dem weitere Sub-Elemente hinzugefügt werden können und deren paint-Methode überschrieben werden kann.

Üblicherweise werden hier Standard-Kontrollelemente wie etwa Labels oder Buttons angezeigt. Diese können direkt im Konstruktor zur View hinzugefügt werden. Des weiteren kann die paint-Methode überschrieben werden, um komplexere Grafiken selber zu implementieren.

Steuerelemente hinzufügen

paint überschreiben

Daten des Model-Objektes anzeigen

Bis jetzt haben wir nur eine generische View erzeugt. Diese ist noch nicht mit den Daten in berührung gekommen, die sie anzeigen soll. Woher erhält sie diese Daten überhaupt?

Nun, das View-Objekt wird vom zugehörigen EditPart erzeugt. Dazu muss die Methode protected IFigure createFigure() im EditPart implementiert werden. Diese Methode erzeugt ein den EditPart passendes View-Objekt und liefert es zurück.

Der EditPart hält nun sowohl eine Verbindung zum Model-Objekt und zum View-Objekt. Er muss nun dem View-Objekt mitteilen, was es zu visualisieren hat, und anschließend nach jeder Änderung der Daten im Model-Objekt diese Aufforderung wiederholen. Die konkreten Ausgestaltung dieser Verbindung ist dem Programmierer überlassen, denkbare Varianten sind etwa:

  • Das Model-Objekt wird der View bereits im Konstruktor übergeben. Dies ist möglich, entspricht aber nicht dem Gedanken der Trennung von Daten und Anzeige.
  • Dem EditPart wird Zugriff auf die Objekte gegeben, die die Daten anzeigen. Er manipuliert etwa direkt Labels oder setzt Farbwerte. Auch dies ist nicht gewünscht, dafür ist der EditPart nicht zuständig.
  • Eine gute Lösung ist: Der EditPart ruft eine Methode der View auf und übergibt ihr dort das Model-Objekt. Damit ist die View selber zur Aktualisierung der angezeigten Daten zuständig, braucht aber das Model-Objekt nicht speichern.

Zur Umsetzung der Lösung legen wir also in allen Views eine Methode public void update(ModelTyp model); an. Diese wird vom EditPart aufgerufen, wann auch immer die Daten des Model-Objektes geändert wurden.

Beispiel

Dies ist ein einfaches Beispiel für eine View, die keine Kind-Elemente hat und lediglich einen Text in einem Label anzeigt:

public class ChildView extends Figure {
	private Label label;

	public ChildView() {
		this.setLayoutManager(new ToolbarLayout());
		label = new Label();
		label.setBackgroundColor(ColorConstants.green);
		label.setOpaque(true);
		this.add(label);
	}

	public void update(Child child) {
		label.setText("Child: " + child.getName());
	}
}

Im Konstruktor wird zuerst ein LayoutManager gesetzt; dieser bestimmt, wie die Elemente der Figure angeordnet werden. Im Falle eines ToolbarLayouts werden diese nebeneinander gezeichnet. Anschließend wird das Label erzeugt, mit einer Hintergrundfarbe (Grün) versehen und als "nicht durchsichtig" (engl. opaque = dt. undurchsichtig) markiert. Das Label wird anschließend (als einziges Element) zur aktuellen Figure hinzugefügt.

In update wird der Text des Labels entsprechend dem Namen des Model-Objektes aktualisiert.

GEF-Tutorial: Allgemeines - Kapitel 1 - Kapitel 2 - Kapitel 3 - Kapitel 4 - Kapitel 5 - Kapitel 6 - Kapitel 7

Meine Werkzeuge