我的应用程序的主 JFrame 上有一个窗口监听器。我还在应用程序内的按钮上有一个按钮监听器。我用它作为按钮监听器的模式:
good.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
// We're going to do something that takes a long time, so we
// spin off a thread and update the display when we're done.
Thread worker = new Thread() {
public void run() {
// Report the result using invokeLater().
SwingUtilities.invokeLater(new Runnable() {
public void run() {
for(int i=0; i<1000000; i++){
System.out.println("foo");
}
}
});
}
};
worker.start(); // So we don't hold up the dispatch thread.
}
});
当我单击按钮时,我会看到每次迭代的打印输出,但直到循环执行完毕后才会触发窗口监听器。 print 'foo' 只是用来模拟需要一段时间的事情,我希望在窗口事件发生时立即触发监听器(可能是在 run() 方法执行中间的某个位置),但它似乎直到 for 循环结束才触发它。
知道为什么吗?
最佳答案
Swing 是单线程的 - Event Dispatch Thread (EDT) 管理 Swing 的绘画和 Activity 。放置在 EDT 上的任何长时间运行的任务都将阻止 EDT 执行任务,直到长时间运行的任务完成为止(换句话说,UI 看起来像是已锁定)。在这里,您的代码使用 SwingUtilities
将长时间运行的进程(for
循环)分派(dispatch)到 EDT - 如果您有一个长时间运行的任务并且希望在此过程中获得响应式 Swing UI ,然后将长时间运行的任务放入其自己的 Thread 中,或使用 SwingWorker 。
关于java - Swing 窗口监听器线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30111071/