JavaFX Label flackert beim aktualisieren

Der_AltMann

Aktives Mitglied
Ich habe eine Scrollpane, in der eine Vbox ist, in der mehrere Flowpanes sind, die mehrere Hboxen enthalten. In diesen Hboxen befindet sich dann immer 2 Labels.
Wenn ich das Fenster so klein habe, dass 5 Hoxen in einer Reihe sind ist alles gut, mache ich das Fenster jedoch größer fangen die Hboxen/Labels an zu flackern wenn sie ihren Wert aktualisieren.
1605794992267.png
Das weiße oben rechts ist das "flackern". Die ganze Hbox flackert, ich aktualisiere aber nur ein Element in der Box.

Das Label wird so aktualisiert(Labels habe ich in "map" gespeichert):
Java:
Platform.runLater(() -> {

                try {
                    if (map.containsKey(signal)) {
                        if (map.get(signal) instanceof Label) {
                            if (valueToDisplay == Double.MIN_VALUE) {
                                // if the value dont have decimal places it is better to display an integer
                                // instead of double
                                ((Labeled) map.get(signal)).setText(String.valueOf(value));
                                System.out.println("setValue: " + signal + " value: " + value);
                            } else {
                                ((Labeled) map.get(signal)).setText(String.valueOf(valueToDisplay));
                                System.out.println("setValue: " + signal + " value: " + valueToDisplay);
                            }

Die Labels werden von einem 2 Thread aktualisiert. Das komische ist, wenn ich das Fenster erst maximiere und dann den Thread starte gibt es keine Probleme.
Ich habe auch noch 3 Buttons, mit denen ich den Thread starte und stoppe. Wenn ich den Thread gestoppt hab (nicht maximiert gestartet) dann werden die Buttons auch so "weiß" wenn ich mit der Maus drüber fahre.
1605795353271.png
Vielleicht hat jemand sowas schonmal gesehen 🙂
 
UI Änderungen sollte man nicht in einem anderen Thread machen als dem UI Thread. Benutze einfach ein invokeLater bei den Änderungen
 
UI Änderungen sollte man nicht in einem anderen Thread machen als dem UI Thread. Benutze einfach ein invokeLater bei den Änderungen
Das scheint er ja zu beherzigen ... Was mir einfallen würde: hast Du für eine Änderung evtl. mehrere invokeLater?
Dann könnte es sein, dass er zwischen den einzelnen invokeLater die paint Messages hat und bearbeitet. Soweit ich mich erinnere haben die paint Nachrichten Vorrang, also wenn Du mehrere Events an eine Applikation gibst, dann werden alle WM_PAINT zuerst abgearbeitet.

Aber das ist schon zu lange her - da konnte man Windows Programme noch schön in C schreiben ohne schräg angesehen zu werden 🙂 Also vielleicht Verwechsel ich da jetzt auch was...
 
Das scheint er ja zu beherzigen ... Was mir einfallen würde: hast Du für eine Änderung evtl. mehrere invokeLater?
Dann könnte es sein, dass er zwischen den einzelnen invokeLater die paint Messages hat und bearbeitet. Soweit ich mich erinnere haben die paint Nachrichten Vorrang, also wenn Du mehrere Events an eine Applikation gibst, dann werden alle WM_PAINT zuerst abgearbeitet.

Aber das ist schon zu lange her - da konnte man Windows Programme noch schön in C schreiben ohne schräg angesehen zu werden 🙂 Also vielleicht Verwechsel ich da jetzt auch was...

Ist runLater das gleiche wie invokeLater? Ist bei mir auch schon paar Jahre her das ich Swing genutzt habe.
 
Ist runLater das gleiche wie invokeLater? Ist bei mir auch schon paar Jahre her das ich Swing genutzt habe.
Nein. Das eine ist JavaFX (Platform.runLater) und das andere ist Swing (SwingUtilities.invokeLater).

Aber prinzipiell machen Beide das gleiche: Es wird ein Event generiert, dass dann vom Event Dispatch Thread verarbeitet und ausgeführt wird. Dazu nehmen beide ein Runable als Parameter.
 
Das scheint er ja zu beherzigen ... Was mir einfallen würde: hast Du für eine Änderung evtl. mehrere invokeLater?
Dann könnte es sein, dass er zwischen den einzelnen invokeLater die paint Messages hat und bearbeitet. Soweit ich mich erinnere haben die paint Nachrichten Vorrang, also wenn Du mehrere Events an eine Applikation gibst, dann werden alle WM_PAINT zuerst abgearbeitet.

Aber das ist schon zu lange her - da konnte man Windows Programme noch schön in C schreiben ohne schräg angesehen zu werden 🙂 Also vielleicht Verwechsel ich da jetzt auch was...
Es ist nur eine invokeLater, diese wird aber sehr oft ausgeführt. Mit dem Programm überwache ich Lin Kommunikation und jedes Mal, wenn ein neuer Wert auf den Bus kommt aktualisiere ich die GUI mit diesem Wert(über die invokeLater). Das Komische ist halt wirklich, dass der Bug nicht auftritt, wenn ich das Fenster vorm starten der Kommunikation schon maximiere.
 
Nur so als Idee: kann es sein, dass du immer noch *zu viel* in deinem #runLater machst?
Ich würde dort wirklich *nur* die Labels setzen, nicht suchen, Text vorbereiten und dann rein machen. Du kannst auch von anderen Threads mit UI-Komponenten interagieren, solange du sie nicht manipulierst. Nur die Manipulation muss dann ins #runLater.

Aber wie gesagt ist das nur eine Idee. Ich hab keine konkrete Ahnung, warum es sich bei dir so verhält (vor allem wenn du eigentlich gerade weniger anzeigst).
 
Nur so als Idee: kann es sein, dass du immer noch *zu viel* in deinem #runLater machst?
Ich würde dort wirklich *nur* die Labels setzen, nicht suchen, Text vorbereiten und dann rein machen. Du kannst auch von anderen Threads mit UI-Komponenten interagieren, solange du sie nicht manipulierst. Nur die Manipulation muss dann ins #runLater.

Aber wie gesagt ist das nur eine Idee. Ich hab keine konkrete Ahnung, warum es sich bei dir so verhält (vor allem wenn du eigentlich gerade weniger anzeigst).
danke für den Tipp, tatsächlich habe ich das schon versucht aber es verhält sich genau gleich
 
Kannst du das in einem kleinen und selbständig lauffähigen Beispiel hier im Code zur Verfügung stellen? Dann könnte ich es auf Linux und Windows mal ausprobieren. Und vielleicht auch auf unterschiedlichen JavaFX-Version und Java-Installationen...
 
Kannst du das in einem kleinen und selbständig lauffähigen Beispiel hier im Code zur Verfügung stellen? Dann könnte ich es auf Linux und Windows mal ausprobieren. Und vielleicht auch auf unterschiedlichen JavaFX-Version und Java-Installationen...
Danke für die Hilfe, als ich ein selbständig lauffähigen Beispiel erstellen wollte, habe ich herausgefunden an welcher Zeile Code das Problem liegt.
Ich setze noch den Style von jedem Label, nachdem ich den Inhalt update:
Java:
map.get(signal).setStyle("-fx-font-weight: bold;");
genau daran liegt es. Ich habe auch schon versucht, es mit Platform.runlater zu machen aber das Resultat ist das selbe.
Wenn ich diese Zeile aus kommentiere funktioniert alles wunderbar.
Warum das Probleme macht weiß ich allerdings nicht
 
Ah... CSS und JavaFX. Ein Segen und ein Fluch zugleich. Den Style im Code zu setzen ist eh immer etwa heikel. in 99% der Fälle alles ok, aber das eine Prozent dann...
Am Besten steigst du auf normale, und wenn nötig auch Pseudo-, -Klassen um - mit denen habe ich eigentlich gute Erfahrungen gemacht.
 
Ah... CSS und JavaFX. Ein Segen und ein Fluch zugleich. Den Style im Code zu setzen ist eh immer etwa heikel. in 99% der Fälle alles ok, aber das eine Prozent dann...
Am Besten steigst du auf normale, und wenn nötig auch Pseudo-, -Klassen um - mit denen habe ich eigentlich gute Erfahrungen gemacht.
ah okay danke für die Info 🙂 meinst du mit Klassen dann CSS-Klassen, die ich über den Code setze?
 
Also idealerweise hängt man immer seine eigenen Style-Klassen ran (im Code oder im FXML). Und lässt sie dort!

Wenn man dann etwas aufgrund einer speziellen Situation ändern möchte, kann man dann noch Style-Klassen im CSS definieren und sie im Code (und soweit ich weiss nur dort) aktivieren oder deaktivieren.
 

Zurück
Oben