java – 应该从事件调度程序或主线程控制Swing GUI应用程序吗?

我读了几本关于Java的书.在所有这些中,至少有一章教授GUI编程.在所有这些中,创建一个简单的表单应用程序遵循以下逻辑:

MyFrame.java

public class MyFrame extends JFrame
{
    JButton button1;

    public MyFrame()
    {
        button1 = new JButton("Click here.");
    }
}

FrameTest.java:

public class FrameTest
{
    public static void main(String[] args)
    {
        MyFrame myFrame = new MyFrame();

        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setSize(600, 600);
        myFrame.setVisible(true);
    }
}

基本上,只是将JFrame子类化为创建表单并将其他组件声明为实例变量,并在构造函数中初始化这些组件.然后创建另一个测试类,在该类中实例化框架子类并调用它的一些方法使其可见.

但在并发课程中,我了解到我们有一个主线程,它在我们创建的每个应用程序中运行main().据我所知,当我们使用Swing创建GUI应用程序时,我们有另一个线程(Event Dispatcher Thread).因此,如果我没有记错,在每个基于Swing的GUI应用程序中至少有两个线程.这使得每个GUI应用程序都是多线程的.在我读过的一些文章和教程中,它说Swing不支持多线程,因此只应在Event Dispatcher Thread中创建和修改所有GUI组件,否则可能会出现线程干扰和内存不一致错误.

即使在维基百科(http://en.wikipedia.org/wiki/Swing_%28Java%29)中最简单的例子中,它也是通过invokeLater方法制作的.

那么哪一个是真正的方法?我哪里错了?

最佳答案
任何UI / Swing组件的所有交互必须在EDT的上下文中完成

启动应用程序时,在尝试创建/与任何Swing组件交互之前,应确保在EDT中执行.

简单地说,你应该使用类似……

EventQueue.invokeLater(new Runnable() {
    public void run() {
        // Now in the event dispatching thread
    }
});

如果需要运行长时间运行的任务或执行任何阻塞任务,则应在单独的线程中执行它.在大多数情况下,SwingWorker是一个不错的选择,因为它提供了一些简单的机制来将代码重新同步到事件调度线程.

请仔细阅读

> Initial Thread
> Will the real Swing Single Threading Rule please stand up?

所以,简短的回答是,是的,所有基于Swing的代码都应该从EDT的上下文中访问/修改/交互.

转载注明原文:java – 应该从事件调度程序或主线程控制Swing GUI应用程序吗? - 代码日志