Q: When exactly is the EDT started? What line of code is responsible [f]of it?
The inner workings of Swing are JVM-specific. Different JVMs start the Event Dispatch Thread (EDT) based on differing criteria. In general though:
The EDT starts when it receives its first AWTEvent
.
The stack traces below reaffirm this point. Take for example the following main
method.
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setVisible(true);
}
In the example above, the line of code responsible for starting the EDT is frame.setVisible(true);
The above main
method was executed on two different JVMs. A breakpoint was placed at EventQueue.initDispatchThread
. When the breakpoint was hit, the following stack traces were noted.
Using the Mac's JDK on the AWT-AppKit
thread:
EventQueue.initDispatchThread() line: 906
EventQueue.wakeup(boolean) line: 1109
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
Method.invoke(Object, Object...) line: 597
SunToolkit.wakeupEventQueue(EventQueue, boolean) line: 348
PostEventQueue.postEvent(AWTEvent) line: 2137
SunToolkit.postEvent(AppContext, AWTEvent) line: 583
SunToolkit.executeOnEventHandlerThread(PeerEvent) line: 654
SunToolkit.executeOnEventHandlerThread(Object, Runnable) line: 631
EventFactoryProxy.windowMoved(CWindow) line: 89
Using Oracle's JDK for Windows on the main
thread:
java.awt.EventQueue.initDispatchThread() line: 861
java.awt.EventQueue.postEventPrivate(java.awt.AWTEvent) line: 199
java.awt.EventQueue.postEvent(java.awt.AWTEvent) line: 180
javax.swing.RepaintManager.scheduleProcessingRunnable(sun.awt.AppContext) line: 1369
javax.swing.RepaintManager.nativeAddDirtyRegion(sun.awt.AppContext, java.awt.Container, int, int, int, int) line: 548
javax.swing.SwingPaintEventDispatcher.createPaintEvent(java.awt.Component, int, int, int, int) line: 45
sun.awt.windows.WFramePeer(sun.awt.windows.WComponentPeer).postPaintIfNecessary(int, int, int, int) line: 741
sun.awt.windows.WFramePeer(sun.awt.windows.WComponentPeer).handlePaint(int, int, int, int) line: 736
sun.java2d.d3d.D3DScreenUpdateManager.repaintPeerTarget(sun.awt.windows.WComponentPeer) line: 274
sun.java2d.d3d.D3DScreenUpdateManager.createScreenSurface(sun.awt.Win32GraphicsConfig, sun.awt.windows.WComponentPeer, int, boolean) line: 175
...
sun.awt.windows.WToolkit.createFrame(java.awt.Frame) line: 383
javax.swing.JFrame(java.awt.Frame).addNotify() line: 460
javax.swing.JFrame(java.awt.Window).show() line: 859
javax.swing.JFrame(java.awt.Component).show(boolean) line: 1584
javax.swing.JFrame(java.awt.Component).setVisible(boolean) line: 1536
javax.swing.JFrame(java.awt.Window).setVisible(boolean) line: 842
Example.main(java.lang.String[]) line: 113
On the Mac, a call to PostEventQueue.postEvent(AWTEvent)
is made. Similarly on Windows, a call to java.awt.EventQueue.postEvent(java.awt.AWTEvent)
is made. Both eventually call EventQueue.initDispatchThread
.
As another example, consider the following main
method:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("Start!");
}
});
}
Using the Mac's JDK on the main
thread:
EventQueue.initDispatchThread() line: 906 [local variables unavailable]
EventQueue.postEventPrivate(AWTEvent) line: 227
EventQueue.postEvent(AWTEvent) line: 208
EventQueue.invokeLater(Runnable) line: 1048
SwingUtilities.invokeLater(Runnable) line: 1267
Example.main(String[]) line: 31
Using Oracle's JDK for Windows on the main
thread:
java.awt.EventQueue.initDispatchThread() line: 861
java.awt.EventQueue.postEventPrivate(java.awt.AWTEvent) line: 199
java.awt.EventQueue.postEvent(java.awt.AWTEvent) line: 180
java.awt.EventQueue.invokeLater(java.lang.Runnable) line: 999
javax.swing.SwingUtilities.invokeLater(java.lang.Runnable) line: 1267
The call to SwingUtilties.invokeLater
is responsible for starting the EDT. Here again, calls to EventQueue.postEvent(AWTEvent)
are made.
Thoughts on 'My guess is that "someSwingComponent.setVisible(true)" does the trick, but I'm not sure.'
Not just any call to someSwingComponent.setVisible(true)
will start the EDT. For example, executing the following main
method does not create the AWT-Event-Queue-0
thread:
public static void main(String[] args) {
JLabel label = new JLabel();
label.setVisible(true);
}
Resources
Of course, there are many resources online about the EDT.