Swing Frage zu paintComponent/getGraphics

P@u1

Aktives Mitglied
Hallo zusammen,

ich habe vermehrt gelesen, dass man immer alle Zeichnungen in paintComponent machen soll.
Leider hatte ich das noch nicht gelesen, als ich mein Programm (einen Plotter für ein EKG-Signal) geschrieben habe und habe deshalb mit getGraphics gearbeitet.
Das ganze funktioniert allerdings trotzdem und ich habe jetzt noch ein paar Fragen:

Also erstmal, was spricht dagegen, das mit getGraphics zu machen, das Hauptargument was ich gelesen hatte war, dass es dann nicht neu gezeichnet wird, aber ich das so gemacht, das ein Timer laufend die neuen werte zeichnet und das ich trotzdem paintComponent benutze und nur dann wirklich alles neu zeichne und ansonsten nur das was neu kommt, weils sonst extrem flackert.
Ist das so nicht sinnvoller?
Also so wie ich das verstehe, macht man das mit der paintComponent methode so, dass immer alles neu gezeichnet wird, ich erneuere mit 25Hz also 40 Bildern / Sekunde und das funktioniert so nicht wirklich gut.
Wie würdet ihr sowas umsetzen?

Und noch eine andere Sache:
Ich maches im Moment so, dass nicht in paintComponent selbst neugezeichnet wird, sondern, dass dort ein Flag gesetzt wird und dann beim nächsten Zeichen durch den Timer einmal alles neugezeichnet wird, was auch relativ gut funktioniert.
Der Plotter benutzt dafür immer ein Attribut graphics, das am anfang einmal auf panel.getGraphics gesetzt wurde.
Testweise habe ich dann mal im paintComponent dieses Attribut umgestzt auf g, also den Übergabeparameter von paintComponent, was komischerweise zur Folge hatte, dass die Neuzeichnung zwar gemacht wurde, aber sofort danach wieder verschwand, so das man gerade noch sehen kann, dass überhaupt etwas gemacht wurde.
Habt ihr dafür irgendwelche Erklärungen?

Danke schonmal für euer Hilfe.
P.S.:
Falls sich wer wundert, warum ich schon wieder einen neuen Thread aufmache, ich dachte mir, da der Titel des alten Threads nicht mehr zu den aktuellen Fragen passt, mach ich mal nen neuen auf.
 
Wenn du Swing-Komponenten (JPanel, JComponent, J...) richtig benutzt, flackert garnichts weil diese Komponenten automatisch double-buffering verwenden. Mit "getGraphics" kann man allerdings sehr schnell das ganze ausgeklügelte System durcheinander bringen und es schön flackern lassen... (gerade wenn man irgendwie "verzögert" zeichnen will).

IMHO die beste Lösung in deinem Fall wäre zuerstmal auf ein Bild (z.B. BufferedImage) zu zeichnen, und dann dieses Bild in der paintComponent-Methode direkt anzuzeigen (Graphics.drawImage(...)). Du kannst dann immerwieder kleine Updates im Bild machen, und es neu zeichnen. Beide Operationen kosten fast keine Zeit.
 
Das mit dem Buffern hatte ich mal versucht, aber es wurde dadurch mega langsam und der plot kam nicht mehr mit dem datenstrom hinterher.
Meinste das lag daran, dass ich mit getgraphics gearbeitet hab?

Man kann aber ohne Probleme das so machen, dass man in paintComponent eine methode aufruft und g übergibt und dann was auf g zeichnen lässt, oder ist das auch schon problematisch?

Wird wohl halbwegs viel Arbeit, alles umzustellen, aber ich denk ich werds mal machen.

Bist du dir denn ganz sicher, dass das ganze schnell genug wird?
 
Andere Methoden aufrufen ist kein Problem. Problematisch ist nur zu zeichnen wenn das Framework das eigentlich nicht erwartet.

Ich denke, das kann man schon schnell machen. Ich meine, den Plot updaten ist 1-2 neue Linien zeichnen. Und ein Bild zeichnen dauert auch fast garantiert nicht mehr als 50 Millisekunden (bei einem älteren PC, und wenn es kleiner als 800x600 Pixel ist).

So ein Graphics Objekt bietet auch Methoden um ein Bild verschoben zu zeichnen, also ein lustiger Laufeffekt sollte auch drin liegen.

Schreib dir doch ein Miniatur-Testprogram um mal die Zeiten zu vergleichen, das dauert ja nicht allzulange.
 
So, ich hab mal ein paar Test gemacht, einmal mit Swing und einmal mit SWT.
Ich habe das jetzt erstmal nicht so gemacht, dass die Kurve sich selbst "auffrisst", sondern so, dass das ganze Bild sich "bewegt".

In Swing läuft es halbwegs ok, aber ein paar kleinere Ruckler treten bei mir schon auf.
Mit SWT ist es eine einzige Katastrophe (flackert nur), aber ich hab heute erst mit SWT angefangen und es kann sehr gut sein, dass ich irgendwas total falsch gemacht hab.
Mir fällt auch auf, dass beim beenden von der SWT-Version Exceptions fliegen, was wohl daran liegt, dass beim Beenden die Timer weiterlaufen und nur die Form weg ist.

Ich lad mal das derzeitige Projekt hoch, es gibt einmal die MainSwing.java und einmal die MainSWT.java für die beiden verschiedenen Versionen.
Achtung, viele Unterodner wegen langem Packagenamen^^
Und ich weiß auch nicht, ob sich die SWT-Version bei euch überhaupt ausführen lässt, ihr müsst dafür wahrscheinlich SWT in den workspace importieren.

Falls euch irgendwas dazu einfällt (möglich Verbesserungen z.B.), bitte melden!
Vielen Dank schonmal!
 

Anhänge


Zurück
Oben