Eclipse DataBinding für die Kommunikation zwischen Modell und GUI

Wir sehen, dass das TargetObservable im vorliegenden Fall SWTObservables.observeText ist, das ModelObservable erhält den Wert BeansObservables.observeValue und UpdateStrategy wird beide Male mit null belegt. Dies bewirkt, dass eine Standard-UpdateStrategy verwendet wird. Betrachten wir zunächst das SWTObservable. Ein SWT Text Widget bietet die Eigenschaft, einen Text anzuzeigen und zu verändern. Mittels der Methode observeText verwenden wir diesen Text im vorliegenden Beispiel für das Eclipse DataBinding. Wir könnten jedoch genauso gut und genauso einfach andere Eigenschaften, wie zum Beispiel Sichtbarkeit, Auswahl (Selektion) oder Farbe eines SWT Widgets mit einem Modellattribut mittels Eclipse DataBinding verknüpfen. Abbildung 3 zeigt, welche Methoden die Klasse SWTObservables zu diesem Zweck bietet. Als Nächstes wollen wir das Augenmerk auf BeansObservables richten. Durch die Methode observeValue drücken wir aus, dass wir uns für eine bestimmte Property einer konkreten JavaBean interessieren, in unserem Falle die Property name der JavaBean mitarbeiter.

Abb. 3: Die Methoden der Klasse SWTObservables
Eine Strategie muss her

Wir haben bisher betrachtet, wie ein DataBindingContext mit einem TargetObservable und einem ModelObservable versorgt wird, welche durch DataBinding miteinander synchronisiert werden sollen. Was aber nun noch fehlt, sind genaue Anweisungen, wie diese Synchronisation vorgenommen werden soll. Diese Anweisungen werden bei Eclipse DataBinding in Gestalt einer UpdateStrategy angegeben, welche aus diesen drei Teilen besteht:

  • Konvertierungsanweisungen
  • Validierungsanweisungen
  • Policy

Wichtig dabei ist, dass ein DataBindingContext zwei unterschiedliche Update-Strategien haben kann, nämlich eine für die Synchronisation von Target zu Modell und die andere für die Gegenrichtung, von Modell zu Target.

Konvertierung

Schauen wir uns nun im Folgenden die Bestandteile einer UpdateStrategy genauer an, beginnend mit den Konvertierungsanweisungen. Diese werden, wenn es darum geht, einen Wert mit einem bestimmten Datentyp zu einem anderen Datentyp zu konvertieren, von Eclipse DataBinding herangezogen. Es ist natürlich möglich, eigene Konvertierungsanweisungen anzugeben, Eclipse DataBinding liefert jedoch bereits eine schöne Auswahl fertiger Datentypkonvertoren (Abb. 4).

Abb. 4: Datentypkonvertoren von Eclipse DataBinding
Validierung

Validierungsanweisungen dienen dazu, eine Synchronisation von Target und Modell nur dann durchzuführen, wenn der zu synchronisierende Wert eine Gültigkeitsprüfung besteht. Man kann sich zum Beispiel vorstellen, dass der Benutzer in einem grafischen Eingabefeld eine Zahl eingeben soll, wobei von der Applikationslogik her diese Zahl niemals 1 000 oder größer sein kann. Wenn nun nicht schon das grafische Eingabefeld auf drei Stellen beschränkt ist, kann bei Eclipse DataBinding als Bestandteil einer UpdateStrategy eine entsprechende Validierungsanweisung angeben werden, sodass der Wert des graphischen Eingabefeldes nur dann zum ApplikationsModell synchronisiert wird, wenn der Benutzer eine Zahl eingegeben hat, die 999 oder kleiner ist. Eine solche Validierungsanweisung kann in Form einer Klasse angegeben werden, die das Interface IValidator implementiert und so aussehen könnte:

private static class ThreeDigitsValidator implements IValidator {

  public IStatus validate(Object value) {
    Integer price = (Integer) value;
    return (price 
Policy

Nach der Konvertierungsanweisung und der Validierungsanweisung wollen wir uns nun den dritten Bestandteil einer UpdateStrategy ansehen, nämlich die Policy. Diese steuert im Wesentlichen, wann Eclipse DataBinding eine Synchronisierung durchführt, und kann folgende Werte annehmen:

  • NEVER
  • ON_REQUEST
  • CONVERT
  • UPDATE

NEVER bedeutet, dass Eclipse DataBinding das Quell-Observable nicht beobachtet und niemals das Ziel-Observable aktualisiert. ON_REQUEST bedeutet, dass das Quell-Observable nicht beobachtet wird und Validierung, Konvertierung und Aktualisierung nur dann vorgenommen werden, wenn die entsprechenden Methoden der DataBindingContext-Instanz aufgerufen werden. CONVERT bewirkt, dass das Quell-Observable beobachtet wird und auch die Validierung durchgeführt wird, die Aktualisierung des Ziel-Observables geschieht jedoch nur, wenn dies explizit beim DataBindingContext angefordert wird. UPDATE schließlich ist quasi der Automatik-Modus, bei dem das Quell-Observable beobachtet wird und die Konvertierung, Validierung und Aktualisierung des Ziel-Observables automatisch bei Bedarf vorgenommen werden. Für alle vier Policy-Werte gilt: Das Quell-Observable ist entweder das Target- oder das Modell-Observable, in Abhängigkeit davon, ob es sich um die UpdateStrategy T zu M oder M zu T handelt.

Änderungsmitteilungen

Bei unserem Beispiel sieht der Anwender in der GUI ein SWT-Texteingabefeld. Jedesmal, wenn in diesem Feld eine Änderung gemacht wird (also bei jedem Tastendruck), wird Eclipse DataBinding aktiv und führt Konvertierung, Validierung und Update durch. Ein solches Verhalten ist dann wünschenswert, wenn der Benutzer sofort Feedback zu seiner Eingabe erhalten soll. Zum Beispiel könnte sich das Texteingabefeld rot verfärben, wenn die aktuelle Benutzereingabe nicht den Anforderungen entspricht. Eine derartige Funktionalität lässt sich übrigens sehr schön mit Eclipse DataBinding realisieren. Ein anderes Szenario sieht beispielsweise so aus, dass der Anwender zunächst in Ruhe seine Eingabe machen kann und Überprüfungen, Konvertierungen und Aktualisierungen erst dann erfolgen sollen, wenn der Benutzer mit seiner Eingabe fertig ist und dies explizit ausdrückt, indem er zum Beispiel auf einen Button klickt. In diesem Fall würde unser Beispielquellcode so aussehen:

bindingContext.bindValue(SWTObservables.observeText(nameWidget, SWT.FocusOut), 
BeansObservables.observeValue(mitarbeiter, "name"), null, null);

Der einzige Unterschied zu vorher ist, dass sich SWT.Modify zu SWT.FocusOut geändert hat. Durch den Parameter SWT.FocusOut wird Eclipse DataBinding immer dann über eine Änderung im SWT Widget nameWidget informiert, wenn der Fokus auf ein anderes Widget wechselt. Dies passiert etwa dann, wenn der Benutzer auf einen OK-Button klickt.

Stand der Dinge

Eclipse DataBinding ist in Version 1.0 im Europa Release der Eclipse-Plattform enthalten, die Ende Juni 2007 erschienen ist. Tatsächlich ist Eclipse DataBinding schon etwas älter und gereifter, wie der Kasten „Die Historie von Eclipse DataBinding“ zeigt, und es handelt sich bei dieser Technologie um ein gut durchdachtes Konzept. Bisher gibt es allerdings noch wenig Dokumentation zu Eclipse DataBinding. Als Startpunkte kann ich die Wiki-Seite [1] empfehlen sowie einen Blick in das CVS Repository [2]. Dort findet sich der Quellcode zu Eclipse DataBinding, der insgesamt recht gut dokumentiert ist und viele wertvolle Hinweise enthält. Darüber hinaus gibt es im CVS Repository eine ganze Reihe von JUnit-Tests für Eclipse DataBinding. Diese stellen ein hilfreiches Sammelsurium an Beispielen dafür dar, wie man Eclipse DataBinding benutzen kann und was alles damit möglich ist. Abbildung 5 zeigt, wo org.eclipse.core.databinding und org.eclipse.core.databinding.beans im CVS Repository zu finden sind. Empfehlenswert ist auch ein Blick auf das Projekt org.eclipse.jface.examples.databinding.

Abb. 5: Eclipse DataBinding im CVS-Repository
Eclipse DataBinding hieß früher JFace DataBinding und kam in Gestalt eines einzigen Plug-ins, nämlich org.eclipse.jface.databinding. Für die Version 3.3 der Eclipse-Plattform wurde JFace DataBinding überarbeitet und besteht nun aus einem Kern-Plug-in (org.eclipse.databinding.core) sowie Adaptoren für JavaBeans und JFace (org.eclipse.databinding.beans und org.eclipse.databinding.jface). Die neue Bezeichnung wird noch nicht durchgängig verwendet, oft wird noch der Begriff JFace DataBinding benutzt, auch wenn damit das neuere Eclipse DataBinding gemeint ist.
Fazit

Wir haben gesehen, dass es mit Eclipse DataBinding auf elegante Art und Weise und mit relativ wenig Quellcode gelingt, ein GUI-Element mit einem Modellattribut zu verknüpfen. Es gibt zahlreiche Einstellmöglichkeiten, mit denen beeinflusst werden kann, zu welchen Zeitpunkten Eclipse DataBinding seine Arbeit verrichten soll. Mit diesen Möglichkeiten und in Verbindung mit individuellen Konvertierungs- und Validierungsanweisungen liefert Eclipse DataBinding sehr viel Flexibilität und ein großes Einsatzspektrum. Als Java-Entwickler spart man sich lästig zu schreibenden und sich häufig wiederholenden EventListener-Quellcode sowie unhandliche Datentypkonvertierungen. Probieren Sie es doch einfach mal selbst aus und profitieren Sie von diesen Vorteilen.

Ludwig Mittermeier arbeitet im Fachzentrum Architektur in der Corporate-Technology-Abteilung der Siemens AG. Er berät die Siemens-Geschäftsbereiche in Fragen zu Software-Architektur und hilft ihnen, die richtigen Software-Technologien für ihre Produkte auszuwählen.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.