CS 4773 Object Oriented Systems Review of Swing And Threads
Threads and Java
- We already know:
- Every Java application starts with a main method that runs a main thread.
- We saw this in the PingPong example.
- When the first window is shown, a second thread, the AWT event dispatch
thread is created.
- All event notifications are run in the event dispatch thread.
- In response to an action, the event dispatch thread should only execute
for a short time.
- If you need to run something that will take a long time,
create a new thread to do it.
- All of this is fine as long as the created thread(s) do not have to
interact with the Swing widgets.
- Most Swing methods are not thread-safe.
- The consequence is that the user interface can become corrupted if a Swing
method is called from within a user thread.
Using threads with Swing
- If an action takes a long time, fire up a thread to handle it
- If an action can block on input or output, fire up a new thread to handle it.
- If you need to wait for a specific amount of time, don't sleep in the
event dispatch thread, use a timer event.
- The work done in the worker threads cannot touch the user interface.
- Read any information you need from the user interface before starting
the thread.
- Launch the thread
- update the user interface from the event dispatch thread.
The last of these rules is called the single thread rule for
Swing programming.
Exception to the single thread rule:
- A few of the Swing methods are thread-safe.
They are specifically marked as being thread safe in the documentation.
Some of the thread-safe methods are:
JTextComponent.setText
JTextArea.insert
JTextArea.append
JTextArea.replaceRange
- Note that JLabel.setText is not thread-safe.
A JLabel is not a JTextComponent.
- The following methods are thread-safe:
repaint
revalidate
- You can add ir remove event listeners in any thread.
The corresponding methods will be called by the event dispatch thread.
- You can construct components, set their properties,
and add them to containers, as long as they have not be realized.
- A component has been realized if it can receive repaint or validation
events.
- This happens when setVisible(true) or pack
has been called.
- It also happens when it is added to a container that has been realized.
- You can create the GUI in the main method before calling
setVisible(true).
How to update from the event dispatch queue:
Use one of the static methods in the EventQueue class:
invokeLater(Runnable runnable) or
invokeAndWait(Runnbale runnable) throws InterruptedException, InvocationTargetException
Example:
EventQueue.invokeLater(new Runnable()
{
public void run() {
label.setText("This is a label");
}
});
See the SwingThreadTest example.
Some modifications made form the Core Java code:
- Keep a list of the threads created
- Display the total number of threads when a new one is created.
- Add a button to stop all threads
- Insert informative string instead of random number in combo box.