codecentric AG Wesentliche Anforderungen an den Desktop Client − Anzeige von Suchergebnissen ! − Upload per Drag&Drop und über Transfer-Ordner ! − Schneller Wechsel zwischen mehreren Logins ! − Offline-Verfügbarkeit von ausgewählten Sammlungen und Dokumenten ! − Lokales Öffnen und Bearbeiten von Dokumenten − Erkennen von Änderungen/Kollisionen und Upload als neue Version ! − Tray-Integration
codecentric AG Warum JavaFX ? − Verschiedene Zielplattformen: Mac OS, Windows, Linux ! − Java-Kompetenz im Team stark vorhanden ! − Hohe Flexibilität durch Nutzung von FXML, CSS und Java ! − JavaFX hinreichend stabil − Erster Prototyp mit JavaFX 2.2, später dann Wechsel auf JavaFX 8
codecentric AG Eingesetzte Frameworks/Bibliotheken − Derby − Eingebettete relationale Datenbank − Zugriff durch eigene Klasse ähnlich zu Spring JDBCTemplate − Connection Pooling mit Apache commons-pool ! − REST − Eigene Bibliothek basierend auf Jersey − Inklusive OAuth-Client
codecentric AG Änderungen an FXMLView (afterburner.fx) − Verwende den Guice Injector ! − Berücksichtige Locale des Nutzers beim Laden von ResourceBundles ! − Speichere Referenzen auf alle Presenter-Instanzen − Für späteren Cleanup ! − Erlaube Angabe zusätzlicher Guice-Module bei Konstruktion − Ermöglicht verschiedene Presenter für Instanzen der gleichen View-Klasse
codecentric AG Empfehlungen − Möglichkeiten in FXML, CSS und Java kennen ! − Regeln für Größenberechnung verstehen − minimum/preferred/maximum/computed size − „grow“ bei Boxes ! − Verstehen wie und wann die Anzeige aktualisiert wird − Pulse
codecentric AG Empfehlungen − Lebenszyklus von JavaFX Controllern (Initializable) kennen − Bei WeakReferences: Gefahr, dass Controller plötzlich weg ist − StackPane eignet sich gut zum Verwalten austauschbarer Nodes − Aber: Vorsicht vor Klicks/Events beim falschen Empfänger − Bei Transparenz: setPickOnBounds(false) ! − Preloader − Bei nichttrivialem Startup Pflicht − Aber: Ausblenden bei Autostart
codecentric AG Gotchas − WebView/WebEngine − Keine Möglichkeit beliebige HTTP-Header zu setzen (z.B. Accept-Language) − „Do not follow redirects“ gibt es nicht ! − ListView − Event-Flut (Selected/Focus) bei einfachen Aktionen − Manchmal keine Aktualisierung bei Änderungen (JavaFX 2.2) ! − Kein Support für System Tray − Verwendung von AWT, darin ggf. wieder JavaFX − Erheblicher Aufwand
codecentric AG Gotchas − Unter bestimmten Umständen unerwartet hohe CPU-Last − z.B. Rotating Icon (zählt in einer Endlos-Schleife) ! − Wenig Einstiegs-/Erweiterungspunkte im Framework − Viel Zugriff auf restricted API (com.sun.javafx) beim Bau von Custom Controls − Customizing der OS X Menüleiste erfordert Reflection − Hacks nötig um eigenen Font mit auszuliefern (JavaFX 2.2)
codecentric AG FXML vs. Java-Code − Empfehlung − FXML: Definition der Struktur einer View − FXML: Layout „einfacher“ Nodes wie Listen, Labels, Buttons − CSS: Alles was an Styling möglich ist − Java: Komposition von Views im Presenter-Code ! − Dynamische Daten (z.B. eine Zeile in einer Liste von Suchergebnissen) − FXML als Template − Customizing ggf. im Java-Code − z.B. Skalieren/Einpassen von Bildern
codecentric AG Allgemeine Empfehlungen − Keine blockierenden Backend-Aufrufe aus dem UI − Verwende JavaFX-Tasks und Callbacks − Falls doch blockierend, dann mit sehr kleinem Timeout ! − Keine Ereignisse ins Leere laufen lassen − EventBus: Dead Messages beachten − Thread Factories mit UncaughtExceptionHandlers für Worker-Pools ! − Resilience im Client − Rate Limiting auf der API ? − Server kann jederzeit „weg“ sein − Achte auf „Edge Cases“ wie serverseitige Löschung von Daten
codecentric AG Allgemeine Gotchas − Einheitliche Java-API, aber unterschiedliches Verhalten des Dateisystems − Änderungen nicht erkannt (WatchService) − Datei lesbar während sie zum Schreiben geöffnet ist ? − Dateigröße 0 im laufenden Kopiervorgang ! − Proxies ! − Upload versteckter Dateien ! − Betriebssystem geht schlafen -> Netzwerkverbindung getrennt ? ! − Mac OS: Starten der Anwendung aus dem Disk Image heraus
codecentric AG Internationalisierung − Anforderung − Initiale Sprache basierend auf OS-Einstellungen − Sprachauswahl in der Anwendung ! − Initialisierung − Verwende Default-Mechanismus via FXML ! ! − Aktualisierung − Handling im Java-Code bedeutet doppelte Arbeit − Und kann leicht vergessen werden − Deshalb: Neuinitialisierung des UI wie beim Mandantenwechsel
codecentric AG Datensynchronisation − Regelmäßiger Abgleich relevanter Daten mit dem Server − Abgleich der Daten selbst ist aufwändig − Event-Timeline/-Cursor steigert Performance erheblich − Ideal: Push-Notifications ! − Stabilität − Dateien können lokal geöffnet oder geändert worden sein − Eine Datei pro Version, die Datenbank kennt die aktuelle Version − Asynchrones Aufräumen im Hintergrund ! − Abbildung von Sammlungen/Tags auf Ordner schwierig − Deshalb Ablage in einem „versteckten“ Speicher
codecentric AG Anzeige großer Datenmengen − Asynchron Daten laden: JavaFX-Task, Worker, Callback, FXCollection ! − Bei automatischem Refresh nur Änderungen einpflegen − Hashcode kann helfen ! − Endlos-Scrolling oder Paginierung ? − Endlos-Scrolling: Probleme mit Lücken, Duplikaten und Refresh − Paginierung viel stabiler ! − Gescheitertes Experiment: Mehr synchronisieren als nötig − Idee: Auch im Online-Modus möglichst gegen die lokale Datenbank − Aber: Hoher Synchronisationsaufwand, falls kein Push − Und: Manche Features nur auf dem Server (z.B. Volltextsuche)
codecentric AG Offline-Modus − Puffern von Uploads und Downloads − Speichern von Aufträgen in die Datenbank − Ausführung asynchron, Events bei Abschluss von Tasks ! − Anzeigen/Öffnen offline verfügbarer Dokumente − Backend-Zugriffe hinter Facade verstecken ! − Wie erkennen ob online oder offline? − Irgendein Netzwerkcall schlägt auf bestimmte Weise fehl -> offline − Ein relevanter (!) Server ist verfügbar -> online ! − Nicht vergessen: Pausieren/Starten relevanter Services − Globaler Event bei Status-Änderung
codecentric AG Packaging und Installation − JavaFX Packaging für uns nicht zufriedenstellend ! − Mehr Flexibilität mit eigenem Installer − JAR mit Libs, JRE, Starter-Skript − Installer bzw. Disk Image − Erstellung automatisiert auf Build-Server ! − Vorteile: Partielle Updates, Entkopplung vom System JRE ! − Nachteil: Schwierigkeiten bei einfachen Dingen (z.B. Mac OS Menü)
codecentric AG Automatische Updates − Komplett innerhalb der Anwendung − Aktualisiere Anwendung, JRE oder beides (nach Bedarf) − Anwendung prüft auf Updates und lädt diese ggf. herunter − Starter-Skript führt Update-Skript aus, falls vorhanden ! − Nachteile − Starter-Skript nicht unmittelbar änderbar − Ggf. korrupte Updates durch Firewall
codecentric AG Fazit − Wir würden wahrscheinlich wieder auf JavaFX setzen − Das meiste geht ziemlich leicht − Manche Kleinigkeiten kosten viel Zeit − Entscheidung sollte auch vom Know-how im Team abhängen ! − Empfehlungen − Evaluationsphase − Überblick über JavaFX-Frameworks verschaffen − Frühzeitig Packaging/Deployment implementieren