Tipps und Tricks zu JavaFX2.0

Ich lerne gerade JavaFX2.0 kennen und sammle hier meine Erkenntnisse zu einzelnen Themen. Wieso JavaFX2.0? Hauptgrund sind zum Einen die Erwartungen der Benutzer, die mit einem simplen Formular und ein paar Bildchen nicht mehr zu begeistern sind und zum Anderen die unüberschaubare Anzahl von Web-Frameworks, die am Ende des Tages doch an Browser-Inkompatibilitäten scheitern.

Bei JavaFX2.0 geht es darum, die Produktivität zu erhöhen, in dem der Benutzer seine gewohnten Handgriffe schneller und zuverlässiger ausführen kann.

Dabei geht's um verschiedene Aspekte: Funktionalität, Zuverlässigkeit und Optik.

Los geht's mit Funktionalität:

JavaFX2.0 ist Java. Alles was in der Vergangenheit clientseitig funktioniert hat, ist immer noch korrekt. Dazu kommen starke Controls, wie WebView, TableView, TreeView und Toolbar und GUI-Elemente für die Organisation des GUIs, wie Accordion. Dazu gleich mehr ...

Zentral sind Properties und Bindings. Properties erinnern an getter-/setter-Methoden aus JavaBeans-Zeiten (also: gestern). Zusätzlich zur Basisfunktionalität der Kapselung bieten Properties Observable-Funktionalität und Support für Binding. Grundsätzlich können Properties über Binding verknüpft werden. Das bedeutet, dass bei der Änderung eines Properties andere Properties automatisch neu gesetzt (z.B. berechnet) werden. Mehr Infos hier. Beide Themen sind zentral für JavaFX.

Tipp zu Binding: für Layout nie Binding verwenden. Die Performance leidet und der Code wird unlesbar. Verwende die entsprechenden Panes für die optische Anordnung von GUI-Elementen. Optimal für Bindings sind die Datenstrukturen hinter Tabellen, Trees oder eigenen JavaFX2.0 GUI-Elementen. Der Callback in die GUI Aktualisierung entfällt, wenn Datenstrukturen direkt mit den zugehörigen Elementen verknüpft sind.

JavaFX2.0 kommt mit neuen Collections (List und Map-style), die einen über inhaltliche Änderungen informieren. Beide lassen sich von FXCollections aus herkömmlichen Collections erzeugen.

WebView

Hierbei handelt es sich um eine komplette webkit-basierte HTML-Engine inkl. JavaScript, die überall ins GUI integriert werden kann. Der Inhalt kann über eine URL oder direkt als HTML übergeben werden.

URL:

 WebView wv = new WebView();
 WebEngine we = wc.getEngine();
 we.load("http://...");

direkt als HTML:

 WebView wv = new WebView();
 WebEngine we = wc.getEngine();
 we.loadContent("...");

TableView

Im Unterschied zu Swing entfällt die Implementierung eines TableModels und die ganze optische Gestaltung ist in CSS ausgelagert. Somit beschränkt sich die Implementierung der TableView auf die Funktionalität.

Dank Generics können Tabellen einfacher gebaut werden als früher unter Swing. Dazu braucht man zuerst ein Model-Klasse, die eine Zeile der Tabelle repräsentiert. Dazu reicht im Prinzip ein POJO; in den Beispielen sieht man häufig Beans mit Properties. Dies hilft natürlich sehr, wenn man automagisch aktualisierte Werte braucht.

Wenn man das Model hat, definiert man Tabellenspalten und fügt sie der TableView hinzu. Im Unterschied zu früher ist Sortierung (auch nach mehreren Spalten [aktivierbar mit SHIFT] ) standardmässig integriert. Die Optik kann mit CSS angepasst werden.

TreeView

Ähnlich wie bei der TableView entfällt auch hier die explizite Model-Implementierung. Man baut einen Baum mit TreeItems mit der Methode node.getChildren().add(myNode). Als Label für ein TreeItem wird toString() auf dem enthaltenen Value verwendet.

ToolBar

Eine ToolBar bietet kaum Überraschungen. Es lassen sich Effekte auf eine ToolBar anwenden; sinnvoll ist dies nicht. Schön wäre es eine ToolBar detachable zu definieren. Dies scheint aber (noch) nicht zu gehen.

 

Nun zur Zuverlässigkeit:

Es lohnt sich Auswahllisten und Daten, die selten ändern oder gar historische Daten sind, lokal zu speichern (mindestens in memory, evtl. auch echt persistent). Sämtliche aus der Client-Server-Entwicklung bekannten Tricks sind hier nicht verkehrt. Einzig das Bauen von GUIs "auf Vorrat" lohnt sich weniger. Gegenüber Panel-basierten GUIs mit GridBagLayout ist die Performance-Steigerung bei JavaFX2.0 enorm.

Zum Schluss die Optik:

Keep it simple! Perfekte Farbkombinationen und Schatten werden nie entsprechend honoriert. Im Gegenteil! Die hier verwendete Zeit bekommt keine Budget-Position. Beim Bauen eines GUIs mit einfachen Layouts anfangen und Benutzer-Feedback abwarten. Mit JavaFX2.0 sind GUIs so schnell neu oder umgebaut und diese Arbeiten sind so non-invasiv, dass ein gewaltiges Investment in Optisches fehlgeleitet ist.

Layout

HBox und VBox sollten nicht sehr tief geschachtelt werden. Das kostet Performance. Wahrscheinlich hilft eine GridPane diese Verschachtelungen zu vermeiden. Verwende kein Binding damit ein GridPane sich der Grösse des Fensters anpasst.

Gradients

Farbübergänge lassen sich in JavaFX2 sehr einfach erzeugen. Es gibt zwei Klassen dafür: LinearGradient und RadialGradient mit dem jeweiligen Buildern dazu. Am Besten zu Enterprise GUIs passen üblicherweise dezente, lineare Farbübergänge im Graubereich (oben hell / unten etwas dunkler) auf Fensterebene. Mit einem dunkleren Farbübergang (oben dunkelgrau / unten schwarz) lässt sich ein Adobe Flash Effekt erzielen. Dies kann hilfreich sein, wenn man User dieser Plattform "abholen" will.

CSS

Einem GUI (egal ob browser-basiert oder window-basiert) liegt immer ein DOM-Baum zugrunde, der die Struktur dieses GUIs definiert. Will man nun einen Knotenpunkt (Node) innerhalb eines solchen DOMs finden, kann man entweder drüber iterieren (beginnend mit myScene.getRoot()) oder man sucht den Node direkt über seinen Namen:

 Node n = parentNode.lookup("...");

Dies setzt natürlich voraus, dass vorgängig mit myNode.setId("...") eine eindeutige Id vergeben wurde.

Diese Ids können dann in CSS-Files verwendet werden.

Hier ein paar Tricks, wie man einer Applikation einen einheitlichen, neuen Farbstil geben kann:

-fx-base:/* Basisfarbe für alle Komponenten */

-fx-text-base-color:/* Textfarbe */

-fx-accent: /* Standard Knöpfe ... */

-fx-focus-color: /*Farbe für die Anzeige des aktuellen Fokus */

-fx-mark: /* Farbe für Markierungen (CheckBoxen, Menüs, ...) */

Animationen

JavaFX2.0 ermöglicht es fast Alles irgendwie zu animieren. Aber man muss hier natürlich den Anwendungsfall im Auge behalten. Der Einsatz von Animationen in Spielen drängt sich ja meistens geradezu auf, aber in Business Applikationen ist davon abzuraten. Es mag die ersten paar Mal toll aussehen, aber schon nach kurzer Zeit nervt's den Benutzer. Es mag Fälle geben, in dem man den Benutzer mit einer Animation bspw. auf einen aktuell laufenden Prozess hinweisen möchte, aber im Zweifelsfall: Finger weg von Animationen!

Effekte

JavaFX bietet eine Vielzahl von Effekten. Hier gilt aber dasselbe, wie bei Animationen: nur mit besonders gutem Grund brauchen. Vielleicht eine Ausnahme sind Fade-Out und Fade-In. Sie können gut funktionieren, wenn sie dem Benutzer einen klaren Hinweis geben sollen (z.B."Ich brauche hier Input"). Aber dann sollten sie schnell sein (ca 250 ms) und konsistent verwendet werden.

Bei allen Aspekten rund um die Optik: eine kleine Bibliothek von vordefinierten Styles anlegen und diese dann entsprechend und konsequent verwenden. Das gibt ein einheitliches GUI. Unbedingt CSS einsetzen, damit die Optik später von einem CSS-Profi anpassbar ist. Niemand will im Java-Code die Optik pflegen.