2015-06-28

Schöne neue Welt

Kann sich noch jemand an den JSR 296 erinnern? Er spezifiziert ein Swing Application Framework, das die reichlich vorhandenen Bausteine von Swing insbesondere für den unerfahrenen Entwickler sinnvoll zusammenfasst. Leider wurde der Java Specification Request nie in eine Java-Version übernommen. Gut, mittlerweile ist Swing ebenfalls obsolet. Jedenfalls war ein recht nützliches Feature das sich Kümmern um Fensterzustände. Wird die Anwendung beendet, speichert das Framework Größe und Position in einer .properties-Datei. Warum man in der Referenzimplementierung seinerzeit nicht die Preferences API genutzt hat, verstehe ich übrigens bis heute nicht. Anyway. Die spannende Frage ist nun: wie sieht das unter JavaFX aus? Unterstützt der Swing-Nachfolger den Entwickler mit fertigen Hilfsklassen? Die nicht überraschende Antwort ist: im Prinzip ja. Eigentlich ist alles vorhanden. Wie schon bei Swing muss man sich den entsprechenden Code aber selbst zusammenhacken.

Man findet im Netz einige Posts zu dem Thema. Meistens wird vorgeschlagen, mit stage.setOnCloseRequest() einen EventHandler zu setzen, der Position und Größe der main stage ausliest und mit der Preference API persistiert. Beim (erneuten) Start der Anwendung werden die gespeicherten Werte ausgelesen und vor dem Aufruf von stage.show() gesetzt. Soweit, so gut. Was ich bislang nirgendwo gelesen habe: man sollte zusätzlich abspeichern, ob das Fenster beim Beenden maximiert war, und diesen Zustand beim Start wiederherstellen. Andernfalls erscheint das Fenster nämlich nur “irgendwie groß”, weil zwar Breite und Höhe auf volle Größe gesetzt werden, aber das korrespondierende Widget nicht den richtigen Zustand hat. Noch ein Caveat: ist das Fenster maximiert, dürfen Position und Größe nicht übernommen werden, damit beim erneuten Anklicken die ursprüngliche Größe wiederhergestellt werden kann. Also:

  • beim Beenden immer abspeichern, ob das Fenster maximiert ist (stage.isMaximized())
  • nur wenn das Fenster nicht maximiert ist, Position und Größe sichern

Beim Start der Anwendung…

  • immer setMaximized() mit dem gespeicherten Wert setzen; Standardwert ist false
  • Position und Größe auslesen und, sofern vorhanden, setzen

Es gibt einen Sonderfall, den meine Lösung nicht berücksichtigt. Verschiebt man ein nicht maximiertes Fenster oder ändert seine Größe, maximiert es danach, und beendet dann die Anwendung, so erscheint das Fenster nicht an der erwarteten Position und in der erhofften Größe, wenn man nach einem Neustart die Maximierung aufhebt. Deshalb bietet es sich an, auch Positions- und Größenänderungen des Fensters zu überwachen, und die Werte im nicht maximierten Zustand zu sichern.

Ein Tipp zum Schluss: Stages können noch einige weitere Zustände haben, die man unter Umständen persistieren und wiederherstellen möchte…

No comments:

Post a Comment