After Swing components have been displayed on the screen, they should only be operated on by the event-handling thread. The event-handling thread (or just event thread) is started automatically by the Java VM when an application has a graphical interface. The event thread calls methods like paint() on Component, actionPerformed() on ActionListener, and all of the other event-handling methods.

Most of the time, modifications to Swing components are done in the event-handling methods. Because the event thread calls these methods, it is perfectly safe to directly change components in event-handling code. SimpleEvent (see below simple code) shows safe Swing code.  

SimpleEvent.java—Multithread-Safe Swing Code That Uses the Event Thread

1: import java.awt.*;
2: import java.awt.event.*;
3: import javax.swing.*;

5: public class SimpleEvent extends Object {
6:Â Â Â Â  private static void print(String msg) {
7:Â Â Â Â Â Â Â Â  String name = Thread.currentThread().getName();
8:         System.out.println(name + “: “ + msg);
9:Â Â Â Â  }
10:
11:Â Â Â Â  public static void main(String[] args) {
12:         final JLabel label = new JLabel(“————”);
13:         JButton button = new JButton(“Click Here”);
14:
15:Â Â Â Â Â Â Â Â  JPanel panel = new JPanel(new FlowLayout());
16:Â Â Â Â Â Â Â Â  panel.add(button);
17:Â Â Â Â Â Â Â Â  panel.add(label);
18:
19:Â Â Â Â Â Â Â Â  button.addActionListener(new ActionListener() {
20:Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  public void actionPerformed(ActionEvent e) {
21:                     print(“in actionPerformed()”);
22:                     label.setText(“CLICKED!”);
23:Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  }
24:Â Â Â Â Â Â Â Â Â Â Â Â  });
25:
26:         JFrame f = new JFrame(“SimpleEvent”);
27:Â Â Â Â Â Â Â Â  f.setContentPane(panel);
28:Â Â Â Â Â Â Â Â  f.setSize(300, 100);
29:Â Â Â Â Â Â Â Â  f.setVisible(true);
30:Â Â Â Â  }
31: }

In SimpleEvent, two threads interact with the Swing components. First, the main thread creates the components (lines 12–15), adds them to panel (lines 16–17), and creates and configures a JFrame (lines 26–29). After setVisible() is invoked by main (line 29), it is no longer safe for any thread other than the event thread to make changes to the components.

When the button is clicked, the event thread invokes the actionPerformed() method (lines 20–23). In there, it prints a message to show which thread is running the code (line 21) and changes the text for label (line 22). This code is perfectly safe because it is the event thread that ends up calling setText().

When SimpleEvent is run, the frame appears and the following output is printed to the console when the button is clicked:

AWT-EventQueue-0: in actionPerformed()

The thread named AWT-EventQueue-0 is the event thread. This is the thread that can safely make changes through methods like setText().

One of the goals for the developers of Swing was to make the toolkit as fast as possible. If the components had to be multithread-safe, there would need to be a lot of synchronized statements and methods. The extra overhead incurred acquiring and releasing locks all the time would have slowed the performance of the components. The developers made the choice for speed over safety. As a result, you need to be very careful when making modifications to Swing components that are initiated outside the event thread.