In SwingWorker.doInBackground Methode GUI verändern, mit oder ohne invokeLater?

DarthShader

Erfahrenes Mitglied
Hallo,

ich verwende des öfteren den SwingWorker, um in meiner GUI einige Animationen ablaufen zu lassen, z.B. irgendwelche Panels verschieben.

Ich habe bisher immer die GUI Komponenten direkt in der "doInBackground()" Methode des SwingWorkers verändert, es ging stets ohne Probleme.

Nun habe ich aber gelesen, dass man GUI Komponenten nur aus dem Event-Disptach-Thread heraus verändern sollte, wozu es ja auch "SwingUtilities.invokeLater" gibt. Deshalb die Frage, sollte ich "invokeLater" innerhalb der "doInBackground()" Methode des SwingWorkers benutzen? Was könnten denn für Probleme entstehen, wenn ich es nicht tue (wie gesagt, habe noch nie irgendwelche Probleme damit gehabt)?


Vielen Dank für Eure Hilfe!
 
Wenn ich mich nicht irre sollte das garkeine Probleme geben, da der SwingWorker bereits selbst mit invokeLater() seine Operationen in doInBackground() abarbeitet.
 
Hallo,

danke für Deine Antwort.

Wenn ich allerdings innerhalb von doInBackground() ein "System.out.println( EventQueue.isDispatchThread() )" mache, dann gibt er mir "false" aus.
 
Richtig..der SwingWorker arbeitet in einem eigenen Thread...benutzt aber invokeLater um dem EDT zu sagen was er wann machen soll/darf.

invokeLater kannst du direkt auf dem EDT sogar soweit ich weis garnicht aufrufen, das wirft ne Exception.
 
Das verwirrt mich nun etwas - stellen wir fest, dass

a) doInBackground nicht im EDT läuft
b) man invokeLater verwenden sollte, wenn man aus einem Nicht-EDT-Thread die GUI verändert.

Daraus folger ich, dass ich in doInBackground() nicht direkt die GUI verändern darf, sondern invokeLater benutzen muss. Oder ist das jetzt falsch?
 
Hi,

doInBackground() läuft nicht im EDT - genaus deshalb soll man auch längere Aktionen in diese Methode auslagern.

Wenn du hier Änderungen an der GUI machen willst, dann kannst du das entweder:

* mit invokeLater() tun (das wirft keine Exception) -> kein sauberes Design
* mit process(T...) -> wird in dem EDT ausgeführt
* oder du tust es in einem abschließendem Schritt, nachdem die längere Aktion zurück kommt - wenn das möglilch ist.
 
Hallo firmadankt,

vielen Dank für den Hinwis mit "process(...)", ich habe dies nun in der API nachgelesen, und das Zusammenspiel mit "publish" und "process" verstanden und werde das in Zukunft so umsetzen.

Danke!
 
Zurück