java使用SwingUtilities。main方法中的invokeLater()
我最近看到一个MVC java应用程序,其中的主要方法是:
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
View view = new View();
Model model = new Model();
Controller controller = new Controller(view, model);
controller.start();
}
});
}
这难道不会让所有程序(包括模型和控制器,它们与Swing完全无关)一直运行,直到代码在AWT事件调度线程而不是主线程中结束吗
如果最后一个是真的,那么这对应用程序来说真的很糟糕,因为它会阻止EDT执行它需要执行的任务(例如,调度事件,因为模型可能正在计算其他任务)。对吗
有一个类似的old post(不是这个代码的副本)可以表明上面提到的代码是良好的实践,所以它让我更加困惑
# 1 楼答案
您展示的代码片段的目的是创建Swing UI和模型,并将它们连接在一起
没有Swing更新(就对用户输入的反应而言),因为在
run()
方法结束之前不能有任何用户输入虽然可以在主线程和EDT之间拆分这些任务(在UI首次显示之前可能会增加几毫秒),但这也会使应用程序的设计复杂化(多线程不是一个容易的主题),并在代码库中乱放
invokeLater()
调用。除非有人证明这是必要的,否则我不会这么做IMHO EDT是任何GUI应用程序中的主线程。对用户输入的每一个反应都在这个线程中开始,用户界面的每一次更新都必须在这个线程中完成
长时间运行的任务应该在后台线程中完成——这通常意味着任何需要几毫秒以上时间的任务
如果创建模型需要几秒钟怎么办
在这种情况下,我会尝试将模型创建分为两部分:
如果无法做到这一点怎么办(即,在模型完全初始化之前,无法显示UI)
在这种情况下,用户必须等待模型的完全初始化,然后才能查看和使用UI。因此,无论这个初始化是在EDT上运行还是在主线程上运行,都无关紧要。因此,使用更简单的解决方案:EDT上的所有内容
但是给用户一些提示,你的应用程序是通过显示splash screen来启动的