Java Tutorial/Intermediate GUIs/Why is Swing single-threaded?

Swing is single-threaded because the designers had no need for multi-threading and only to use one thread made the design simpler (so complexity and performance could be wasted in other places).

Of course the class SwingUtilities does offer invokeLater () and invokeAndWait (), which can be used to communicate with the Swing user interface from other threads. Computationally intensive tasks should always be performed on other threads to allow the user interface to remain responsive.

Some operating systems (for instance QNX, Haiku or Mach) intensively use messages for the communication between processes. If you would prefer a more message-oriented design, that can easily be retrofitted to Swing: Just implement the following interface and you can send messages. One should remember, however, not to make any calls into Swing components that weren't designed to be multi-threaded from other threads than the Swing thread. For your own components, however, there is no such limitation as long as you remember to use the synchronize keyword where it is required.

A MessagePort can easily send messages to the Swing thread by wrapping a call to invokeLater () with a Runnable that knows what to do with the message. Of course other threads can also receive messages, which makes the design more consistent; your own Swing components can, of course, also send messages internally to cause computation on the Swing thread, when called from another thread.

package org.wikiversity.java_tutorial;

public interface MessagePort
{
    public interface Message { /* tagging interface */ }

    public void putMessage (Message msg);
    public Message getMessage ();
    public boolean isBlocking ();
    /**
     * set the blocking/non-blocking flag for message retrieval thru getMessage ()
     */
    public void setBlocking (boolean flag);
    public String getName ();
    /**
     * remove the messageport from the lookup table or any other registry or advertisement mechanism.
     */
    public void close ();
}