回答您在一些现有答案的 cmets 中询问的关于需要检查 EventQueue.isDispatchThread() 的问题:
不,您不必在致电invokeLater() 之前检查您是否已经在 EDT。
SwingUtilities JavaDoc 声明:
如果从事件分派线程调用 invokeLater ——例如,从 JButton 的 ActionListener —— doRun.run() 仍将被延迟,直到所有未决事件都已处理完毕。请注意,如果 doRun.run() 抛出未捕获的异常,则事件调度线程将展开(而不是当前线程)。
下面是对invokeLater()使用的进一步解释。
注意ButtonDemo.java 中的 createAndShowGUI() 是使用 invokeLater() 调用的。我们必须这样做,因为 main() 方法没有在 EDT(事件调度线程)上运行。 main() 运行在每个 Java 应用程序都有的自己的特殊主线程上。
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
但是在actionPerformed() 中,没有使用invokeLater() 方法,因为这里我们已经在EDT。
//b1, b2, and b3 are all JButtons
public void actionPerformed(ActionEvent e) {
if ("disable".equals(e.getActionCommand())) {
b2.setEnabled(false);
b1.setEnabled(false);
b3.setEnabled(true);
} else {
b2.setEnabled(true);
b1.setEnabled(true);
b3.setEnabled(false);
}
}
据我所知,actionPerformed() 等事件侦听器方法总是从 EDT 调用。 (抱歉,我不知道手头的支持文档,而且我还没有足够的声誉来发布更多链接。除了阅读 camickr 答案中链接的页面外,请尝试 Google 搜索“java tutorial swing introduction event listeners” .)
因此,如果您尝试从 EDT 以外的线程更新 Swing 组件,请调用 invokeLater()。如果您在事件侦听器方法中(即已经在 EDT 上),则无需调用 invokeLater()。