# Swing oder JavaFX



## javanese2018 (23. Aug 2018)

Hallo zusammen,

zurzeit plane ich ein größeres Desktop-Programm. Es soll sehr GUI-lastig sein und ich beabsichtige auch das Look-and-Feel der Komponenten zu verändern. Nun frage ich mich, ob ich dieses mit Swing oder mit JavaFX erstellen soll. 

Danke im Voraus.


----------



## MoxxiManagarm (23. Aug 2018)

JavaFX


----------



## RalleYTN (24. Aug 2018)

Soweit ich weiß ist JavaFX nicht Teil aller JVMs. (korrigiert mich wenn ich falsch liege)
Deswegen blockiert dir Eclipse standradmäßig den Zugriff.
Wenn du also Nichts für spezielle JVMs auf speziellen Geräten programmierst ist JavaFX sicher.
JavaFX hat auch den Vorteil das selbst erstellte LaFs einfacher umgesetzt werden können, da man mit CSS arbeiten kann.
Gibt nur leider zu wenig Tutorials die einem erklären wie der Code funktioniert und stattdessen dich zu irgendeinem doofen Scene Builder weiterleiten.


----------



## mrBrown (24. Aug 2018)

RalleYTN hat gesagt.:


> Gibt nur leider zu wenig Tutorials die einem erklären wie der Code funktioniert und stattdessen dich zu irgendeinem doofen Scene Builder weiterleiten.


doofer SceneBuilder? Der (bzw. FXML) ist deutlich sinnvoller als die ganze GUI in Code aufzubauen und ( zumindest für mich) einer der großen Pluspunkte für JavaFX


----------



## RalleYTN (24. Aug 2018)

mrBrown hat gesagt.:


> doofer SceneBuilder? Der (bzw. FXML) ist deutlich sinnvoller als die ganze GUI in Code aufzubauen und ( zumindest für mich) einer der großen Pluspunkte für JavaFX


Ich habe ganz einfach ein Problem mit automatisch generierten Code den ich nicht verstehe und daher nicht vernünftig warten kann. FXML ist jedoch voll in Ordnung... wenn selbst geschrieben.


----------



## mrBrown (24. Aug 2018)

RalleYTN hat gesagt.:


> Ich habe ganz einfach ein Problem mit automatisch generierten Code den ich nicht verstehe und daher nicht vernünftig warten kann. FXML ist jedoch voll in Ordnung... wenn selbst geschrieben.


Der SceneBuilder produziert auch nur FXML, unverständlichen oder unwartbaren Code gibts da nicht (anders als bei den Swing-GUI-Buildern).
SceneBuilder und händisch geschrieben macht selten einen Unterschied und lässt sich auch ziemlich gut mischen


----------



## javanese2018 (24. Aug 2018)

@MoxxiManagarm , @RalleYTN, @mrBrown Vielen Dank für eure Antworten. Ich habe mich nun entschieden das Programm mit JavaFX zu erstellen.


----------



## thecain (24. Aug 2018)

Ich mag TornadoFX für die Guis mit JavaFX


----------



## looparda (24. Aug 2018)

Unabhängig von look and feel Anpassung möchte ich mvvmFx erwähnen, da du offensichlich in JavaFX einsteigen willst. Ich finde es schade, dass ich es nicht von Anfang kannte, da es sehr hilfreich ist zur Strukturierung des Codes.


----------



## temi (24. Aug 2018)

thecain hat gesagt.:


> Ich mag TornadoFX für die Guis mit JavaFX


Das ist ja Kotlin, lässt sich das mit Java in einer Anwendung gemischt verwenden?
GUI = Kotlin - Rest = Java


----------



## thecain (25. Aug 2018)

temi hat gesagt.:


> Das ist ja Kotlin, lässt sich das mit Java in einer Anwendung gemischt verwenden?
> GUI = Kotlin - Rest = Java


genau, oder alles kotlin, wenn man will.


----------



## mihe7 (26. Aug 2018)

Zu JavaFX habe ich ein zwiespältiges Verhältnis. 

Als es erschien, präsentierte es sich mir als UI-Framework, das auf zwei Dinge ausgerichtet war: RIA und vor allem: UI-Effekte, insbesondere Animationen. Es sah besser aus als Swing (was jetzt nicht wirklich eine Kunst ist ), war jedoch fürchterlich lahm, so dass ich es nicht wirklich ernsthaft weiter verfolgt habe. 

Nun ist es so, dass mir JavaFX irgendwie aber auch gefällt. Später habe ich dann einen Versuch gestartet, eine Anwendung zu portieren, habe dann jedoch entnervt aufgeben müssen.

Heute macht es auf mich den Eindruck, als folge das Toolkit dem "friss oder stirb"-Ansatz: einfach, so lange man mit dem auskommt, was geboten wird, beinahe unmöglich, sobald man auch nur ein Quäntchen davon abweichen will. 

Wenn ich mir z. B. den Thread Alternativtext ansehe, dann muss ich mich schon fragen, ob es sein kann, dass so eine einfache Aufgabe zu einem größeren Problem wird. 

Selbst zur Berechnung der Breite eines Strings findet man auf Stackoverflow nur irgendwelche Hacks (z. B. https://stackoverflow.com/questions/46641114/an-alternative-to-fontloader-computestringwidth).

Ein anderes Beispiel: Listen/Tabellen. In Swing war es ausreichend, ein simples Interface (ListModel, TableModel) zu implementieren. Ressourcenschonend, schnell, super Sache. JavaFX arbeitet mit ObservableLists. Was soll das?


----------



## mrBrown (27. Aug 2018)

mihe7 hat gesagt.:


> Wenn ich mir z. B. den Thread Alternativtext ansehe, dann muss ich mich schon fragen, ob es sein kann, dass so eine einfache Aufgabe zu einem größeren Problem wird.


Das hat mich allerdings auch überrascht. Fehlte bisher wohl einfach der Bedarf zu, das "Abschneiden" des Textes lässt sich ja schon konfigurieren...



mihe7 hat gesagt.:


> Selbst zur Berechnung der Breite eines Strings findet man auf Stackoverflow nur irgendwelche Hacks (z. B. https://stackoverflow.com/questions/46641114/an-alternative-to-fontloader-computestringwidth).


Das Problem dabei dürfte sein, dass die Länge erst nach dem Rendern fest steht. Mir persönlich würde auch kein anderer Weg einfallen, das zu berechnen. 



mihe7 hat gesagt.:


> Ein anderes Beispiel: Listen/Tabellen. In Swing war es ausreichend, ein simples Interface (ListModel, TableModel) zu implementieren. Ressourcenschonend, schnell, super Sache. JavaFX arbeitet mit ObservableLists. Was soll das?



Ist es nicht noch deutlich simpler, Elemente in eine Liste zu legen, anstatt ein Interface implementieren zu müssen?  
Ich fand Tabellen in Swing immer einen ziemlichen Krampf, und Tabellen in JavaFX dagegen als ziemlichen Segen...


----------



## mihe7 (27. Aug 2018)

mrBrown hat gesagt.:


> Das Problem dabei dürfte sein, dass die Länge erst nach dem Rendern fest steht. Mir persönlich würde auch kein anderer Weg einfallen, das zu berechnen.


Die Metrics stehen in der Font. Natürlich müssen gewisse Informationen über das Ausgabemedium vorhanden sein, aber rendern in dem Sinne muss man den Text vorab nicht. Es geht ja nicht nur um die Breite: ich brauche z. B. Grundlinie, Unterlängen etc. Da hilft mir das Rendern gar nix, wenn ich am Ende nur weiß: aha, Rechteck mit der Breite und der Höhe.



mrBrown hat gesagt.:


> Ist es nicht noch deutlich simpler, Elemente in eine Liste zu legen, anstatt ein Interface implementieren zu müssen?


Das eine schließt das andere nicht aus. 

In Swing ist das TableModel ein Interface, das genau darauf zugeschnitten ist, was eine Tabelle braucht (interface segregation). Will ich eine "ObservableList" an eine Tabelle binden, ist das über einen Adapter kein Problem. 

Will ich einer JavaFX-Tabelle ein eigenes Modell geben, muss ich eine schwergewichtige ObservableList-Implementierung zur Verfügung stellen: 90 % der Methoden werden von einer Tabelle nicht benötigt, um zu funktionieren.


----------



## mrBrown (27. Aug 2018)

mihe7 hat gesagt.:


> Die Metrics stehen in der Font. Natürlich müssen gewisse Informationen über das Ausgabemedium vorhanden sein, aber rendern in dem Sinne muss man den Text vorab nicht. Es geht ja nicht nur um die Breite: ich brauche z. B. Grundlinie, Unterlängen etc. Da hilft mir das Rendern gar nix, wenn ich am Ende nur weiß: aha, Rechteck mit der Breite und der Höhe.


Zumindest in Teilen ergeben sich die zur Berechnung nötigen Informationen erst aus der Position des Textes innerhalb der Szene, vorher sind CSS etc doch nicht endgültig bekannt?
Die anderen Dinge bekommt man damit nicht, bisher kam zumindest ich aber auch ohne aus. Rein aus Interesse: wofür braucht man die in 'nem JavaFX-Kontext?



mihe7 hat gesagt.:


> Das eine schließt das andere nicht aus.
> 
> In Swing ist das TableModel ein Interface, das genau darauf zugeschnitten ist, was eine Tabelle braucht (interface segregation). Will ich eine "ObservableList" an eine Tabelle binden, ist das über einen Adapter kein Problem.
> 
> Will ich einer JavaFX-Tabelle ein eigenes Modell geben, muss ich eine schwergewichtige ObservableList-Implementierung zur Verfügung stellen: 90 % der Methoden werden von einer Tabelle nicht benötigt, um zu funktionieren.


Die 90% sind halt normale Listen-Methoden, nicht zwingend notwendig, aber oft ziemlich praktisch.

Einer JavaFX-Tabelle ein eigenes Modell geben ist nicht mehr als ein `table.getItems().addAll(
irgendeineListe)` oder `table.getItems().addAll(
element1, element2, element3)`. Ne eigene Implementierung von irgendwas muss man da nicht zur Verfügung stellen, wenn man nicht will, muss man nicht mal direkt mit ObservableList arbeiten. Wenn man doch will, gibts genug Implementierungen und Adapter von JavaFX zur Verfügung.


----------



## mihe7 (27. Aug 2018)

mrBrown hat gesagt.:


> Zumindest in Teilen ergeben sich die zur Berechnung nötigen Informationen erst aus der Position des Textes innerhalb der Szene, vorher sind CSS etc doch nicht endgültig bekannt?


Es geht ja z. B. darum, die Position zu bestimmen. Beispiel: Beim Layout wird mitgeteilt, welche Breite zur Verfügung steht. Passt der Text rein? Wie viel passt rein? Wo kann ich umbrechen? 



mrBrown hat gesagt.:


> Die anderen Dinge bekommt man damit nicht, bisher kam zumindest ich aber auch ohne aus. Rein aus Interesse: wofür braucht man die in 'nem JavaFX-Kontext?


Beispielsweise zum optischen vertikalen Ausmitteln. Man kann nicht einfach drei Zeilen (ggf. mit unterschiedlichen Schriftarten und -größen) übereinander und den Block dann mittig setzen. Dazu kommen noch andere Dinge wie Zeilen- und Zeichenabstand usw. Das Schriften-Zeug ist ziemlich komplex und auch unter Java2D nicht unproblematisch, wie ich vor ein paar Jahren in Zusammenarbeit mit einem Schriftsetzer schmerzlich erfahren musste, weil die diversen Java Implementierungen unterschiedliche Font Engines verwenden, die teilweise unterschiedliche Ergebnisse liefern.



mrBrown hat gesagt.:


> Die 90% sind halt normale Listen-Methoden, nicht zwingend notwendig, aber oft ziemlich praktisch.


Das bestreitet auch niemand. Die Frage ist: warum nimmt man mir die Möglichkeit, ein simples Interface zu implementieren? 



mrBrown hat gesagt.:


> Ne eigene Implementierung von irgendwas muss man da nicht zur Verfügung stellen, wenn man nicht will, muss man nicht mal direkt mit ObservableList arbeiten. Wenn man doch will, gibts genug Implementierungen und Adapter von JavaFX zur Verfügung.



Hier wird ganz klar das ISP verletzt und die Frage ist: warum? Das UI-Model soll oftmals nur ein Adapter sein, der zwischen den UI-Komponenten und dem Application Layer liegt. 

Nehmen wir mal ListModel, das sind vier einfache Methoden, wovon zwei für die Listener gedacht sind. Wenn man AbstractListModel verwenden kann, dann sind gerade mal zwei Methoden zu implementieren: getSize() und getElementAt(int). Ich weiß genau, was die Liste braucht und ich muss auch nicht mehr zur Verfügung stellen. 

Warum kommt ListView, um beim Beispiel zu bleiben, nicht mit einem einfachen Interface mit vier Methoden aus, das z. B. von ObservableList implementiert wird?


----------



## mrBrown (27. Aug 2018)

mihe7 hat gesagt.:


> Die Frage ist: warum nimmt man mir die Möglichkeit, ein simples Interface zu implementieren?


warum zwingt man mich, ein spezielles Interface zu implementieren, wenn ich doch nur eine Liste anzeigen will 



mihe7 hat gesagt.:


> Hier wird ganz klar das ISP verletzt und die Frage ist: warum? Das UI-Model soll oftmals nur ein Adapter sein, der zwischen den UI-Komponenten und dem Application Layer liegt.
> 
> Nehmen wir mal ListModel, das sind vier einfache Methoden, wovon zwei für die Listener gedacht sind. Wenn man AbstractListModel verwenden kann, dann sind gerade mal zwei Methoden zu implementieren: getSize() und getElementAt(int). Ich weiß genau, was die Liste braucht und ich muss auch nicht mehr zur Verfügung stellen.
> 
> Warum kommt ListView, um beim Beispiel zu bleiben, nicht mit einem einfachen Interface mit vier Methoden aus, das z. B. von ObservableList implementiert wird?


Weil es so wesentlich einfacher zu nutzen ist? Man ist halt weg von einem speziellen Interface hin zu einem abstraktem Datentyp.

Dein Beispiel mit AbstractListModel: du musst AbstractListModel und zwei Methoden implementieren. Das der Tabelle geben und dem Model noch deine Daten geben.
JavaFX: du musst nichts implementieren. Einfach nur, ohne irgendwas anderes machen zu müssen, deine POJOs (die in einer ganz normalen List liegen können) der ListView/TableView übergeben.  

Andersrum könnte man fragen, warum muss man bei Swing ein spezielles Interface implementieren, wenn es ein einfacher ADT tut?
Sollte man dann auch jedes List<?> durch ein geeigneteres Interface ersetzen?


----------



## mihe7 (27. Aug 2018)

mrBrown hat gesagt.:


> Weil es so wesentlich einfacher zu nutzen ist?


An der Benutzung ändert sich so gut wie nichts, wenn ich geeignete Implementierungen zur Verfügung gestellt bekomme.

Wenn ich wollen würde, könnte ich DefaultListModel (würg) verwenden, da habe ich einen ähnlichen Effekt:

```
DefaultListModel<Person> model = new DefaultListModel();
list.setModel(model);
model.addElement(p1);
model.addElement(p2);
```

Ist jetzt auch nicht so viel anders als

```
ObservableList<Peson> model = ...;
list.setItems(model);
model.add(p1);
model.add(p2);
```



mrBrown hat gesagt.:


> du musst AbstractListModel und zwei Methoden implementieren.


Das liegt aber vor allem daran, dass Standardbibliothek keine geeignete Implementierung anbietet.



mrBrown hat gesagt.:


> JavaFX: du musst nichts implementieren.


Das liegt aber nur daran, dass die Bibliothek eine geeignete Implementierung anbietet  


mrBrown hat gesagt.:


> Andersrum könnte man fragen, warum muss man bei Swing ein spezielles Interface implementieren, wenn es ein einfacher ADT tut?



Swing zu kritisieren ist auch völlig richtig. 

Warum hat man das Interface nicht kompatibel zur Collections-API gemacht (z. B. ListModel#get und ListModel#size)? Warum stellt Swing nicht entsprechende Erweiterungen und Implementierungen (ObservableList<E> extends List<E>, ListModel<E> und Implementierungen dazu) bereit?

Ebenso muss ich aber fragen, warum kommen JavaFX-Komponenten nicht mit einem schlanken Interface aus, das ich auch mal eben selbst implementieren kann?

Habe mal eben gesucht, wie die Leute es in JavaFX machen, Daten aus einer DB-Tabelle anzuzeigen. Lösung: füge die Sätze zu einer ObservableList hinzu. WTF?!?


----------



## temi (27. Aug 2018)

Wie seht ihr eigentlich die Zukunft von JavaFX, wenn es jetzt als OpenFX weitergeführt wird?


----------



## mihe7 (27. Aug 2018)

temi hat gesagt.:


> Wie seht ihr eigentlich die Zukunft von JavaFX, wenn es jetzt als OpenFX weitergeführt wird?



Die einen sagen so, die anderen so. Da Oracle JavaFX nicht mehr mit dem JDK ausliefert, ist es in meinen Augen zum aktuellen Zeitpunkt ein Framework unter "vielen", das mit 30 - 50 MB auch nicht gerade leichtgewichtig ist. Die Trennung kann sich positiv auf den Fortschritt auswirken, das ist natürlich von der Community abhängig. Ob JavaFX jemals den Schritt in den Standard machen wird, steht in den Sternen. Momentan würde ich eher vermuten, dass man Java auf dem Desktop irgendwann ganz entfernt.


----------



## Javinner (27. Aug 2018)

mihe7 hat gesagt.:


> Momentan würde ich eher vermuten, dass man Java auf dem Desktop irgendwann ganz entfernt


Hoffentlich passiert es nie, das wäre für mich die Katastrophe schlecht hin! Habe mir paar andere Sprachen angeschaut und finde Java für mich am besten nachvollziehbar. Wenn man googelt, dann stellt man fest, dass man Java bereits nach der Jahrtausend Wende ein Aus vorhergesagt hat, aber Java gibt es immer noch und so wie es aussieht, wird an der Sprache weiter gearbeitet. Für Android ist nun Kotlin verfügbar und wenn Google ganz auf Java verzichtet, dann schaue ich aber dumm aus der Wäsche..


----------



## mihe7 (27. Aug 2018)

Javinner hat gesagt.:


> Hoffentlich passiert es nie, das wäre für mich die Katastrophe schlecht hin!


Keine Angst, es ging "nur" um den Standard und die nächsten paar Jahre passiert das eh nicht.


----------

