Ein Java-UI-Framework für das Web

Vaadin – ein Java-Webframework im Visier

Florian Müller

Im Bereich der Java-UI-Webframeworks wurden zu Ajax-Hype-Zeiten echte Schlachten ausgetragen. Mittlerweile ist es ruhiger geworden, die Spreu hat sich vom Weizen getrennt. Was bleibt, ist eine Handvoll solider und ausgereifter Frameworks, die für die Entwicklung von Weboberflächen „on top of Java“ eingesetzt werden können. Der vorliegende Artikel stellt das Vaadin-Framework [1] vor. Dabei handelt es sich um ein eher unbekanntes Framework. Die Resultate, die sich basierend auf Vaadin erzielen lassen, sind jedoch beeindruckend – Grund genug, das Framework explizit im Java Magazin vorzustellen.

Benutzeroberflächen im Kontext von Java haben bekanntermaßen eine schwierige Kindheit durchlebt. Die direkten Java-Oberflächentechnologien (AWT, Swing, SWT usw.) sind mittlerweile auf einem robusten Stand, der es ermöglicht, den Einsatz der Technologien in Projekten entsprechend argumentativ zu vertreten. Leider liegt der Fokus bei der Entwicklung von Oberflächen, basierend auf direkten Java-Technologien, jedoch nach wie vor eher auf „rock solid“ und nicht unbedingt auf „smart“. Auch JavaFX konnte nicht dazu beitragen, dass Java-Oberflächen das angestaubte Image der Vergangenheit abstreifen konnten. Gerade im Hinblick auf die heranrollende Welle von Smartphone- und Tablet-Anforderungen wird deutlich, dass man, basierend auf einer Plain Oracle Architecture, den daraus resultierenden Anforderungen nur bedingt gerecht werden kann. Auch der  „Zero-Install“-Ansatz ist de facto nicht vorhanden. Für Shopanwendungen z. B., bei denen es wichtig ist, keine Benutzergruppe auszusperren, kommt der Griff zu einer reinen Java-Technologie nach wie vor nicht in Frage. Es sei jedoch auch bemerkt: Für echte Power-GUIs, bzw. Benutzermasken, die mehr können müssen, als nur einen Warenkorb anzuzeigen und grundsätzlich auf einen hohen Produktivitätsgrad ausgelegt sind, ist Java nach wie vor ein Topkandidat. Das beste Beispiel dafür ist die Eclipse IDE, die von Millionen von Entwicklern tagtäglich eingesetzt wird, um professionell Software zu entwickeln.

Für den Business-to-Business- bzw. Business-to-Consumer-Bereich gilt jedoch der Einsatz von Dritt-Frameworks aus den oben genannten Gründen als durchaus legitim, um optimale Resultate bei der Umsetzung der Kundenanforderungen erzielen zu können. Häufig taucht bei der Frameworkauswahl noch die grundsätzliche Frage „Standard oder nicht?“ auf. An dieser Stelle sei erwähnt: Im Bereich von „On top of Java“-Weboberflächen existiert ein solcher Standard (JSF), und die Auswahl eines Frameworks, das den JSF-Standard entsprechend unterstützt, garantiert im Gegenzug einen hohen Grad an Nachhaltigkeit. Leider bieten die meisten der aktuell am Markt verfügbaren JSF-Implementierungen jedoch nur ein relativ geringes Abstraktionslevel, sodass der Einsatz des JSF-Standards unter Umständen eine bremsende Wirkung auf die Entwicklung haben kann – der Entwickler steht also vor der Entscheidung: Entwicklungskomfort versus Standard. Im Rahmen dieses Artikels wurde der Komfort-Weg eingeschlagen. Vaadin unterstützt den JSF-Standard nicht – dafür kann die Anwendung jedoch komplett in Java geschrieben werden, ohne dass der Entwickler in irgendeiner Form mit JSF-Bibliotheken oder sonstigen JSF/JSP/HTML-Tags in Berührung kommen muss.

Das Vaadin-Framework stammt übrigens aus Finnland und weist eine kleine Historie auf. Vielleicht wird sich der eine oder andere Leser noch an das Ajax-Framework „IT Mill Toolkit“ erinnern. Dabei wurde für das clientseitige Komponenten-Rendering eine proprietäre Eigenentwicklung eingesetzt, die im Jahr 2007 aufgegeben und durch das Google Web Toolkit ersetzt wurde. GWT? Richtig. Vaadin verfolgt den Ansatz, dass man die Crux des clientseitigen Renderings mit sämtlichen Höhen und Tiefen an Google abtreten kann. Das passiert nach dem Motto: „Es langt, wenn sich die GWT-Jungs mit Themen wie Browserinkompatibilitäten herumschlagen. Wir konzentrieren uns auf den Server und die Kommunikation zwischen Client und Server.“ Auch das Lizenzmodell wurde im Rahmen des Architekturwechsels in eine Apache-2.0-Lizenz (open, free, do what you want) überführt. Danach wurde im Rahmen eines Rebrandings auch der alte Name „IT Mill Toolkit“ über Bord geworfen und durch „Vaadin“ ersetzt. Dass Vaadin für das Wort Rentier steht, ist dank Wikipedia schnell in Erfahrung zu bringen. Der Bezug zum Framework wird jedoch erst durch eine kleine Buchstabenrotation ersichtlich: Drehen Sie doch einfach mal das Vaadin-Logo um 90 Grad und Sie werden ein gehörntes Rentier erhalten.

Nach den Soft-Facts wird als Nächstes die Architektur des Frameworks beleuchtet, damit Sie anschließend im Rahmen der Demo-Implementierung das Big Picture kennen und wissen, was hinter den Kulissen des Vaadin-Frameworks passiert. Die Frameworkarchitektur ist in Abbildung 1 dargestellt. 

Abb. 1: Vaadin-Architektur

[ header = Seite 2: Hello-Vaadin-Anwendung ]

Grundsätzlich wählt Vaadin einen altbewährten Ansatz, der auf zwei wesentlichen Schritten bzw. Server-Roundtrips basiert:

  1. Oberfläche an Client übertragen: der Java-Komponentenbaum (repräsentiert die Oberfläche) wird in ein übertragbares und für den Client verständliches Format überführt. Bei Vaadin wird dabei die so genannte UIDL (User Interface Definition Language) eingesetzt. Innerhalb des Clients wird die UIDL mittels GWT Rendering Engine in eine Oberfläche transformiert.
  2. Die clientseitige Vaadin JavaScript Engine protokolliert sämtliche Änderungen im Client (z. B. Feldwert geändert und Button gedrückt) und sendet sie zurück an den Server. Die Änderungen werden auf dem Server verarbeitet und die daraus resultierenden Änderungen im Komponentenbaum zurück an den Client gesendet. Dabei wird ein Delta-Rendering eingesetzt, d. h. es werden nur Änderungen übertragen und nicht die komplette Seite erneut geladen.

Da die gesamte Client-Server-Kommunikation bereits durch Vaadin behandelt wird, kann der Entwickler den Client-Server-Kommunikationsteil als Blackbox betrachten und muss lediglich gegen ein Swing-ähnliches API programmieren. Das vereinfacht die Entwicklung extrem und ermöglicht es, den Fokus der Entwicklung auf den Serverteil der Anwendung zu setzen. Damit erspart man sich die Überlegungen beim Client, ob nun das gesamte Domain-Objekt oder nur ein Teil davon an den Server übertragen werden soll. Der Einstieg in Vaadin erfolgt basierend auf der klassischen „Hallo Vaadin!“-Anwendung. Diese wird jedoch schnell wachsen, denn das Frameworkkonzept erlaubt eine steile Lernkurve.

Die einfachste Art, mit Vaadin durchzustarten, ist die Installation als Eclipse-Plug-ins [2] (HELP│INSTALL NEW SOFTWARE…). Nach der Installation kann direkt ein Projekt mit Vaadin-Struktur erstellt werden: FILE │ NEW │ OTHER │ VAADIN │ VAADIN PROJECT. Das Projekt beinhaltet eine Java-Klasse, die gemäß Listing 1 erweitert wird. 

ackage com.example.hellovaadin;
import com.vaadin.Application;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
public class HellovaadinApplication extends Application
{
@Override
public void init()
{
Window mainWindow = new Window("Hellovaadin Application");
Label label = new Label("Enter your name:");
mainWindow.addComponent(label);
final TextField textfield = new TextField("name");
mainWindow.addComponent(textfield);
Button button = new Button("Say Hello",new Button.ClickListener()
{
public void buttonClick(ClickEvent event)
{
textfield.setValue("Hello " +textfield.getValue());
}
});
mainWindow.addComponent(button);
setMainWindow(mainWindow);
}
} 

Auf das Layout der Anwendung wird an dieser Stelle kein Wert gelegt, die grundlegende Funktionsweise von Vaadin wird in Listing 1 jedoch ersichtlich: Es existieren mehrere Vaadin-Java-Komponenten com.vaadin.Button, com.vaadin.Textfield usw. Sie werden in einen Container eingebettet. In unserem Beispiel wird als Container direkt das Hauptfenster eingesetzt – der Einsatz von weiteren Subcontainern (HorizontalLayout, VerticalLayout usw.) ist möglich, das Konzept der Layouts funktioniert analog zum Swing-Container-Konzept. Um auf Actions zu reagieren, wird dem Button ein ClickListener zugewiesen. Innerhalb des ClickListeners wird die eigentliche Logik der Anwendung implementiert. Ganz klar, in der Praxis würde an dieser Stelle der Aufruf einer Controller-Methode erfolgen. Um das Beispiel jedoch einfach zu halten, wird auf den Controller-Aufruf an dieser Stelle verzichtet. Führen Sie die Anwendung direkt aus der Eclipse-Umgebung via RUN AS │ RUN ON SERVER aus. Dazu sollte ein Tomcat oder sonstiger Servlet-Container in Ihre Eclipse-Umgebung gelinkt sein. Die Anwendung wird im Browser unter folgendem URL gestartet: http://localhost:8080/HelloVaadin/. Voilà, das ist Ihre erste Vaadin-Anwendung, die jetzt nach Belieben angepasst werden kann. Eine Übersicht sämtlicher verfügbaren Vaadin-Komponenten kann direkt der Vaadin-Seite [3] entnommen werden.

Abb. 2: Vaadin-Sampler

Wichtig beim Hinzufügen neuer Komponenten und Anpassungen: Der Server muss bei Veränderungen im Java-Layout bzw. der Java-Logik nicht neu gestartet werden, der Applikation muss jedoch explizit mitgeteilt werden, dass sie neu gerendert werden soll. Das ist über den Parameter ?restartApplication möglich (http://localhost:8080/HelloVaadin/?restartApplication). Sollten Sie jemals das Problem haben, dass Änderungen nicht angezeigt werden, können Sie sicher sein, dass der Parameter nicht gesetzt wurde – eine der häufigsten Stolperfallen im Vaadin-Framework, die Sie jetzt umgehen können.

Abb. 3: Anwendung „Hello Vaadin!“

Als Nächstes soll die „Hallo Vaadin!“-Anwendung erweitert werden (Abb. 3). Als Grundlage wird dabei das „5 Minute Tutorial“ von Vaadin eingesetzt [4]. Um einen stärkeren Praxisbezug herzustellen, wird jedoch das Szenario „Adressbuch“ in eine so genannte Device-Management-Anwendung umgewandelt. In vielen Unternehmen schwirren mittlerweile etliche mobile Demogeräte herum, die verwaltet werden müssen. Statt zukünftig ein verknittertes Excel aus der Schublade zu ziehen, können Sie dann auf einen URL verweisen, die die Ausgabe/Rücknahme von Geräten trackt (Abb. 4).

Abb. 4: Rudimentäres Device Management

Das Erweiterungspotenzial der Anwendung ist grenzenlos. Darüber hinaus beinhaltet die Anwendung eine Login-Maske, die den Zugriff auf die Anwendung kontrolliert. Die Login-Maske ist technisch eine 0815-Coding-Prozedur. Durch ihren Einsatz kommt jedoch ein weiterer wichtiger Aspekt in die Demoanwendung ― die Seitennavigation. Der Sprung von der Login-Maske zur Hauptanwendung zeigt eine rudimentäre Möglichkeit, Navigation basierend auf Vaadin zu implementieren. Zugegeben, das elementare Navigationskonzept von Vaadin ist gewöhnungsbedürftig und vergleichbar mit einer Schultafel: Seiteninhalte werden an die Tafel geschrieben, eine neue Seite bedeutet das Auswischen der Tafel und Hinzufügen neuer Inhalte. Grundsätzlich bewegt sich der Benutzer jedoch nur auf einer festen Tafel, der Sprung zwischen verschiedenen Tafeln (Vaadin Pendant: Application) ist nicht möglich, und den Tafeldienst übernehmen Sie an dieser Stelle. Es stehen jedoch diverse Vaadin-Erweiterungen zur Verfügung [5], [6], die Ihnen Navigationskonzepte zur Verfügung stellen. Im Rahmen der DeviceManagement-Anwendung wird die Navigation jedoch von Hand implementiert. Das gesamte Beispiel liegt als Eclipse-Projekt auf der Leser-CD unter Devicemanagement.zip.

[ header = Seite 3: Hauptanwendung ]

Hauptanwendung

Zunächst wird das Hauptfenster implementiert, das die Erfassung neuer Ausleihvorgänge ermöglicht. Listing 2 zeigt den Aufbau der Oberfläche. Prinzipiell ist das nur eine kleine Erweiterung der Hallo-Welt-Anwendung. Der Swing-Ansatz bleibt jedoch erhalten und es wird ein Komponentenbaum basierend auf Java-Elementen erstellt. Wichtig ist der Aufruf der mainWindow.removeAllComponents()-Methode. Diese sorgt später dafür, dass der Login-Screen nach erfolgreichem Login entfernt wird und die Hauptanwendung im Main-Window platziert wird (Listing 2).

private void initLayout()
{
SplitPanel splitPanel = new SplitPanel(
SplitPanel splitPanel = new SplitPanel(
SplitPanel.OREINTATION_HORIZONTAL);
mainWindow.removeAllComponents(); // clear screen
mainWindow.addComponent(splitPanel);
VerticalLayout left = new VerticalLayout();
left.setSizeFull();
left.addComponent(deviceList);
deviceList.setSizeFull();
left.setExpandRatio(deviceList, 1);
splitPanel.addComponent(left);
splitPanel.addComponent(deviceEditor);
deviceEditor.setSizeFull();
deviceEditor.getLayout().setMargin(true);
deviceEditor.setImmediate(true);
bottomLeftCorner.setWidth("100%");
left.addComponent(bottomLeftCorner);
} 

 Darüber hinaus kommen zwei Vaadin-Komponenten zum Einsatz, die Ihnen out of the Box die Grundfunktionalität der Anwendung zur Verfügung stellen. Es handelt sich um die Table-Komponente deviceList sowie die Formkomponente deviceEditor. Der Formkomponente wird später als Datenquelle ein Eintrag aus der Tabelle zugewiesen. Die Formkomponente generiert automatisch das korrespondierende Formular, das für die Datenanzeige bzw. das Editieren von Daten eingesetzt werden kann. Das Zusammenspiel zwischen Tabellenkomponente und Formular wird in Listing 3 demonstriert. Dabei wird ein Dummy-Datensatz generiert und in die Tabelle eingefügt, darüber hinaus wird der ClickListener für die Tabelle definiert, der eine entsprechende Formularanzeige triggert.

// table cols
private static String[] fields = { "Device", "To", "Date", "Return", "Reason" };
// create dummy data
private static IndexedContainer createDummyData()
{
IndexedContainer ic = new IndexedContainer();
for (String p : fields)
{
ic.addContainerProperty(p, String.class, "");
}
Object id = ic.addItem();
ic.getContainerProperty(id, "Device").setValue("iPad 1");
ic.getContainerProperty(id, "To").setValue("Petje Puck");
ic.getContainerProperty(id, "Reason").setValue("Application Testing");
return ic;
}
private String[] initDeviceList()
{
deviceList.setContainerDataSource(deviceData);
deviceList.setVisibleColumns(visibleCols);
deviceList.setSelectable(true);
deviceList.setImmediate(true);
deviceList.addListener(new Property.ValueChangeListener())
{
public void valueChange(ValueChangeEvent event)
{
Object id = deviceList.getValue();
deviceEditor.setItemDataSource(id == null ? null : deviceList
.getItem(id));
deviceRemovalButton.setVisible(id != null);
}
});
return visibleCols;
} 

Das Hinzufügen neuer Datensätze via Benutzeroberfläche wird an dieser Stelle nicht ausführlich demonstriert. Der Vorgang funktioniert jedoch analog zur Generierung der Dummy-Daten. Als Nächstes soll die bereits angedrohte Navigation umgesetzt werden. Zur Vermeidung von „Riesenklassen“, die sämtliche Layoutinformationen der einzelnen Screens beinhalten, wird eine entsprechende separate Klasse erstellt (Listing 4). Diese erbt von VerticalLayout. Der Screenaufbau wird innerhalb des Konstruktors implementiert. Dabei ist wichtig, dass dem Konstruktor eine Instanz der Hauptapplikation (die Tafel) übergeben wird. Dadurch können innerhalb der Login-Klasse Methoden aus der Hauptanwendung aufgerufen werden. Innerhalb der Hauptanwendung wiederum wird eine Page Switch Routine implementiert (alle Inhalte vom Screen nehmen, neue Inhalte auf den Screen hinzufügen). Diese führt dann bei erfolgreichem Login den eigentlichen Page Switch aus.

public class LoginScreen extends VerticalLayout
{
public DevicemanagementApplication application;
// setup login screen
public LoginScreen(DevicemanagementApplication appcontext)
{
// enable application "context" access...
this.application = appcontext;
LoginForm login = new LoginForm();
login.setWidth("100%");
login.setHeight("300px");
login.addListener(new LoginForm.LoginListener()
{
public void onLogin(LoginEvent event)
{
String un = event.getLoginParameter("username");
String pw = event.getLoginParameter("password");
if (un.equals("dummy") && pw.equals("user"))
{
application.switchToMainPage();
}
}
});
addComponent(login);
}
} 

Das hier dargestellte Layoutkonzept ist etwas fragwürdig, denn sobald eine Anwendung mehr als nur zwei Screens beinhaltet, erhält man ein zähes eng vernetztes Klassenkonstrukt, das Wiederverwendbarkeit von Komponenten nur bedingt möglich macht. An dieser Stelle wird empfohlen, eines der bereits genannten Vaadin-Navigation-Plug-ins einzusetzen. Grundsätzlich sollten Sie an dieser Stelle so weit sein, dass Sie Ihre erste Vaadin-Anwendung erfolgreich erstellt haben oder zumindest die Grundlagenkenntnisse besitzen, um eine solche Anwendung zu erstellen. Neben den bereits vorgestellten Features rund um Vaadin soll noch ein weiteres Add-on des Frameworks vorgestellt werden, dass es Ihnen möglich macht, nicht nur Desktop- und Webanwendungen zu erstellen, sondern auch in den mobilen Bereich vorzudringen. Es handelt sich um das so genannte Vaadin Touch Kit [7].

[ header = Seite 4: Vaadin mobile! ]

Vaadin mobile!

Die Programmierung mittels Touch Kit erfolgt analog zur bereits vorgestellten Programmierung. Einziger Unterschied ist das Hinzufügen eines TouchPanel auf der Hauptapplikation sowie die Verwendung gezielter weiterer Touch-Komponenten (TouchMenu, TouchCommand etc.). Die Resultate sind durchaus beeindruckend: Mit nur wenigen Zeilen Java kommen Sie mittels Vaadin Touch Kit zu einer mobilen Anwendung (natürlich HTML-basiert, von Look and Feel jedoch eng an das iPhone-native Verhalten angelehnt), die es Ihnen beispielsweise ermöglicht, mobile Erweiterungen für die Device-Management-Anwendung zu implementieren (Abb. 5).

 Abb. 5: Vaadin Touch Kit

 Es sei jedoch auch erwähnt, dass sich die Touch-Kit-Implementierung in erster Linie für mobile Erweiterungen eignet, „Instant-Value-Anwendungen“ können jedoch problemlos umgesetzt werden. Leider schlummert das gesamte Touch-Kit-Projekt ein wenig vor sich hin. Der im Jahr 2010 zur Verfügung gestellte Release 1.0 erfüllt zwar sämtliche Basisanforderungen rudimentärer mobiler Szenarien, wünschenswert wären jedoch weitere Komponenten wie indexbasierte iPhone-Listen. Da das gesamte Projekt jedoch quelloffen zur Verfügung steht, kann auch selbst Hand angelegt werden. So gesehen stehen Ihnen als Entwickler alle Türen offen, den Ansatz mobiler Szenarien basierend auf Java umzusetzen.

[ header = Seite 5: Fazit ]

Fazit

Das Vaadin-Framework zählt zwar im europäischen Bereich eher zur Kategorie „Nischenframework“, dennoch sollte nicht der Fehler begangen werden, das Framework im Rahmen von Evaluierungen außen vor zu lassen, nur bedingt durch einen zu geringen Bekanntheitsgrad. Die Community rund um das Framework ist hochaktiv. Fragen, die nicht bereits durch die umfangreiche Dokumentation beantwortet werden, finden spätestens in einem der Vaadin-Foren entsprechende Antworten. Die Tatsache, dass sich Java-Entwickler in ihren gewohnten Gefilden bewegen können, resultiert in einer steilen Lernkurve. Zusätzlich kommt eine ordentliche Portion Motivation in die Entwicklung, bedingt durch die Tatsache, dass Vaadin-Anwendungen im Vergleich zu GWT-Anwendungen von Anfang an gut aussehen. Ganz klar, auch GWT-Anwendungen können mit einigen Styling-Tricks gut aussehen, genau diese entfallen jedoch beim Einsatz von Vaadin. Grundsätzlich kann die Frage GWT versus Vaadin nicht pauschal beantwortet werden, Fakt ist jedoch, dass die Einstiegshürde in Vaadin wesentlich niedriger ist als die GWT-Hürde, da Vaadin deutlich stärker abstrahiert als GWT. Im Gegenzug bedeutet ein höheres Maß an Abstraktion jedoch auch ein geringeres Maß an Konfigurationshoheit. Je nach Komplexität einer Anwendung muss diese Konfigurationshoheit jedoch gegeben sein. Allerdings sollte auch bedacht werden, dass zu viele Stellschrauben am Ende ganz genauso in einer schlechten Architektur resultieren können, wenn beispielsweise die darunter liegenden Frameworkkonzepte falsch verstanden werden. Entsprechend muss je nach Anforderungen abgewogen werden, wie viel Konfigurationshoheit tatsächlich benötigt wird, um eine begründete Frameworkwahl treffen zu können.

Für jeden Java-Entwickler und kleinere Projekte, bei denen keine zweiwöchigen Framework-Ramp-ups eingeplant werden, um das Web-UI umzusetzen, wird zumindest ein Blick auf Vaadin dringend empfohlen. Viel Spaß bei diesem Blick!

Florian Müller arbeitet als Solution Architekt mit dem Schwerpunkt UI-Technologien für den SAP Dienstleister Resource AG Schweiz (http://www.resource.ch). Darüber hinaus betreibt Florian die Plattform Richability (http://www.richability.com), wo regelmäßig über neuste Erkenntnisse aus dem Bereich Frontend Technologien & Entwicklung informiert wird. Sie erreichen ihn via Florian.Mueller[at]richability.com.
Geschrieben von
Florian Müller
Kommentare

Schreibe einen Kommentar

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