Check if thread is EDT is necessary?
I have an UI implemented with Swing. One component does some work that may take some time, so I use SwingUtilities.invokeLater
. However, I was reading some old code and found this in an ActionListener
:
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// code X
}
});
} else {
// code X
}
I thought that it made sense since it separates code X
from the EDT. However, I found it error-prone since I have used it a couple of times and both times I forgot the else
part.
The question is: is the SwingUtilities.isEventDispatchThread()
checking necessary? Or could I assume that I 开发者_如何学Goam not in the EDT and always use invokeLater
?
Thanks a lot.
Invoking later is fine even if you are on the EDT, however it certainly changes the timing of events, so you have to be sure that you were not dependent on the sequence of the code here when you were on the EDT. That being said, a simple way to avoid forgetting the else is to wrap the call in a utility method:
public static void invokeInDispatchThreadIfNeeded(Runnable runnable) {
if (EventQueue.isDispatchThread()) {
runnable.run();
} else {
SwingUtilities.invokeLater(runnable);
}
}
That way you never forget the else
.
Also, in general in your idom repeating code x
is a very bad idea, as you may find later that you have to fix or improve that code and you will only do it in one place, leaving a bug in the other.
I believe for your particular use case, checking isEventDispatchThread()
is unnecessary. Directly calling invokeLater()
will not create a new thread, so this occurs no performance penalty.
The code really ought to know if it is on the EDT or not (if that is relevant). So java.awt.EventQueue.isDispatchThread
should be left to assertions.
Simply if you have on your code a thread(A)launch by the EDT, and in that thread(A) you have another thread(B) which have to modify your GUI, in that case you have to use invokeLater on thread(B). However, if the modification of your GUI is doing by first thread(A) it's not necessary to use invokeLater.
精彩评论