Plus CD! Neue Serie: -Business-Modelle >> 78

eclipse magazin 3.2009 JPA mit EclipseLink

Deutschland € 9,80 3.09 Österreich € 10,80, Schweiz CHF 19,20

You spoke. We listened. Introducing Liferay Enterprise Edition.

www.eclipse-magazin.de

>> Bonusartikel „Eclipse DataBinding für die Kommunikation zwischen Modell und GUI“ von Ludwig Mittermeier JPA mit >> Persistenz-Frameworks EclipseLink, EMF Teneo, CDO

>> Tools & Plug-ins Apache POI, Apache Lucene 2.4.0, Luke – Lucene Index Toolbox EclipseLink >> Modeling

Now get the best of both worlds. • Model Query, Net4j RCP bei der Eisenbahn Liferay Enterprise Edition gives you all the benefits of open source with the stability, Weitere Infos S. 3 security, and reliability of an enterprise subscription. And with version 5.1, get the latest in SOA, Social Networking, and Collaboration technology, all at a fraction of the cost of Oracle® or IBM®. Eclipse RCP >> 72 •

Spring Dynamic Modules RCP-Einsatz bei den Schweizerischen Bundesbahnen Liferay 5.1 Enterprise Edition Maintenance Subscription Platinum Support (24x7)

2.950 EUR / server / year 19.950 EUR / server / year Spring Dynamic

Compare Oracle® WebCenter Suite: 125.000 EUR / processor, support 27.500 EUR / yr, as of 6 / 2008 Modules >> 12 • Eclipse SOA Modularisierung mit Spring DM For more information, email us at [email protected].

• Alle Infos zum

Eclipse-Business-Modelle Eclipse SOA >> 80 Was ist guter Service?

ab Seite 53

EclipseLink als JPA-Provider >> 21

EUROPEAN HEADQUARTERS - LANGEN, GERMANY 68864 D LIFERAY GMBH — ROBERT - BOSCH - STRASSE 11, 63225 LANGEN, GERMANY XML Binding mit EclipseLink >> 26 TEL: +49 - (0) 6103 - 3018570 Ý FAX: +49 - (0) 6103 - 3018571 „ EclipseLink bietet multiple Persistenzservices“ EclipseLink-Lead Doug Clarke im Gespräch >> 29 DataBinding für UI-Controls Rich Client Platform

Foto: P. Rudi

Eclipse DataBinding für komplexe UI Controls

Quellcode DataBinding für auf CD! Fortgeschrittene

>> h e i k o b a r t h u n d t h o r s t e n s c h e n k e l

ellen Informationsquellen ist die Eclipse- In vielen Applikationen wird bereits Eclipse DataBinding für die Tren- DataBinding-Wiki-Seite [1], eine andere nung und Synchronisation von grafischer Benutzeroberfläche und dem sind die zwei Dutzend Beispiele im CVS- Repository [2]. Es gibt jedoch auch ver- Modell eingesetzt. Entsprechende Publikationen befassen sich ausgiebig schiedene Artikel zu diesem Thema, die mit den Grundlagen des DataBindings. Dieser Artikel geht einen Schritt sich im Wesentlichen mit den Grundla- gen des Eclipse DataBinding befassen weiter und zeigt, dass Eclipse DataBinding sehr effizient für komplexe UI (Kasten: „Wo gibt‘s mehr zu Eclipse Da- Controls (z. B. Tabellen) verwendet werden kann. taBinding?“). Im Folgenden werden die fortgeschrittenen Aspekte des Eclipse DataBinding anhand verschiedener Bei- clipse DataBinding etabliert sich Wart- und Testbarkeit steigern wieder- spiele im Detail beleuchtet. Einnerhalb des Eclipse-Ökosystems um die Akzeptanz dieser Vorgehenswei- zunehmend als Standard für die einheit- se in den Reihen der -Entwickler. Viewer liche Synchronisation des Graphical Leider reflektiert die aktuell verfüg- JFace erleichtert mit seinen Viewern den User Interface (GUI) mit dem zugrunde bare Dokumentation nicht vollständig Umgang mit komplexeren SWT-Widgets liegenden Datenmodell. Die daraus re- die Möglichkeiten, die in Eclipse Data- wie Table oder Tree. Die Viewer kapseln sultierenden Vorteile in den Bereichen Binding stecken. Eine der wenigen offizi- bestehende SWT-Widgets für eine verein-

www.eclipse-magazin.de eclipse magazin 3.09 43 Rich Client Platform DataBinding für UI-Controls

Abb. 1: ListViewer Abb. 2: Master-Detail fachte Anbindung eines Datenmodells. feuert. Das Ganze sieht im Code dann Klasse Person liefert toString den Nach- Eclipse DataBinding erweitert dieses wie folgt aus: namen. Konzept durch verschiedene Adaptoren Um eine Änderung innerhalb eines für einen vereinheitlichten Zugriff auf ListViewer viewer = new ListViewer(shell); Personenobjekts automatisch in dem das Datenmodell. Am einfachsten kann viewer.setContentProvider List Widget zu reflektieren, ist ein wei- anhand des List Widgets die Verwen- (new ObservableListContentProvider()); terer Schritt notwendig. Das Modellob- dung von JFace-Viewern und Eclipse List persons = createPersonsList(); jekt muss eine Schnittstelle anbieten, die DataBinding veranschaulicht werden. In WritableList input = new WritableList es erlaubt, dessen Properties zu über- einem kleinen Beispiel sollen die Namen (persons, Person.class) wachen. Nur auf diese Weise besteht viewer.setInput(input); von Personen in einer Liste angezeigt die Möglichkeit, Änderungen direkt werden. Als Modell liegt eine Liste mit weiterzugeben. Anschließend kann sich Instanzen der Klasse Person vor: Änderungen an der WritableList werden ein spezieller LabelProvider über diesen auf diese Weise sofort in dem UI reflek- Mechanismus an dem Modellobjekt public class Person { tiert. Der ObservableListContentPro- registrieren und die Wertänderungen private String lastName; vider überwacht die Liste und leitet Än- an das User Interface weitergeben. Die public Person(String lastName) { derungen an das Widget weiter. Hierfür Vorgehensweise ist der Überwachung this.lastName = lastName; wird der Quellcode wie folgt erweitert. der WritableList sehr ähnlich. Exemp- } Dem GUI wird ein Button hinzugefügt, larisch erweitern wir nun den Code wie der das selektierte Element aus der Per- folgt: In unserem Beispiel wird zunächst public void setLastName(String lastName) { sonenliste löscht: ein Button hinzugefügt, der den Nach- this.lastName = lastName; } namen komplett in Groß- bzw. Klein- Button removeButton = new Button(shell, SWT.PUSH); buchstaben umwandelt: removeButton.setText("Remove"); public String getLastName() { removeButton.addSelectionListener return lastName; Button changeButton = new Button(shell, SWT.PUSH); (new SelectionAdapter() { } changeButton.setText("Change to upper/lower case"); @Override changeButton.addSelectionListener public void widgetSelected(SelectionEvent e) { @Override (new SelectionAdapter() { if (viewer.getSelection().isEmpty()) { public String toString() { return; return getLastName(); } Wo gibt´s mehr zu } Person p = (Person) ((IStructuredSelection) viewer Eclipse DataBinding? .getSelection()).getFirstElement(); In dieser Ausgabe des Eclipse Magazins: } input.remove(p); „EMF und SWT: Datenmodell und UI effizient } verheiratet!“ von Matthias Heinrich und Für Listen bietet das Eclipse DataBin- }); Henrik Lochmann. ding bereits einen passenden Content- Auf der Heft-CD und auf JAXenter.de: Provider: ObservableListContentPro- Nach dem Löschen des selektierten Ele- „Daten und ihre Bindungen“ von Ludwig vider. Um ihn verwenden zu können, ments wird dieses nicht mehr in der UI- Mittermeier: www.jaxenter.de/artikel/1353, muss dem ListViewer von JFace eine Liste angezeigt: Die Daten wurden von „Eclipse Forms im Härtetest“ von Marco van Liste übergeben werden, die IObser- dem Modell zum User Interface synchro- Meegen: www.jaxenter.de/artikel/1816. vableCollection implementiert. Wir nisiert. Anderswo: „Eclipse DataBinding + Valida- entscheiden uns für eine WritableList, Eine Person wird in der Liste als tion + Decoration“ von Kai Tödter: http:// die eine Liste von Personen kapselt. Der String gerendert, der den Nachnamen eclipse.dzone.com/articles/eclipse-databin- ding-validation, „Eclipse DataBinding with Mehrwert der Kapselung besteht darin, repräsentiert. Der standardmäßige La- Eclipse RCP Applications – Tutorial“ von dass eine IObservableCollection über belProvider des ListViewer ermittelt Lars Vogel: http://www.vogella.de/articles/ das Observer Pattern überwacht wer- den angezeigten Wert über die toString- EclipseDataBinding/article.html den kann und bei Änderungen Events Methode des Modellobjekts. In der

44 eclipse magazin 3.09 www.eclipse-magazin.de DataBinding für UI-Controls Rich Client Platform

@Override Master-Detail public void widgetSelected(SelectionEvent e) { Häufig findet man in UIs das folgende if (viewer.getSelection().isEmpty()) { Szenario: Im UI gibt es eine Liste, Ta- return; belle oder einen Baum, wo ein Element } selektiert werden kann. Entsprechend Person p = (Person) ((IStructuredSelection) viewer .getSelection()).getFirstElement(); der Selektion sollen detailliertere Infor- if (p.getLastName().toUpperCase().equals mationen angezeigt und möglicherwei- (p.getLastName())) { se bearbeitet werden. Beispielsweise p.setLastName(p.getLastName().toLowerCase()); kann es sich bei dem selektierten Ele- } else { ment um eine Person handeln, und die p.setLastName(p.getLastName().toUpperCase()); editierbaren Details sind neben dem } Namen auch die Telefonnummer oder } das Geburtsdatum. Für solche Szenari- }); en hat sich der Begriff „Master-Detail“ durchgesetzt. Im nächsten Schritt muss die Klasse Wir wollen unser Beispiel erweitern, Person angepasst werden. Diese Klas- um die Unterstützung von Eclipse Da- se muss um PropertyChangeSupport taBinding bezüglich Master-Details zu erweitert werden. Außerdem wird ein veranschaulichen. Die Klasse Person er- LabelProvider benötig, der sich an ei- hält zwei neue Properties: firstName und nem Objekt als Observer registriert und telephoneNumber. Damit die Details im Events weiterleitet. Eclipse DataBin- GUI angezeigt werden können, fügen wir ding stellt hierfür die Klasse Observ- drei Textfelder hinzu: ableMapLabelProvider zur Verfügung. Der Konstruktor der Klasse erwartet als Text lastName = new Text(shell, SWT.BORDER); Parameter ein IObservableMap. In die- lastName.setEditable(false); ser Map steht, welches Attribut welcher Text firstName = new Text(shell, SWT.BORDER); Elemente bezüglich Änderungen beob- firstName.setEditable(false); Anzeige achtet werden soll. In unserem Beispiel Text telephoneNumber = new Text(shell, SWT.BORDER); wird das Attribut lastName der Person telephoneNumber.setEditable(false); überwacht. Wir erstellen die IObserv- ableMap mithilfe der von BeansObserv- Jetzt müssen die Details mit der Auswahl ables angebotenen Methode observe- in der Liste verbunden werden. Drei Map: Schritte sind notwendig. Zuerst muss die Selektion in der Liste beobachtet werden ListViewer viewer = new ListViewer(shell); (ViewersObservables.observeSingle ObservableListContentProvider contentProvider = Selection), dann das Property (Detail) new ObservableListContentProvider() in der Selektion (BeansObservables. viewer.setContentProvider(contentProvider); observeDetailValue), und zuletzt muss IObservableMap observableMap = das Detail mit dem Textfeld gebunden BeansObservables.observeMap( werden. Der zweite und der dritte Schritt contentProvider.getKnownElements(), wiederholen sich für die beiden anderen Person.class, "lastName"); viewer.setLabelProvider(new ObservableMapLabelProvider Properties: (observableMap)); List persons = createPersonsList(); DataBindingContext dbc = new DataBindingContext(); WritableList input = new WritableList(persons, // 1. Observe changes in selection. Person.class) IObservableValue selection = ViewersObservables viewer.setInput(input); .observeSingleSelection(viewer); // 2. Observe the property of the current selection. Die Methode observeMap nimmt nicht IObservableValue detailObservable = BeansObservables entsprechend unseres Modells eine Liste .observeDetailValue(Realm.getDefault(), selection, entgegen, sondern ein IObservableSet. "lastName", String.class); Glücklicherweise bekommt der Java- // 3. Bind the Text widget to the detail Entwickler dieses Set vom Observab- dbc.bindValue(SWTObservables.observeText( leListContentProvider geliefert. Wenn lastName, SWT.None), detailObservable, null, null); wir nun unser Beispiel starten, sehen wir, dass die Änderung der Groß- bzw. Wird in der Liste nun eine Person ausge- Kleinschreibung sofort in der UI-Liste wählt, werden in den Textfeldern die da- angezeigt wird. zugehörigen Details angezeigt.

www.eclipse-magazin.de Rich Client Platform DataBinding für UI-Controls

für die Spalten und der aktuelle Kontext TableViewer Damit alle Spalten sichtbar sind, müssen des DataBindings übergeben werden. Im Im Beispiel soll anstelle einer Liste eine sie auch erzeugt werden: Beispiel übergeben wird noch den Na- Tabelle verwendet werden. Der List- men der Property. Im Konstruktor wird Viewer wird einfach durch den Table- TableViewerColumn columnLastName = der Editor für die Zelle erzeugt. Für die Viewer ersetzt. Auf den ersten Blick ist new TableViewerColumn(viewer, SWT.NONE); Strings unserer Modellklasse bietet sich auch der Unterschied im GUI minimal. columnLastName.getColumn().setText("Last Name"); ein Editor an, der als Control ein Textfeld Wollen wir aber mehr als eine Spalte an- columnLastName.getColumn().setWidth(80); liefert (TextCellEditor). Die Methode do- zeigen, benötigen wir für den LabelProvi- TableViewerColumn columnFirstName = new CreateCellEditorObservable sorgt dafür, der mehr als nur eine Map. Der Observ- TableViewerColumn(viewer, SWT.NONE); dass Änderungen im Textfeld beobachtet columnFirstName.getColumn().setText("First Name"); ableMapLabelProvider kann auch ein Ar- und gemeldet werden, und doCreateEle- columnFirstName.getColumn().setWidth(80); ray von Maps entgegennehmen, und mit TableViewerColumn columnTelephone = mentObservable tut dies für die Property BeansObservables.observeMaps kann new TableViewerColumn(viewer, SWT.NONE); unseres Modells. getCellEditor liefert im- man dieses Array sehr einfach erstellen columnTelephone.getColumn().setText mer den Editor, den wir bereits im Konst- lassen. Das sieht im Quellcode so aus: ("Telephone Number"); ruktor erstellt haben. Somit sieht unsere columnTelephone.getColumn().setWidth(100); Implementierung wie in Listing 1 aus. IObservableMap[] observableMaps = BeansObservables. Den folgenden Editor benötigen wir observeMaps( Dank Eclipse DataBinding bleibt die jetzt für jede Spalte: peopleViewerContentProvider.getKnownElements(), komplette Funktionalität des Beispiel- Person.class, new String[] { "lastName", "firstName", programms auch mit der Tabelle erhalten. columnLastName.setEditingSupport(new ViewerEditor "telephoneNumber" }); Etwas aufwändiger wird es, wenn die Zel- Support(viewer, dbc, "lastName")); viewer.setLabelProvider(new ObservableMapLabelProvide len der Tabellen editierbar werden sollen. r(observableMaps)); Jede Spalte muss einer Klasse (Editing- TreeViewer Support) übergeben werden, die den Erst mit Eclipse 3.4 bietet das Eclipse Da- Listing 1 Editor liefert. Eclipse DataBinding stellt taBinding eine Unterstützung für Bäume private static class ViewerEditorSupport extends die abstrakte Klasse ObservableValue- im UI. Die Vorgehensweise beim Anbin- ObservableValueEditingSupport { EditingSupport bereit, um Zelleditor und den eines Modells ist der für Tabellen sehr DataBinding zusammenzuführen. Dem ähnlich. Der Hauptunterschied ergibt private CellEditor cellEditor; Java-Entwickler obliegt es, den Kon- sich aus der Struktur des Datenmodells. private String property; struktor und drei Methoden zu implemen- Als Modell liegt nicht, wie in einer Tabel- tieren. Dem Konstruktor muss der Viewer le, eine Liste vor, sondern ein Baum. Um public ViewerEditorSupport(ColumnViewer viewer, DataBindingContext dbc, String property) { Listing 2 super(viewer, dbc); cellEditor = new TextCellEditor((Composite) IObservableValue firstNameOV_ui = SWTObservables.observeText(firstNameText, SWT.FocusOut); viewer.getControl()); firstNameOV_model = BeansObservables.observeValue(model, ”firstName“); this.property = property; context.bindValue(firstNameOV_ui, firstNameOV_model, null, null); } IObservableValue lastNameOV_ui = SWTObservables.observeText(lastNameText, SWT.FocusOut); lastNameOV_model = BeansObservables.observeValue(model, “lastName“); @Override context.bindValue(lastNameOV_ui, lastNameOV_model, null, null); protected IObservableValue doCreateCellEditor IObservableValue computed_ui = SWTObservables.observeText(computedNameText, SWT.Focu- Observable( sOut); CellEditor cellEditor) { IObservableValue computed_model = new FullNameObservable(); return SWTObservables.observeText context.bindValue(computed_ui, computed_model, null, null); (cellEditor.getControl(), SWT.FocusOut); .... } private class FullNameObservable extends ComputedValue { @Override protected IObservableValue doCreateElement @Override Observable(Object element, protected Object calculate() { ViewerCell cell) { String firstName = (String) firstNameOV_model.getValue(); return BeansObservables.observeValue(element, String lastName = (String) lastNameOV_model.getValue(); property); StringBuilder builder = new StringBuilder(); } builder.append(lastName); if (lastName.length() > 0) { @Override builder.append(”, ”); protected CellEditor getCellEditor(Object element) { } return cellEditor; builder.append(firstName); } return builder.toString(); } } }

46 eclipse magazin 3.09 www.eclipse-magazin.de DataBinding für UI-Controls Rich Client Platform

die für einen Baum übliche Parent-Child- ObservableListTreeContentProvider peopleViewerContent zu welchen Zeitpunkten ein Computed- Beziehung zu modellieren, erweitern Provider = new ObservableListTreeContentProvider( Value berechnet werden soll. Betrachten wir die Klasse Person um die Property listFactory, null); wir das Beispiel aus Listing 2: Computed- viewer.setContentProvider(peopleViewerContentProvider); children, die eine Liste von Personen Value berechnet sich über das IObservable viewer.setInput(root); (List) hält. Der TableView- für den Nachnamen und das IObservable er wird durch TreeViewer ersetzt. Dem für den Vornamen. getValue liefert die ent- TreeViewer wird keine WriteableList, Den Button Remove entfernen wir aus sprechenden Werte konkateniert zurück. sondern das Wurzelelement des TreeMo- dem GUI, da unser Modell das Löschen ComputedValue ist gegen ein Textfeld dels als Input übergeben. Den LabelPro- von Children nicht unterstützt. (computedNameText) gebunden. vider können wir so belassen, aber da im ComputedValue soll immer dann ak- Baum nur die erste Property angezeigt ComputedValue tualisiert werden, wenn sich entweder der wird, verwenden wir wieder nur eine Eine weitere hilfreiche Klasse von Eclipse Vorname oder der Nachname ändert. Und IObservableMap, und zwar die für last- DataBinding ist ComputedValue. Diese das Überraschende ist, dass unser Beispiel Name. Die größte Änderung betrifft den Komponente ist eine spezielle Ausprä- genau diese Funktionalität schon anbietet. ContentProvider. Für einen Baum wird gung von IObservableValue. Der Wert Wie wird ComputedValue darüber infor- ObservableListTreeContentProvider eines ComputedValues leitet sich aus den miert, dass sich eine seiner Abhängigkeiten eingesetzt. Dem Konstruktor wird zuerst Werten anderer IObservableValues ab. ändert, ohne dass wir einen entsprechen- eine Factory übergeben, die dafür sorgt, Die Ermittlung des Werts wird in der Me- den Observer an diesen registriert haben? dass die Children jedes Knotens über- thode calculate implementiert. Von hier An dieser Stelle kommt der Observable- wacht werden. Da die Children in unse- aus können beliebige andere IObservables Tracker ins Spiel. Mithilfe dieser Kom- rem Beispiel in einer Liste abgespeichert nach deren Werten gefragt werden, um die ponente ist es möglich, beliebigen Code sind, übergeben wir eine Factory, die eine Parametermenge der Berechnung zu fül- auszuführen und dabei alle IObservable- solche beobachtet. Die wichtigsten Ände- len. Calculate wird immer als Konsequenz Values zu sammeln, deren get-Methode rungen auf einen Blick sind: von getValue aufgerufen. Diese Funktio- aufgerufen wurde. Als Hintergrundin- nalität lässt sich auf einfache Weise selbst formation sei noch darauf hingewiesen, IObservableFactory listFactory = implementieren. Wo liegt der Mehrwert dass die Klasse AbstractObservableValue BeansObservables.listFactory(Realm.getDefault(), des ComputedValue? Um diese Frage zu im Code der getValue-Methode sich bei "children", Person.class); beantworten, ist es wichtig zu verstehen, dem Observ-ableTracker automatisch

Anzeige Rich Client Platform DataBinding für UI-Controls

registriert. Genau diese Funktionalität box benötigen wir zwei IObservableValue tiert die Methode so, dass das Runnable macht sich der ComputedValue zu Nutze. für die beiden Checkboxen. Somit kann in auf dem User Interface Thread ausgeführt Er ruft nach der Instanziierung die eigene der Methode calculate der Klasse Com- wird. Durch diese Abstraktion von dem calculate-Methode über den Observ- putedList die Liste erzeugt werden (Listing Widget Toolkit steht auch der Verwen- ableTracker auf und erhält implizit die 3). Wie bereits bei ComputedValue funkti- dung von Realms innerhalb von Swing Liste seiner Abhängigkeiten in Form von oniert dies ohne weitere Observer, da auch oder anderen Toolkits nichts im Weg. Ein IObservables. Bei jedem dieser IObserv- ComputedList vom ObservableTracker Realm kann einer Instanz von DataBin- ableValues registriert er sich als Observer über die Änderungen informiert wird. dingContext übergeben werden. und kann auf Wertänderungen reagieren. DelayedObservableValue Fazit ComputedList Eine interessante Komponente ist das De- Eclipse DataBinding ermöglicht eine ComputedList ist eine weitere Kompo- layedObservableValue. Diese Komponen- einheitliche Synchronisation von Da- nente des Eclipse DataBindings, deren te wird im Bereich von Textfeldvalidierun- tenmodellen mit UI Widgets und wird in Werte sich aus anderen IObservableVa- gen eingesetzt. DelayedObservableValue verschiedenen Projekten innerhalb von lues ergeben. Die Methode calculate liefert kapselt ein ISWTObservableValue und Eclipse standardmäßig eingesetzt. Mithil- eine Liste von Werten zurück, deren Inhalt gibt dessen Events erst verzögert weiter. fe der zahlreichen Convenience APIs wird entsprechend der Abhängigkeiten ermit- Nachfolgende gleichartige Events inner- auch das Binden von komplexen UI Cont- telt wird. Um die Auswirkungen zu veran- halb der Verzögerungszeit überschreiben rols zum Kinderspiel. Die Wartbarkeit des schaulichen, kodieren wir folgendes klei- den Event. Auf diese Weise wird z. B. bei Codes wird durch die Nutzung von Eclipse nes Szenario: Wir haben eine Combobox, einer Bindung an ein Textfeld verhindert, DataBinding gesteigert. Außerdem stellen in der die Namen von Personen angezeigt dass nach jedem Tastendruck eine Validie- verschiedene Projekte Erweiterungen be- werden. Über zwei Checkboxen wird be- rung stattfindet. Erst wenn die Tastatur reit, die den Umgang mit Eclipse DataBin- stimmt, ob weibliche und/oder männliche über die Dauer der Verzögerungszeit ruht, ding noch weiter vereinfachen und aufzei- Personen erscheinen sollen. Das UI besteht werden observierende Objekte informiert. gen, wie elegant eine Integration in andere somit aus drei Komponenten: Eine Ausnahme ist das Verlassen des SWT UI Toolkits (u. a. Swing, GWT) möglich Widget. Dieser Fall wird entsprechend des ist. Besonders Riena [3], EMF [4] (Eclipse men = new Button(shell, SWT.CHECK); Ablaufs der Verzögerung behandelt. Um Modeling Framework) und UFace [5] sind men.setText("Men"); von dem Mehrwert von DelayedObserva- women = new Button(shell, SWT.CHECK); bleValue zu profitieren, ist es also wichtig, women.setText("Women"); im Fall einer Textfeldüberwachung das zu Heiko Barth ist Diplom-Informatiker Combo combo = new Combo(shell, SWT.DROP_DOWN | und seit 2006 als IT-Consultant, kapselnde Observable mit dem Flag SWT. Coach und Entwickler bei der com- SWT.READ_ONLY); MODIFY zu erzeugen. viewer = new ComboViewer(combo); people AG in Frankfurt tätig. Den Schwerpunkt seiner Tätigkeit bildet Realms die Entwicklung von Smart-Client-Architekturen Zur Berechnung des Inhalts der Combo- Innerhalb von Eclipse DataBinding spie- und -Anwendungen. Darüber hinaus beschäftigt len Realms – verborgen vor dem Entwick- er sich mit Eclipse Equinox und der Rich Client ler – eine wichtige Rolle. Realms reprä- Platform. Heiko Barth ist aktiver Commiter des Eclipse-Riena-Projekts. Listing 3 sentieren einen beliebigen Kontext, der zu final IObservableValue womenObservable = einem Zeitpunkt aktiv oder inaktiv sein SWTObservables.observeSelection(women); kann. Im Bereich von SWT entspricht der Thorsten Schenkel ist als IT-Consul- final IObservableValue menObservable = Kontext gewöhnlich dem User Interface tant und Softwareentwickler bei der SWTObservables.observeSelection(men); Thread. Das zugehörige Realm ist Dis- compeople AG in Frankfurt tätig. Er viewer.setContentProvider(new beschäftigt sich seit 1999 intensiv mit playRealm. Bevor eine Aktion innerhalb ObservableListContentProvider()); Client-Server-Anwendungen sowie IObservableList filteredList = new ComputedList() { eines Observables ausgeführt wird, gibt grafischen Benutzeroberflächen im Java-Umfeld, @Override es einen Aufruf von checkRealm(). Hier- und in den letzten Jahren verstärkt mit Anwendun- protected List calculate() { durch wird sichergestellt, dass das aktuelle gen auf Basis der Eclipse RCP. Seit Ende 2007 ist er List result = new ArrayList(); Realm gültig ist. In dem von SWT verwen- aktiver Committer des Eclipse-Riena-Projekts. for (Person person : persons) { deten DisplayRealm wird an diesem Punkt if (((Boolean) womenObservable.getValue()) überprüft, ob der Code auf dem aktuellen && person.getGender() == Gender.FEMALE) { result.add(person); User Interface Thread ausgeführt wird. Ist Links & Literatur dies nicht der Fall, gibt es eine Exception. } else if (((Boolean) menObservable.getValue()) [1] Eclipse-DataBinding-Wiki-Seite: http://wiki. && person.getGender() == Gender.MALE) { Auf diese Weise wird einer Inkonsistenz eclipse.org/index.php/JFace_Data_Binding result.add(person); des User Interface vorgebeugt. Neben der [2] CVS-Repository: org.eclipse..examp- } reinen Überprüfung, ob ein Realm aktuell les.databinding/src/org/eclipse/jface/ } gültig ist, besteht auch die Möglichkeit, examples/databinding/snippets return result; die Ausführung von Code innerhalb eines } [3] Riena: http://www.eclipse.org/riena/ }; Realms zu erzwingen. Dies geschieht über [4] EMF (Eclipse Modeling Framework): http:// viewer.setInput(filteredList); Realm.asyncExec (final Runnable runn- www.eclipse.org/modeling/emf/ able). Der SWT-DisplayRealm implemen- [5] UFace: http://code.google.com/p/uface/

48 eclipse magazin 3.09 www.eclipse-magazin.de