JavaFX Automatisches Neuzeichnen ("Repaint") abstellen.

Javohl!

Mitglied
Hallo Leute!

Ich schreibe ein Programm, in dem ich bestimmte Daten auslese und live auf einem javafx.scene.chart.XYChart als einen javafx.scene.chart.LineChart darstelle. Dabei werden mehrere linecharts gleichzeitig dargestellt und in periodischen abständen aktuallisiert.

Das Problem an der Sache ist, dass wenn ich zu einem der vielen Linecharts (this.chart im Quellcode unten) einen neuen Wert hinzufüge:

Code:
        void update_chart(){
            this.chart.getData().add(
                new XYChart.Data(
                        <x-wert> ,
                        <y-wert>
            ));
        }

...

for( int i = 0; ... ) {
    <chartobjekt mit index i>.update_chart();
}

der gesamte XYChart aktuallisiert (neu gezeichnet) wird, was völlig sinnlos ist, da er für den nächsten chart sowieso ein weiteres mal gezeichnet werden muss.

Mein Ziel ist es also, pro Datenauslese-Zeitperiode den oberen code für alle chart-objekte ausführen und alle diese graphen (linecharts) erst nach dem letzten aktualisierten linecharts neu zeichnen zu lassen.

Kann man also diese Autozeichen-Funktion irgendwie abstellen und per Funktionsaufruf nur manuell neu zeichnen lassen? Ich werde in der doku nicht fündig.
 
Zuletzt bearbeitet:

dzim

Top Contributor
Ich hab etwas ähnliches gemacht: Live-Daten einer Performance-Messung (Speed-Test) werden in ein LineChart mit zwei Serien eingetragen.
Dabei hat mich eher die Tatsache gestört, dass die Labels (die Geschwindigkeiten) live generiert und damit die Breite des Charts beeinflusst werden.

Wie auch immer. Hier mein Ansatz:
Java:
// initialize-Methode
ObservableList<XYChart.Series<Number, Number>> lineChartData = FXCollections.observableArrayList();

this.seriesDownload = new LineChart.Series<Number, Number>();
this.seriesUpload = new LineChart.Series<Number, Number>();

lineChartData.add(seriesDownload);
lineChartData.add(seriesUpload);

lineChart.setData(lineChartData);
lineChart.setCreateSymbols(true);

// [...]

// da ich die Daten von einem anderen Thread bekomme, gibt es diese Hilfmethode:
		private void add(final int index, final LineChart.Series<Number, Number> series, final XYChart.Data<Number, Number> data) {
			// -- ignorier das hier erst mal -- data.setNode(new HoveredThresholdNode(index, data.getYValue().longValue()));
			PlatformHelper.run(new Runnable() {
				@Override
				public void run() {
					series.getData().add(data);
				}
			});
		}

// diese wird nun mit Daten befüllt, in dem ich sie in meinem eigenen EventHandler,
// der die Speed-Updates erhält, so hier aufrufe:
add(1, lineChart.getData().get(1), new XYChart.Data<Number, Number>(ts, v));
// statt "lineChart.getData().get(1)" hätte hier auch "seriesUpload" stehen können

Ich kann dabei kein extremes oder störendes Flackern feststellen.
 

Javohl!

Mitglied
Hallo dzim,

danke für die Antwort. Ehrlich gesagt, verstehe ich nicht so richtig was der code macht, da ich weder das Nodes-Konzept noch das Zeug mit eventhandlers vernünftig verstanden habe, außer dass es mit Verzweigungen/Hierarchie der GUI-Elemente und Events irgendwas zu tun hat (Buttonclicks in meinem Fall). Ich hab leider auch keine Zeit, mich in die JavaFX-GUI-philisophie vernünftig reinzudenken, da der Schwerpunkt meiner Arbeit eher auf der Datenauswertung liegt, die Anzeige ist nur als "Monitor" gedacht.

Kann ich das Problemm nicht auf irgend eine einfache Weise lösen?

Ich stell mir das am einfachsten so vor, dass ich dem Chart Daten hinzufüge, ohne dass der Chart neu gemalt wird.
Nachdem alle daten hinzugefügt sind, will ich eine Funktion aufrufen, die dem Graph sagt, der soll das ganze Zeug jetzt malen.
Es geht also darum, redundante Neuzeichnungen zu vermeiden.
Optische Probleme hatte ich mit dem Chart bisher nicht.

Wenn du irgend eine Idee in der Art hast, wäre ich dir sehr dankbar.

Vielen Dank für dein Verständniss.

Gruß, Javohl!
 
Zuletzt bearbeitet:

dzim

Top Contributor
Die Philosophie kann ich dir auch nicht sagen. Der Aufbau ist bei den meisten recht logisch: Fenster -> Layout -> Widget (wobei ein "widget hier auch wieder Layout -> Widget heissen kann - also ein Baum aus Layouts, auf dem als Blätter bestimmte Widgets liegen).

Bei JavaFX ist Node meist etwas abstraktes von Pane (Panel mit weiteren Widgtets drauf, also eher wieder ein Layout) bis konkrete Widgets wie eben einen GraphView.

Die Frage ist: Willst du einen Live-Graphen? Dann wirst du es so machen müssen, wie dein Code (nur um das Flacker-Problem bereinigt).

Wenn nein: Dann sammle erst mal alle Daten und werfe sie hinterher in einem Rutsch auf den Graphen und zeige solange einen ProgressIndicator (so ein drehendes Ding) oder so an, bis deine Operation fertig ist.
So oder so, ist der Einstieg in JavaFX (und auch andere UI-Frameworks) meist etwas mit umdenken verbunden, aber am Ende keine Hexerei.

Im Code bei dir ist - wie gesagt - die "update_chart"-Methode problematisch (übrigens: Nutze in Java camelCase für Methoden, also "updateChart" als Methodenname).

Heruntergebrochen lässt sich mein Code so formulieren: Lege am Anfang bereits deine Serien an, die dargestellt werden sollen und füge später deine Daten nicht einfach dem Graphen hinzu (wie du es machst), sondern der entsprechenden Serie.
 

kaoZ

Top Contributor
Was hindert dich daran ähnlich dem doublebuffering , deine Graphen oder Grafiken erst auf ein Image zu zeichnen und bei bedarf eben dieses Image auf dein Pane oder ähnliches zu bringen, wie und wie oft kannst du doch vollkommen selbst festlegen , z.B bei einem auslösen eines Events ?

Ich kenn mich mit JavaFX nu nicht wirklich aus, aber das Prinzip dahinter sollte ja umsetzbar sein .

So wärst du zumindest unabhängig vom repainten , da du selbst dafür sorgen könntest insofern der chart halt eben nicht "live" sein soll.
 
Zuletzt bearbeitet:

Javohl!

Mitglied
Die Frage ist: Willst du einen Live-Graphen? Dann wirst du es so machen müssen, wie dein Code (nur um das Flacker-Problem bereinigt).

Wenn nein: Dann sammle erst mal alle Daten und werfe sie hinterher in einem Rutsch auf den Graphen und zeige solange einen ProgressIndicator (so ein drehendes Ding) oder so an, bis deine Operation fertig ist.
So oder so, ist der Einstieg in JavaFX (und auch andere UI-Frameworks) meist etwas mit umdenken verbunden, aber am Ende keine Hexerei.


Leider will ich einen Live-Graphen. Ich lasse per Timer (javafx.animation.Timeline) periodisch, also in "Frames" die neuen Daten an die Graphen "dranpappen". Was mich dabei stört ist eben, dass dabei jeder Graph und der Hintergrund dazu mehrfach pro Frame neu gezeichnet werden - was performancetechnisch Unsinn ist und das Programm etwas "ruckelt" bei vielen live-Graphen.

Ich könnte die Daten in einem Rutsch über die ObservableList wie bei dir in Zeile 11 bei der Initiierung des LineCharts übergeben. Das klappt aber live nicht mehr, denn jedes mall, wenn ich an einen der Serials-Objekt neue Daten hinzufüge, wird der Hintergrund und der Graph neu gemalt, ohne dass ich es wirklich möchte.

Das wird aber genauso gemacht, wenn ich alle meine Series-Objekte an eine ObservableList binde.

Die einzige Lösung wäre es wohl, jedes mal eine neue ObservableList zu erzeugen und die alte durch die neue zu ersetzen?
 

dzim

Top Contributor
Hm... Irgendwie weiss ich gerade nicht, ob ich mich einfach nur zu blöd ausdrücke:

1) Die Liste, die ich da anlege und hinzufüge ist leer. Klar soweit.
1.1) JavaFX hat interne Mechanismen, Veränderungen an Properties oder ObservablesLists zu tracken eingebaut.

2) dieser Liste füge deine X-Serien zu, die du als separate Linien auf dem Graphen darstellen möchtest.

3) füge nun diese Liste von Serien dem LineChart hinzu
3.1) Änderungen an einer Serien forcieren nun ein Update des LineGraph - aber eigentlich *!!!ohne!!!* diesen neu zu zeichnen.

4) Daten an die jeweilige Serie anhängen.
4.1) Du bist wahrscheinlich auf einem anderen Thread. Wenn ja, dann nutze Platform#run(Runnable) um diese Daten anzuhängen
4.2) Und wie gesagt: Die Daten nur an die Serie hängen, nicht an den Graphen:
Code:
lineChart.getData().get(<deine-Serie>).getData().add(new XYChart.Data<Number, Number>(x, y))
4.3) Und: Nein. Komplett neue Liste (von Serien) ist IMHO nicht nur wenig hilfreich, sondern auch unnötig

Wie gesagt: Ich verwende auch einen Live-Graphen und habe damit überhaupt kein flackern.

Vielleicht wäre noch interessant: Welche Java-Version nutzt du (obwohl ich bei mir ab Java7u45 aufwärt inkl. aller Java8-Versionen keine Probleme damit hatte).

Ich denke, dein Problem sind noch ein wenig die (zugegebenermassen recht komplexen) Datenstrukturen in JavaFX, oder?
 
Zuletzt bearbeitet:

Javohl!

Mitglied
3.1) Änderungen an einer Serien forcieren nun ein Update des LineGraph - aber eigentlich *!!!ohne!!!* diesen neu zu zeichnen.

Ich glaube, exakt da liegt mein Problemm! Ich ging bisher davon aus, dass der LineChart jedes mal neu gemalt wird, wenn JavaFX eine änderung an den Serials bzw. an den Datenpunkten in den Serials feststellt.

Jetzt bin ich verwirrt: wenn die Änderung der Serials-Objekte das Neuzeichnen nicht auslöst - was dann? Prüft das LineChart-Objekt in periodischen Zeitabständen nach, ob sich was an der ObservalbeList bzw. den Inhalten der ObservalbeList geändert hat, und zeichet dies dann neu oder so?
 

Javohl!

Mitglied
Vielleicht wäre noch interessant: Welche Java-Version nutzt du (obwohl ich bei mir ab Java7u45 aufwärt inkl. aller Java8-Versionen keine Probleme damit hatte).

Ich denke, dein Problem sind noch ein wenig die (zugegebenermassen recht komplexen) Datenstrukturen in JavaFX, oder?

Ich benutze Java 8.

Mit dem Flackern hatte ich keine Probleme. Ich sehe nur, dass bei vielen Graphen die CPU-Auslatung recht hoch wird und das programm etwas ruckelig wird und hab gedacht, das kommt von den vielen redundanten Neuzeichnungen.


Ja, die JavaFX-Datenstrukturen sind für den Anfang recht anstrengend.
 

dzim

Top Contributor
Hm. Für den Augenblick bin ich mit meinem Latein am Ende. Ohne den ganzen Code mal in Aktion zu sehen, ist es aber eben auch extrem schwer, eine definitive Aussage zu machen...
Sorry!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
V automatisches neuzeichnen verhindern AWT, Swing, JavaFX & SWT 3
news2swen automatisches erstellen eines Languagefiles AWT, Swing, JavaFX & SWT 1
M JavaFX Automatisches Aktualisieren der Seite AWT, Swing, JavaFX & SWT 26
N "Automatisches" erstellen von jButtons AWT, Swing, JavaFX & SWT 1
Thallius Automatisches Scrollen zum aktiven JTextView klappt nicht AWT, Swing, JavaFX & SWT 2
K Swing Automatisches "Packen" beim "Neu-Painten" AWT, Swing, JavaFX & SWT 2
F Swing GUI-Thread für automatisches Update nutzen AWT, Swing, JavaFX & SWT 10
K Automatisches schliessen eines Dialogs AWT, Swing, JavaFX & SWT 4
P Automatisches Mitscrollen der ScrollPane AWT, Swing, JavaFX & SWT 2
S Automatisches Rendern einen JPanels AWT, Swing, JavaFX & SWT 8
G Weiches automatisches verschieben eines JSplitPane-Dividers? AWT, Swing, JavaFX & SWT 3
V Automatisches Scrollen bei JScrollPane AWT, Swing, JavaFX & SWT 10
S Automatisches Scrollen in einer JTextArea AWT, Swing, JavaFX & SWT 6
Thallius JScrollPane Scrollpos setzen nach Neuzeichnen AWT, Swing, JavaFX & SWT 3
A Neuzeichnen bei AbstractAction AWT, Swing, JavaFX & SWT 4
A Swing JFrame neuzeichnen lassen, position neu berechnen lassen? AWT, Swing, JavaFX & SWT 9
M GUI muss updaten und neuzeichnen AWT, Swing, JavaFX & SWT 3
E Swing Neuzeichnen von JPanel AWT, Swing, JavaFX & SWT 4
P problem mit neuzeichnen AWT, Swing, JavaFX & SWT 2
L Beim Neuzeichnen einer Swing GUI kurz Schwarzer Hintergrund AWT, Swing, JavaFX & SWT 8
D Jpanel neuzeichnen AWT, Swing, JavaFX & SWT 5
K AWT Neuzeichnen unterbinden AWT, Swing, JavaFX & SWT 13
N Swing MainWindow(JFrame) aktualisieren(neuzeichnen) repaint AWT, Swing, JavaFX & SWT 4
P Swing JTextArea - beim neuzeichnen bleibt manchmal weißer Kasten AWT, Swing, JavaFX & SWT 10
S Swing JFrame neuzeichnen - bleibt grau AWT, Swing, JavaFX & SWT 18
D jScrollPane - neuzeichnen AWT, Swing, JavaFX & SWT 4
S Probleme beim Neuzeichnen eines JLabels AWT, Swing, JavaFX & SWT 6
R Bestimmte Komponenten vom Neuzeichnen abhalten AWT, Swing, JavaFX & SWT 2
G SWT - Neuzeichnen AWT, Swing, JavaFX & SWT 2
P Zeichnen in Canvas und Neuzeichnen AWT, Swing, JavaFX & SWT 3
J NeuZeichnen eines JXTitledPanels? AWT, Swing, JavaFX & SWT 4
A Komponente entfernen. Kein neuzeichnen nach validate() AWT, Swing, JavaFX & SWT 2
B Swing GUI neuzeichnen AWT, Swing, JavaFX & SWT 5
N Flackern beim neuzeichnen von JPanel AWT, Swing, JavaFX & SWT 19
H neuzeichnen von graphics nach minimierung oder ähnlichem AWT, Swing, JavaFX & SWT 10
W Problem beim neuzeichnen eines Rechteckes (SWT) AWT, Swing, JavaFX & SWT 2
M drawLine() in JPanel hinzufügen ohne Neuzeichnen AWT, Swing, JavaFX & SWT 3
A Null pointer exception beim Neuzeichnen AWT, Swing, JavaFX & SWT 4
R Neuzeichnen eines JFrame mit repaint AWT, Swing, JavaFX & SWT 3
G JScrollPane scrollt nach Neuzeichnen von selber AWT, Swing, JavaFX & SWT 2
S neuzeichnen AWT, Swing, JavaFX & SWT 4
T JLabel neuzeichnen nach überdecken durch andere Fenster AWT, Swing, JavaFX & SWT 5
A Problem beim Neuzeichnen AWT, Swing, JavaFX & SWT 2
S AWT: Panel durch anderes Panel ersetzen. Neuzeichnen-Problem AWT, Swing, JavaFX & SWT 4
J Anklicken der Symbolleiste und Neuzeichnen des Buttons AWT, Swing, JavaFX & SWT 6
M Probleme mit JTable neuzeichnen! AWT, Swing, JavaFX & SWT 2
D Repaint Funktioniert nicht AWT, Swing, JavaFX & SWT 2
D JUNG Repaint function does not work AWT, Swing, JavaFX & SWT 2
E repaint Probleme AWT, Swing, JavaFX & SWT 13
G listener repaint() - verschiedene Darstellung AWT, Swing, JavaFX & SWT 24
ExceptionOfExpectation Textdarstellung auf einem Canvas mit Hilfe von repaint(); AWT, Swing, JavaFX & SWT 6
J actionperformed wird nicht aufgerufen/ repaint() AWT, Swing, JavaFX & SWT 6
L Swing repaint() ruft paintComponent(g1d) nicht auf AWT, Swing, JavaFX & SWT 12
G Repaint wird nicht durchgeführt AWT, Swing, JavaFX & SWT 8
I Swing Verhindern, dass repaint() kaskadiert AWT, Swing, JavaFX & SWT 6
ms_cikar Update swingUtilities Repaint in der Schleife AWT, Swing, JavaFX & SWT 3
T Swing Probleme mit repaint() bzw. JScrollPane AWT, Swing, JavaFX & SWT 7
N Swing JButtons werden nach repaint() doppelt dargestellt AWT, Swing, JavaFX & SWT 12
K Methode repaint() AWT, Swing, JavaFX & SWT 1
B Swing Wann brauche ich repaint() ? AWT, Swing, JavaFX & SWT 1
javampir Swing repaint in JavaFX Anwendung AWT, Swing, JavaFX & SWT 3
A repaint(); AWT, Swing, JavaFX & SWT 9
J Swing ungewünschter Nebeneffekt bei der repaint() Methode AWT, Swing, JavaFX & SWT 3
A Problem: repaint() - Schleife AWT, Swing, JavaFX & SWT 3
S 2D-Grafik repaint()-Aufruf. Und nichts geschieht. AWT, Swing, JavaFX & SWT 5
Joew0815 JDialog repaint() funktioniert nicht wie gewünscht. AWT, Swing, JavaFX & SWT 2
P JPanel und Repaint AWT, Swing, JavaFX & SWT 5
F JTable Repaint Issue AWT, Swing, JavaFX & SWT 1
N Observer: update ruft nicht repaint auf AWT, Swing, JavaFX & SWT 0
C Repaint() funktioniert nicht in TabbedPanel AWT, Swing, JavaFX & SWT 5
S JList repaint AWT, Swing, JavaFX & SWT 1
L NullpointerException und Probleme mit repaint() AWT, Swing, JavaFX & SWT 11
M Repaint mittels Button richtig aufrufen klappt nicht AWT, Swing, JavaFX & SWT 1
B Repaint auf JFrame, JLabel und ImageIcon AWT, Swing, JavaFX & SWT 4
K 2D-Grafik Paint - Wie binde ich repaint ein? AWT, Swing, JavaFX & SWT 8
D repaint() klappt anders als vorgestellt AWT, Swing, JavaFX & SWT 15
R Repaint() in Schleifen, Threads AWT, Swing, JavaFX & SWT 13
B Swing Repaint Problem - mal wieder AWT, Swing, JavaFX & SWT 5
P 2D-Grafik Gezielter Repaint einzelner Frames in Java-Game AWT, Swing, JavaFX & SWT 6
javampir Bei repaint nix los AWT, Swing, JavaFX & SWT 2
B Swing repaint() AWT, Swing, JavaFX & SWT 3
Ernesto95 AnimationLoop - Problem bei Aufruf von repaint AWT, Swing, JavaFX & SWT 6
P 2D-Grafik repaint(); steigender RAM Verbauch AWT, Swing, JavaFX & SWT 6
Y KeyListener, GUI Thread, repaint AWT, Swing, JavaFX & SWT 7
S Applet Repaint AWT, Swing, JavaFX & SWT 3
M Programm hängt sich auf nachdem repaint() benutzt wurde AWT, Swing, JavaFX & SWT 2
R Swing Grafikfehler bei repaint AWT, Swing, JavaFX & SWT 2
N repaint() blockieren AWT, Swing, JavaFX & SWT 6
K canvas zeig nach repaint nichts an AWT, Swing, JavaFX & SWT 8
M Repaint() AWT, Swing, JavaFX & SWT 14
J Swing repaint, repaint, repaint AWT, Swing, JavaFX & SWT 8
M Applet repaint() verlangsamen AWT, Swing, JavaFX & SWT 7
R paintComponent malt bei repaint() Rahmen um Panel AWT, Swing, JavaFX & SWT 7
P EDT Problem? Kein Aufruf der repaint Methode AWT, Swing, JavaFX & SWT 6
V Applet JApplet Flackern durch Repaint AWT, Swing, JavaFX & SWT 11
kodela Problem mit repaint() AWT, Swing, JavaFX & SWT 3
N Swing Funktion repaint() updated nicht AWT, Swing, JavaFX & SWT 5
F repaint reagiert nicht AWT, Swing, JavaFX & SWT 8
S AWT Probleme mit repaint() AWT, Swing, JavaFX & SWT 2
D Repaint()? Oder was??? AWT, Swing, JavaFX & SWT 5

Ähnliche Java Themen

Neue Themen


Oben