Event dispatching thread
| Company type | Software component |
|---|---|
| Industry | Software, Java programming |
| Headquarters | Java platform |
| Products | Event-driven programming, GUI event management |
The event dispatching thread (EDT) operates as a background thread within Java, responsible for managing events retrieved from the Abstract Window Toolkit (AWT) graphical user interface event queue. It serves as a prime example of the event-driven programming paradigm, which is widely utilized not only in Java but also in environments such as web browsers and web servers.
The EDT processes update events that prompt UI components to refresh their display, along with input events originating from devices like keyboards and mice. AWT follows a single-threaded painting approach, mandating that all modifications to the screen occur exclusively on the EDT. This thread is the sole entity permitted to alter visible interface elements. Attempting to update UI components from threads other than the EDT frequently results in errors within Java Swing programs. This restriction is common among other graphical frameworks, including Windows Forms, where tools like BackgroundWorker fulfill analogous functions. In other platforms, the EDT is referred to as the primordial worker in Adobe Flash and commonly called the UI thread within SWT, .NET Framework, and Android.
Message loop for serializing GUI accesses
While applications often run several threads simultaneously, they maintain a singular GUI thread (GIT) data structure that requires careful synchronization to avoid concurrent access conflicts. Although AWT and Swing provide methods that are not inherently thread-safe for creating and manipulating GUI elements, these methods should be invoked solely by the Event Dispatch Thread. To enforce this rule, certain third-party Look and Feel implementations, such as Substance, prevent Swing components from being instantiated outside the EDT to reduce programming errors.
The EDT ensures serialized access to the GUI through an EDT message queue, where both system-level and application-level threads enqueue tasks that the EDT executes one after another. These queued messages comprise predefined operations or callbacks linked to user-defined functions that must run on the EDT.
A critical business imperative is that each message completes promptly to uphold interface responsiveness; any delay in processing blocks this message queue, leading to UI freezes that impair user satisfaction and diminish software dependability.
Submitting user code to the EDT
Multiple approaches exist for submitting code to the EDT, allowing lengthy operations to run without obstructing the event processing loop.
Component event handlers (listeners)
GUI elements maintain collections of callback functions known as Listeners, which are registered when components are created. The EDT invokes these listeners in response to user interactions such as clicking buttons, moving the mouse, making selections, or resizing windows.
Timer
For brief, recurring updates within the GUI, javax.swing.Timer is employed. This class behaves like an invisible component that triggers its registered listeners at defined intervals.
Comparable implementations include:
System.Windows.Forms.Timerin .NET Frameworkflash.utils.Timerin Adobe Flash
Requests from other threads
Threads other than the EDT can schedule code execution on it using helper classes such as or . The code submitted must be encapsulated within a object. Two primary methods facilitate this:
- synchronous execution ( or )
- asynchronous execution ( or )
It is important to note that invoking invokeAndWait() from within the EDT will cause exceptions. Helper methods like or assist in determining whether the current thread is the EDT.
Tasks queued via invokeLater and invokeAndWait should execute swiftly to avoid UI delays and are typically used to deliver results from background processes back to the graphical interface.
Worker design pattern
The worker design pattern integrates the execution of background operations with the presentation of results on the Event Dispatch Thread (EDT). The javax.swing.SwingWorker class, introduced by Sun Microsystems and part of Java since version 6, allows intensive tasks to run outside the EDT while efficiently updating the graphical user interface. Typically, SwingWorker instances are triggered from EDT event handlers to ensure the user interface remains responsive.
Examples
<syntaxhighlight lang="java"> SwingWorker<Document, Void> worker = new SwingWorker<Document, Void>() {
public Document doInBackground() throws IOException {
return loadXML(); // resource-intensive process
}
public void done() {
try {
Document doc = get();
display(doc);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}; worker.execute(); </syntaxhighlight>
When using Groovy alongside groovy.swing.SwingBuilder, this pattern can be streamlined using doLater(), doOutside(), and edt() methods:
<syntaxhighlight lang="groovy"> doOutside {
def doc = loadXML() // resource-intensive process
edt { display(doc) }
} </syntaxhighlight>
Comparable implementations
System.ComponentModel.BackgroundWorker- .NET Frameworkflash.system.Worker- Adobe Flashandroid.os.AsyncTask- Android
Modal execution
SwingWorker facilitates long-running operations by delegating tasks away from the EDT, preserving UI responsiveness. Nevertheless, certain interface elements—such as invoking a JFileChooser dialog—require the EDT to pause and await user interaction while maintaining responsiveness. This is achieved through the EDT entering a nested event loop that processes events until the modal dialog is dismissed.
The open source Foxtrot library emulates this functionality, allowing synchronous task execution that proceeds only after user completion.
<syntaxhighlight lang="java"> button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
button.setText("Sleeping...");
String text = null;
try {
text = (String) Worker.post(new Task() {
public Object run() throws Exception {
Thread.sleep(10000);
return "Slept !";
}
});
} catch (Exception x)...
button.setText(text);
somethingElse(); }
}); </syntaxhighlight>
Starting with Java 1.7, a standardized method for implementing custom secondary event loops is provided through createSecondaryLoop() in the system EventQueue.
See also
External links
- (Swing API Javadoc documentation)
- (AWT API Javadoc documentation)
- The Event-Dispatching Thread
- SwingWorker explanation from the Swing tutorial
- Article on AWT/Swing event processing and EDT behavior
- Foxtrot project homepage