| Hal Vaughan 2004-10-27, 3:58 am |
| I've been stuck on this for a while (and several posts). It's part of
something bigger, so it's kind of hard to post code here. What I'd like to
know is if this outlined example (below) is a safe way to update Swing
components from other threads. When the user clicks on a JButton, my goal
is to disable several buttons, open a new "Waiting..." window, run an
external program, wait until the external program is done, then close the
"Waiting..." window and enable the buttons. Is this how (in general) to do
it:
1. The actionPerformed listener creates a thread to run the external
program
2. After creating the new thread, I can disable buttons and open a window in
the actionPerformed listener.
3. The new thread includes a (not necessarily) anonymous Runnable object
that closes the new window and enables the disabled buttons.
4. I use EventQueue.invokeLater(Runnable) to run the Runnable object created
in #3 above, then run the external program.
If I understand this correctly, creating a thread in the ActionListener is
necessary so the listener can update the display while the thread is
running. Inside this new thread I can't access a Swing object directly
because Swing objects aren't thread safe. I can, however, update a Swing
component from a new thread by creating a Runnable object, using
EventQueue.invokeLater() to run it, and access the Swing object ONLY from
the Runnable that is invoked later, since that will turn the updating over
to the event dispatching thread and this way the only thread doing any
updating of Swing objects is the EDT.
Is this right? This has been a hard topic for me to grasp, so I hope this
works and I finally have a safe way to do this.
Thanks!
Hal
|