To answer your question about needing to check EventQueue.isDispatchThread()
that you asked in the some of existing answers' comments:
No, you don't have to check if you are already on the EDT before calling invokeLater()
.
The SwingUtilities JavaDoc states:
If invokeLater is called from the event dispatching thread -- for example, from a JButton's ActionListener -- the doRun.run() will still be deferred until all pending events have been processed. Note that if the doRun.run() throws an uncaught exception the event dispatching thread will unwind (not the current thread).
Below is further explanation of invokeLater()
use.
Notice in ButtonDemo.java that createAndShowGUI() is called using invokeLater(). We must do this because the main() method is not running on the EDT (Event Dispatch Thread). main() is running on its own special main thread that every Java app has.
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
However in actionPerformed()
, the invokeLater()
method is not used because here we already on the EDT.
//b1, b2, and b3 are all JButtons
public void actionPerformed(ActionEvent e) {
if ("disable".equals(e.getActionCommand())) {
b2.setEnabled(false);
b1.setEnabled(false);
b3.setEnabled(true);
} else {
b2.setEnabled(true);
b1.setEnabled(true);
b3.setEnabled(false);
}
}
As far as I can recall, Event Listener methods such as actionPerformed()
are always called from the EDT. (Sorry I don't know supporting documentation off-hand, and I don't have enough reputation yet to post anymore links anyway. Along with reading the pages linked in camickr's answer, try Google searching for "java tutorial swing introduction event listeners".)
So if you are trying to update a Swing component from a thread other than the EDT, call invokeLater()
. If you are in an Event Listener method (i.e. already on the EDT), you don't need to call invokeLater()
.