在阅读this question后,我决定执行在我的应用程序中在事件调度线程(EDT)上显示消息对话框的代码。
为此,我修改了显示消息对话框的方法:
private static void showMessage(final Component parent,
final String message,
final String title,
final int type) {
System.out.println("Before dialog.");
JOptionPane.showMessageDialog(parent, message, title, type);
System.out.println("After dialog.");
}
为:
private static void showMessage(final Component parent,
final String message,
final String title,
final int type) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("Before dialog.");
JOptionPane.showMessageDialog(parent, message, title, type);
System.out.println("After dialog.");
}
});
}
然而,我很惊讶地发现这一变化后行为发生了显着变化。在我修改上述方法以在EDT上运行之前,它会打印"Before dialog"
,然后显示对话框 - 阻塞直到它关闭 - 然后打印"After dialog"
。这是预期的行为。修改方法后,我发现打印了"Before dialog"
,对话框短暂出现(基本上闪烁),然后打印"After dialog"
。
在EDT上执行时,JOptionPane.showMessageDialog(...)
调用似乎停止阻止。是什么给予了什么?
我怀疑它可能与我的应用程序关闭代码有关。我在应用程序开始关闭之前显示一条消息,通知用户有关严重错误的信息。但是,在我的shutdown
方法中,我确保它也在EDT上执行:
public static synchronized void shutdown() {
if (userShutdown) {
return;
}
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
shutdown();
}
});
return;
}
userShutdown = true;
System.out.println("Shutting down...");
// ...
}
如果我对事件队列的理解是正确的,因为我在showMessage
之前调用了shutdown
,那么EDT上的shutdown
调用应该在之后执行 >消息对话框关闭(因为它应该在对话框关闭之前阻止),因此shutdown
中的代码不应该影响showMessage
的行为。