Swing Threads : Java Glossary

*0-9ABCDEFGHIJKLMNOPQRSTUVWXYZ (all)

Swing Threads

Even if you have never used the Thread class, you unwittingly are using Threads whenever you use Swing. To write even the simplest Swing program you must follow some simple thread rules to avoid trouble.

Thread Safety Best Practice
The EDT Which Thread Am I On?
invokeLater and invokeAndWait The Sleep Error
Thread Safe Swing Methods Learning More

Thread Safety

Unlike the AWT (Advanced Windowing Toolkit), Swing is not thread-safe. Officially the AWT is not thread-safe either. Sun does not guarantee that AWT is thread-safe. You are also supposed to do all AWT calls from the event dispatch thread.

The EDT (Event Dispatch Thread)

The Swing EventDispatchThread thread is the thread that prods your various listeners with events. It is sometimes called the EDT, EDT. Sometimes it is called simply the Swing thread, even though it handles AWT as well and even though its Thread name is AWT-EventQueue-0.

There are two fundamental things to understand about Swing and threads:

  1. Time-consuming tasks should not be run on the EDT aka Swing thread. Otherwise the application becomes unresponsive. The EDT is busy executing your task and hence can’t process GUI (Graphic User Interface) events.
  2. Swing components should be accessed on the EDT only. To access components from other threads, you must use SwingUtilities. invokeAndWait, SwingUtilities. invokeLater or SwingWorker.

invokeLater and invokeAndWait

You can’t directly meddle with Swing components, or their backing data models from a second thread. The contract is, if you want to do anything to a Swing component that could have any effect on it’s display from an application thread you should add it to the event dispatch thread’s queue via SwingUtilities.invokeLater( Runnable ) or SwingUtilities.invokeAndWait( Runnable ) so that it will be done on the same thread that Swing itself uses. Obviously you can call Swing methods directly from the EventDispatchThread.

The AWT equivalents are called java.awt.EventQueue.invokeLater( Runnable ) and EventQueue.invokeAndWait( Runnable ). The Swing versions are just wrappers around the AWT methods, so you might as well just use the AWT versions all the time. The Swing versions were stop gaps until the AWT versions were available.

The good news is, even though, with invokeLater and invokeAndWait, you are using the Runnable interface normally associated with starting new threads, you don’t actually have the overhead of creating a new Thread since you are just calling the run method on the already existing Swing thread.

Here is how you would wrap a piece of GUI-manipulating code to run from any thread.

// disable the abort JButton from a non-Swing thread.
SwingUtilities.invokeLater( new Runnable() {
    public void run()
        {
        abort.setEnabled( false );
        }
} );

Thread Safe Swing Methods

There are a few exceptions to the general rule of having to invoke Swing methods from the EventDispatchThread, most notably it is safe to call to the following methods from any thread:
Component.repaint
JEditorPane.replaceSelection
JEditorPane.setText
JTextArea.append
JTextArea.insert
JTextArea.replaceRange
JTextComponent.replaceSelection
JTextComponent.setText
JTextPane.insertComponent
JTextPane.insertIcon
JTextPane.insertLogicalStyle
JTextPane.replaceSelection
JTextPane.setCharacterAttributes
JTextPane.setParagraphAttributes
PlainDocument.setText

Most Swing methods are not safe including:
Container.invalidate
Container.revalidate
Container.validate
JButton.setText
JComponent.revalidate
JComponent.setBackground
JComponent.setEnabled
JComponent.setFont
JComponent.setForeground
JComponent.setVisible
JComponent.validate
JLabel.setText
JTextArea.setText
JTextComponent.setText
If you are unsure, check the Javadoc.
Originally you were allowed to construct new Swing objects on other threads and call their methods, but once they were realised, — once you had called pack/setVisible( true ), from that point on you had manipulate the Components only from the Swing thread (which is not the same thread as the main thread). Sun now recommends doing all manipulation of Swing components, realised or not, via the Swing (aka EDT) thread,

Best Practice

Sun now discourages even that original practice. They even want you to construct a JFrame, via SwingUtilities.invokeLater( Runnable ) or SwingUtilities.invokeAndWait( Runnable ).

Here is the safer way to fire up a GUI with all the initialisation on the Swing thread:

The good news is, even though you are using Runnable, you don’t have the overhead of actually creating a new Thread since you are just calling the run method on the already existing Swing Thread.

Which Thread Am I On?

You are not on the Swing event thread when main first starts up! You are on it in

The Sleep Error

One of the most common errors is to tie up the AWT/Swing event thread with some long running computation or even a sleep. Everything freezes up. The GUI can’t respond to mouse clicks and no repainting happens. You have to spin the time-consuming task off on its own thread or use a Timer. SwingWorker makes it easy to set up a background Thread that interacts with the GUI. If the background task does not use the GUI widgets, it is simpler to use an ordinary Thread instead.

If you violate these rules, the entire system starts to behave unpredicably and irrationally. If by violating these rules, you manage to create two event-processing threads, life gets really interesting as they unpredictably fight with each other handling Swing events.

Learning More



This page is posted
on the web at:

http://mindprod.com/jgloss/swingthreads.html

Optional Replicator mirror
of mindprod.com
on local hard disk J:

J:\mindprod\jgloss\swingthreads.html
Canadian Mind Products
Please the feedback from other visitors, or your own feedback about the site.
Contact Roedy. Please feel free to link to this page without explicit permission.

IP:[65.110.21.43]
Your face IP:[3.146.152.99]
You are visitor number