Skip to content

Event Dispatch Thread

Mikle edited this page Aug 7, 2019 · 3 revisions

What is it?

Event Dispatch Thread (or shortly - EDT) is a special Thread that starts and runs in background whenever your code uses any components from Swing framework. EDT exists specifically for processing all of the UI-related operations, that is why Swing is quite often called a single-threaded UI framework.

Although Swing on its own does NOT force you to use EDT while working with Swing components (unlike JavaFX framework does by throwing exceptions whenever you violate the rules), it is highly recommended to use EDT for next kinds of operations:

  • Creating new components, for example: new JFrame (), new JButton () or new JLabel ()
  • Changing any component settings, for example: frame.setLayout ( new BorderLayout () )
  • Manipulating component models, for example: button.getModel ().setSelected ( true )

There are a few operations you can usually perform outside of EDT:

  • Requesting general component settings, for example: label.getBackground ()
  • Requesting specific component settings, for example: tabbedPane.getSelectedIndex ()
  • Requesting component model & data, for example: tree.getModel ().getRoot ()
  • Calling methods JComponent.revalidate () and Component.repaint (...)

General rule is pretty simple - if operation does something from the first list - you have to perform it within EDT. So for example if requesting component setting causes it to perform any operation from the first list - you should not use it outside of EDT.

The main reason to use EDT for all kinds of operations mentioned in the first list is to make sure nothing goes wrong. To put it simple - Swing is not thread-safe. That means that if you attempt to change multiple settings on a single component from different threads - there is a high chance you will either receive a bunch of exceptions and/or break the component and UI in the process. There are quite a few checks and workarounds in Swing framework code, but those were only made for most common misuse cases and I personally think they shouldn't have been added at all in the first place.

How to use it?

The most common way to queue any code into EDT:

SwingUtilities.invokeLater ( new Runnable ()
{
    @Override
    public void run ()
    {
        // Any Swing code
    }
} );

Code submitted in the EDT queue like this will be performed as soon as possible. Sometimes it might take a while if there were a lot of other operations queued, sometimes it will be performed right away.

I personally recommend splitting your UI-related code and pushing it through multiple invokeLater calls. That will ensure your application UI remains responsive at all times because if your EDT is busy with some heavy long-running operation - your UI will NOT respond until it is done because all repainting operations, mouse and keyboard events etc are also processed on EDT.

There is also another method that allows you to wait for your code execution:

try
{
    SwingUtilities.invokeAndWait ( new Runnable ()
    {
        @Override
        public void run ()
        {
            // Any Swing code
        }
    } );
}
catch ( final InterruptedException e )
{
    e.printStackTrace ();
}
catch ( final InvocationTargetException e )
{
    e.printStackTrace ();
}

Although you have to deal with the exceptions.

It is important to understand that any requests queued into EDT through either of the two methods mentioned above will always be performed following FIFO strategy, meaning the earlier you request your Runnable to be performed in EDT the earlier it will proceed.

How to debug my UI?

Unlike base Swing framework WebLaF allows you to force EDT usage for all of the UI elements. It helps you to find out where exactly you are performing UI-related operations outside of EDT as it will throw exceptions whenever such operation occurs.

You can read more about this setting in this article: Forced EDT usage

If you are only starting with Swing - I strongly recommend enabling this option, at least for development time. It will help you avoid most common mistakes developers do when working with Swing UI.