Wie benutzt du den Event Dispatch Thread?

8

Ich habe gelernt, dass Swing nicht threadsicher ist. Wenn ich genauer hinsehe, habe ich festgestellt, dass jede Änderung an einer Swing-Komponente im Event-Dispatch-Thread durchgeführt werden muss, um verschiedene Probleme im Zusammenhang mit Multithreading zu vermeiden. Die Information schien jedoch dort vollständig zu stoppen. Es scheint kein gutes Tutorial zu geben, das erklärt, wie man dies überall im Internet zugänglich macht.

Beim Patchen von Informationen aus Code, der in Bezug auf andere Probleme gepostet wurde, schien es, als würde ich um jede einzelne Swing-Änderung in meinem Programm einen unordentlichen Code-Block anlegen müssen (wie dieses Beispiel aus meinem eigenen Code):

%Vor%

Grundsätzlich, ist das richtig? Muss ich diesen Code (oder das Äquivalent zu invokeLater) für jede Änderung einer Swing-Komponente in meinem Code verwenden?

Warum macht Swing das nicht automatisch?

    
Tharwen 25.10.2011, 22:37
quelle

4 Antworten

6

Der Trick ist, dass wenn Swing Sie anruft, es IMMER im EDT ist, also müssen Sie sich nicht darum kümmern.

Wenn Sie jedoch einen Timer oder eine Aktion haben, die durch ein anderes externes Ereignis, Ihren Hauptthread oder einen anderen von Ihnen erstellten Thread ausgelöst wurde, dann müssen Sie invokeLater oder invokeAndWait verwenden.

Mit anderen Worten, ja Swing macht "es" automatisch. Die Verwendung von invokeXx ist so selten, dass wenn swing es intern tun würde, es zu viel Zeit verschwenden würde.

Viele Java-Programmierer werden das nie herausfinden und es kann einige ziemlich unangenehme, schwer zu findende Probleme beim Zeichnen Ihrer GUI geben. Ich wünschte, Swing hätte eine Ausnahme ausgelöst, wenn man sie nicht mit dem EDT anwendete - Java hätte einen besseren Ruf, wenn es um professionelle GUIs ging, wenn es so wäre, weil es dort weniger Mist geben würde.

    
Bill K 25.10.2011, 22:58
quelle
4

Beachten Sie, dass jeder Code, der von Ereignishandlern ausgeführt wird, bereits im EDT ausgeführt wird (das Ereignis im Akronym)

Dies bedeutet, dass Sie für den allgemeinen Gebrauch (während Sie sich nicht mit Swingworkers und threadpools und so zu tun) immer im EDT

sind

und Sie können immer abfragen, ob Sie mit SwingUtilities.isEventDispatchThread()

im EDT sind

Beachten Sie auch, dass in Ihrem Code der Aufruf von invokeAndWait fehlschlägt und einen Fehler auslöst, wenn Sie bereits im EDT sind

    
ratchet freak 25.10.2011 22:58
quelle
3

Grundsätzlich zeichnen oder aktualisieren Sie die GUI nicht von außerhalb des EDT. Sie verwenden SwingUtilitis.invokeLater () von einem anderen Thread, um sicherzustellen, dass der GUI-Zeichnungs- oder -aktualisierungscode auf dem EDT ausgeführt wird.

    
Zaki 25.10.2011 22:45
quelle
3

Nicht alle Benutzeroberflächencodes müssen Teil eines runnable in einem invokeLater-Aufruf sein. Das liegt einfach daran, dass ein großer Teil Ihres Programms ohnehin auf dem EDT läuft. Sie müssen Nachrichten nur dann an den EDT senden, wenn Sie sich in einem anderen Thread befinden.

    
Savvas Dalkitsis 25.10.2011 22:59
quelle