Praktische Einführung in die Datenhaltung von Vaadin

Seite 2: Ereignisse handhaben

Inhaltsverzeichnis

Das direkte Synchronisieren zwischen zwei Steuerelementen mag nützlich sein, interessant wird Data Binding erst, wenn Entwickler im Code Behind auf Änderungen an den in den diversen Stores enthaltenen Informationen reagieren können. Dazu müssen sie die EnterView um die Implementierung eines Listeners erweitern, der in Form eines eine Methode implementierenden Interfaces vorliegt. Das ist zudem beim Erzeugen der Data Source bei ebendieser anzumelden, was zu einer Gruppe von Änderungen führt. Zuerst das Anlegen des Listeners:

public class EnterView extends VerticalLayout
implements View, ValueChangeListener
{
ObjectProperty myDS;
@Override
public void enter(ViewChangeEvent event) {
...
myDS.addListener(this);
...

Da es jetzt noch keinen Sinn ergibt, sich mit Logik zu beschäftigen, können Entwickler die Methode für die Ereignisverarbeitung folgendermaßen implementieren:

@Override
public void valueChange(ValueChangeEvent event) {
System.out.println("Event occurred");

}

Damit ist das Programm abermals ausführungsbereit: Änderungen in der Textbox resultieren in der Debugger-Konsole von Eclipse in der Ausgabe des Strings "Event occurred". Als Nächstes geht es um die Frage, was passiert, wenn eine Data-Binding-Beziehung zwischen verschiedenen Typen aufgebaut werden soll. Ein Klassiker dafür wäre beispielsweise ein Slider, der in Vaadin – wie früher besprochen – double-Werte zurückliefert, die eine Textbox nicht ohne Weiteres verarbeiten kann. In komplexen Berechnungsmodellen würde man diese Aufgabe über zwei Properties angehen. Geht es primär um Benutzer-Interfaces, bietet Vaadin mit Konvertern eine durchaus attraktive Alternative an.

Da Vaadin rund zwei Dutzend vorgefertigte Konverter mitbringt – eine vollständige Liste findet sich in der Dokumentation in der Rubrik "All Known Implementations" – setzt sich der Artikel stattdessen mit einem komplett eigenen Konverter auseinander. Dazu müssen Entwickler im ersten Schritt eine neue Klasse einfügen, die folgendes Interface implementiert:

public class HeiseSliderConverter implements Converter<String, Double>{
}

Es geht um einen Konverter, der als String anzuzeigende Informationen in das im Code Behind verwendete Modellformat umwandelt. Diese Unterteilung ist keine Pedanterie des Autors – wer die Klasse reflektiert, findet sich mit folgendem Code konfrontiert:

public interface Converter<PRESENTATION, MODEL> extends Serializable {

Das Vaadin-Team weist in der Dokumentation der Klasse darauf hin, dass Konverter per Definition zustandslos und threadsicher sein müssen. Diese Regularien implizieren, dass sie aus dem Konverter heraus keine Änderungen an Modellen, globalen Zuständen oder gar Benutzersteuerelementen vornehmen dürfen. Mit diesem Wissen lässt sich zur Implementierung der vier Konvertermethoden schreiten. GetModelType und GetPresentationType sind dabei nicht sonderlich komplex – die Funktionen geben einfach das Class-Objekt des jeweiligen Datentyps zurück:

@Override
public Class<Double> getModelType() {
return Double.class;
}

@Override
public Class<String> getPresentationType() {
return String.class;
}

Teil zwei der Aufgabe betrifft die eigentliche Vermittlung zwischen dem Modell- und dem
Präsentationsdatentyp. Die Umwandlung von Double in String ist dabei einfach – value liefert den Wert, der nachher per Return zurückgegeben wird:

@Override
public String convertToPresentation(Double value, Class<? extends String> targetType, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
return value.toString();
}

Der Weg in die andere Richtung ist insofern schwieriger, als das Parsen von Strings in Doubles nicht immer erfolgreich verlaufen muss: Es kann auch zu einer Exception kommen. Die Spezifikation der Converter-Klasse deckt dieses Problem mit der ConversionException ab, die der Autor in convertToModel folgendermaßen einspannt:

@Override
public Double convertToModel(String value, Class<? extends Double> targetType, Locale locale)
throws com.vaadin.data.util.converter.Converter.ConversionException {
try{
return Double.parseDouble(value);
}
catch (Exception e){
throw new ConversionException();
}
}

Als Nächstes ist der Konverter zwischen den Steuerelementen zu platzieren. Vaadin funkt hierbei dazwischen, da das Anmelden der Konverter-Klasse mittels setConverter immer beim Steuerelement erfolgen muss, das den Präsentationstyp enthält. Wer einen Konverter in der Textbox anmelden möchte, muss mit dem Anpassen des Typs der ObjectProperty beginnen:

public void enter(ViewChangeEvent event) {. . .
myDS=new ObjectProperty<Double>(1.1, Double.class);

Im nächsten Schritt folgt das Anlegen von Textbox und Slider-Steuerelement. Der hier verwendete Code orientiert sich im Großen und Ganzen daran, was im früheren Vaadin-Artikel realisiert wurde:

TextField myField=new TextField();
myField.setImmediate(true);
myField.setPropertyDataSource(myDS);
myField.setConverter(new HeiseSliderConverter());
addComponent(myField);
Slider mySlider=new Slider();
mySlider.setPropertyDataSource(myDS);
addComponent(mySlider);
Mehr Infos

Groß oder klein geschrieben?

Bei der Arbeit mit Primitivdatentypen sollten Entwickler im Hinterkopf behalten, dass der Java-Sprachstandard Wrapper-Klassen anbietet. Im Fall von "double" lautet der korrekte Name beispielsweise "Double".

Ob das Programm funktioniert, lässt sich – schon jetzt – durch Ausführen im Tomcat verifizieren. Zu beachten ist allerdings, dass Vaadin den Inhalt von Textboxen erst aktualisiert, wenn Nutzer den Editierprozess beenden. Sie müssen den Inhalt durch Wegbewegen des Cursors oder durch Drücken von Enter bestätigen, bevor der Inhalt des Labels angepasst wird.