在Swing-land中,从静态main方法中调用SwingUtilities.invokeLater(Runnable)
似乎是一种常见/良好的做法:
public class MyApp extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
void run() {
// What to do here?!?
}
});
// And what to do here?!?
}
}
根据该方法的JavaDocs:
导致doRun.run()在AWT事件派发线程上异步执行。这将在处理完所有挂起的AWT事件后发生。当应用程序线程需要更新GUI时,应使用此方法。在下面的示例中,invokeLater调用在事件派发线程上对Runnable对象doHelloWorld进行排队,然后打印一条消息。
但即使在阅读完这篇文章后,我仍然感到困惑的是({em>具体)代码放在这个Runnable
中(我们传递给invokeLater
) ,以及不放入其中的代码。有什么想法吗?
答案 0 :(得分:2)
我认为camickr基本上已经回答了核心问题
进行(主要)重新迭代,进入可能改变UI或以某种方式直接或间接与UI交互的任何内容,外部可以进行任何其他操作,尤其是任何阻塞或长时间运行的代码
如果你看过我的任何Swing相关答案,你会看到这种模板(是的,它是我在Netbeans中设置的代码模板)
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
你可以举几个具体的例子吗?
如果它可能会以任何方式改变UI(直接或间接地 - 更改组件的属性,更新布局等)。一般的经验法则是,任何基于Swing的组件都不是线程安全的,你不应该有任何问题,开始第二次猜测这个规则,你会遇到麻烦,也许不是今天,但很可能明天。
问题是,当组件可能触发对EDT的更新时,API几乎没有保证,这正是您真正关心的问题。如有疑问,请加入EDT。
API中很少有被认为是线程安全的方法,repaint
是最明显的,但就个人而言,我只是将整个API视为不是线程安全的,它节省了大量的猜测。
如果您知道有长时间运行或可能阻塞的操作(文件IO,网络呼叫等等),那么这些操作需要在EDT之外进行(可能使用SwingWorker
或Swing {{ 1}}视情况而定),但是当您想要更新UI(例如更改标签文本或更新进度条)时,这些调用必须在EDT的上下文中进行。
首先仔细看看Concurrency in Swing
答案 1 :(得分:0)
对于未来的人来说,我想出来了,尽管文档并没有以一种对Swing新手来说显而易见的方式来解释这一点:
javax.swing.*
下的Swing类的任何操作”。因此,使用JFrame
,JPanel
或任何JComponents
执行任何操作。所有这些内容都应该在您从应用的Runnable
方法内传递到SwingUtilities.invokeLater
的{{1}}内执行。所以基本上你最终会得到一个巨大的,整体的main
来完成所有的UI代码操作。奇怪和反MVC恕我直言。Runnable