Slyh: JTextBox Hintergrund aktualisieren

Beitrag lesen

Hallo,

na super. Jetzt habe ich gerade eine längliche Antwort auf dein Posting
geschrieben, und dann schließe ich aus Versehen -- warum auch immer --
das Browser-Fenster. *grummel*

Also nochmal.

So ist's. Aber was heisst das nun?

Kurz erklärt:
Alle Events werden im EventDispatch-Thread verarbeitet. Dies gilt auch
für "Zeichne mal neu"-Events (aka Repaint). Es wird immer ein Event
nach dem anderen abgearbeitet. D.h. daß die Methode, die auf einen Event
reagiert, zuerst wieder zurückkehren muß, bevor der nächste Event in der
Event-Queue abgearbeitet wird. In deinem Fall muß also zuerst die Methode
actionPerformed(), die ja wiederum runAnimation() aufgerufen hat,
zurückkehren, bevor der nächste Event ausgeführt werden kann, der
möglicherweise das Neuzeichenen der Komponente(n) anstößt.

In deinem Java-Buch ist das mit der Event-Queue und dem EventDispatch-
Thread vermutlich sehr viel besser erklärt.

Die Lösung deines Problems ist erstmal einfach:
Du führst deine for-Schleife in einem eigenen Thread aus, der in
der Methode actionPerformed() erzeugt und gestartet wird. Die Methode
actionPerformed() läuft dann weiter (beendet sich also), während
der Thread mit der for-Schleife parallel dazu läuft und damit den
EventDispatch-Thread nicht blockiert.

So einfach ist es dann aber doch nicht. Komponenten dürfen nämlich
nur innerhalb des EventDispatch-Threads verändert werden.
Das hört sich jetzt wie ein Widerspruch an: Einerseits blockiert die
for-Schleife den EventDispatch-Thread, und damit das Neuzeichnen
der Komponente, andererseits muß die Änderung aber im EventDispatch-
Thread erfolgen.
Das ist aber nur auf den ersten Blick unlogisch. Swing ist nicht
thread-safe. D.h. daß alle Änderungen, die eben nicht aufgrund eines
Events (der ja im EventDispatch-Thread ausgeführt werden würde) durch-
geführt werden sollen, von Hand in den EventDispatch-Thread "geschoben"
werden müssen. Hierfür bietet die Klasse SwingUtilities die Methode
invokeLater(Runnable). Diese nimmt ein Objekt der Klasse Runnable
entgegen und fügt dieses an das Ende der EventQueue an. Sind alle
vorherigen Events abgearbeitet, wird die run()-Methode des Objekts
aufgerufen.

Du mußt also in deiner For-Schleife ein Runnable-Objekt erzeugen
(z.B. als anonyme Inner-Class), in dessen run()-Methode die eigentliche
Änderung der Komponentenfarbe ausgeführt wird.
(Die For-Schleife muß natürlich trotzdem innerhalb eines eigenen
Threads laufen, da sonst nachwievor der EventDispatch-Thread blockiert
werden würde.)

Alle Klarheiten beseitigt? Gut. :-)

Das Java-Buch deiner Wahl wird dir die ganze Geschichte mit dem
EventDispatch-Thread und invokeLater erheblich besser erklären können,
als ich das mit meinen paar Zeilen Text könnte. Lies einfach dort
mal nach.

Ansonsten kann ich dir noch das Vorlesungsskript zur Vorlesung
"Benutzeroberflächen" an der FH-Karlsruhe von Holger Vogelsang
Nahe legen. (http://www.fbi-lkt.fh-karlsruhe.de/~voho0001/Benutzeroberflachen/Vorlesung/FB08-Swing_I18N_und_Ablaufsteuerung.pdf
ab Seite 27)
Dort wird die ganze Sache meiner Ansicht nach sehr gut
und kompakt beschrieben. Natürlich steht näheres auch in der Java-API-
Doku. Vermutlich gibt es außerdem ein Java-Tutorial von Sun dazu.

Wenn du konkrete Fragen hast, frag einfach hier nach.

Gruß
Slyh