Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
If your program creates and refers to its GUI the correct way, you might not need to worry about threads. If your program is an applet, it's safe to construct its GUI in theinit
method. You're also safe if your program is an application with the following common pattern:However, if your program creates threads to perform tasks that affect the GUI or if it manipulates an already visible GUI in response to anything but a standard event, read on.//Thread-safe example public class MyApplication { public static void main(String[] args) { JFrame f = new JFrame(...); ...//Add components to the frame here... f.pack(); f.setVisible(true); //Don't do any more GUI work here. } ... //All manipulation of the GUI -- setText, getText, etc. //is performed in event handlers such as actionPerformed(). ... }
Swing components can be accessed by only one thread at a time, generally the event-dispatching thread. Thus, the single-thread rule is as follows.This rule might sound scary, but for many simple programs, you don't have to worry about threads.
Rule: Once a Swing component has been realized, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread.Before we go into detail about how to write Swing code, let's define the term realized. "Realized" means that the component has been painted on-screen or that it is ready to be painted. A Swing component that's a top-level window is realized by having one of these methods invoked on it:
setVisible(true)
,show
, orpack
. Once a window is realized, all the components it contains are realized. Another way to realize a component is to add it to a container that's already realized. You'll see examples of realizing components later.
Note: The show method does the same thing assetVisible(true)
.Exceptions to the Rule
The rule that all code that might affect a realized Swing component must run in the event-dispatching thread has a few exceptions.
- A few methods are thread safe.
- In the Swing API documentation, thread-safe methods are marked with this text:
This method is thread safe, although most Swing methods are not.- An application's GUI can often be constructed and shown in the main thread.
- As long as no Swing or other components have been realized in the current runtime environment, it's fine to construct and show a GUI in the main thread of an application. To help you see why, here's an analysis of the thread safety of the thread-safe example. To refresh your memory, here are the important lines from the example:
public static void main(String[] args) { JFrame f = new JFrame(...); ...//Add components to the frame here... f.pack(); f.setVisible(true); //Don't do any more GUI work here. }
- The example constructs the GUI in the main thread. In general, you can construct (but not show) a GUI in any thread, as long as you don't make any calls that refer to or affect already realized components.
- The components in the GUI are realized by the
pack
call.- Immediately afterward, the components in the GUI are shown with the
setVisible
(orshow
) call. Technically thesetVisible
call is unsafe, because the components have already been realized by thepack
call. However, because the program doesn't already have a visible GUI, it's exceedingly unlikely that a paint request will occur beforesetVisible
returns.- The main thread executes no GUI code after the
setVisible
call. This means that all GUI work moves from the main thread to the event-dispatching thread, and the example is, in practice, thread safe.
An applet's GUI can be constructed and shown in theinit
method.- Existing browsers don't paint an applet until after its
init
andstart
methods have been called. Thus constructing the GUI in the applet'sinit
method is safe, as long as you never callshow()
orsetVisible(true)
on the applet object.- These
JComponent
methods are safe to call from any thread:repaint
andrevalidate
.
- These methods queue requests to be executed on the event-dispatching thread.
- Listener lists can be modified from any thread.
- It's always safe to call the
addListenerTypeListener
andremoveListenerTypeListener
methods. The add/remove operations have no effect on an event dispatch that's under way.
Most postinitialization GUI work naturally occurs in the event-dispatching thread. Once the GUI is visible, most programs are driven by events, such as button actions or mouse clicks, which are always handled in the event-dispatching thread.However, some programs need to perform nonevent-driven GUI work after the GUI is visible. Here are two examples.
The
- Programs that must perform a lengthy initialization operation before they can be used
- This kind of program should generally show some GUI while the initialization is occurring and then update or change the GUI. The initialization should not occur in the event-dispatching thread; otherwise, repainting and event dispatching would stop. However, after initialization, the GUI update or change should occur in the event-dispatching thread, for thread-safety reasons.
- Programs whose GUI must be updated as the result of nonstandard events
- For example, suppose that a server program can get requests from other programs that might be running on different machines. These requests can come at any time, and they result in one of the server's methods being invoked in a possibly unknown thread. How can that method update the GUI? By executing the GUI-update code in the event- dispatching thread.
SwingUtilities
class provides two methods to help you run code in the event-dispatching thread:
invokeLater
- Requests that some code be executed in the event-dispatching thread. This method returns immediately, without waiting for the code to execute.
invokeAndWait
- Acts like invokeLater, except that this method waits for the code to execute. As a rule, you should use invokeLater rather than this method.
For more information on deploying threads in your Swing programs, see the section How to Use Threads
Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
Copyright 1995-2001 Sun Microsystems, Inc. All rights reserved.