调用事件派发线程

时间:2013-05-01 22:48:29

标签: java swing

我有一个扩展JFrame的主类。

我向这个框架实例添加了面板,它包含JTable和其他Swing组件。

在“ public static void main ”的主要课程中,我设置了swing事件派发线程。

我将面板添加到此实例框架,然后启动:

this.setTitle("Test");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);

等...

一切都很好。

现在,对于JTable,它有一个监听器,当单击一行时,它会打开一个InfoDialog类的新实例。

在这个InfoDialog中,我像往常一样添加Swing组件。

我在JDialog中有另一个调度线程,如下所示:

class InfoDialog  {
    JDialog jd;
    public void initGUI() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
                 jd = new JDialog();
            jd.setModalityType(ModalityType.APPLICATION_MODAL);
            jd.setTitle("Buy");
            jd.setDefaultCloseOperation(jd.DISPOSE_ON_CLOSE);
            jd.pack();
            jd.setLocationRelativeTo(null);
    jd.setVisible(true);
    }});
   } 
}

使用事件调度线程解决了我得到的错误(可能是因为它阻止了当前线程),我的问题是,这是正确的方法吗?

感谢您的任何建议。

2 个答案:

答案 0 :(得分:2)

基本上,您应该只在Event Dispatching Thread的上下文中创建对话框(和所有其他UI组件)并与之交互。

您可以(在某种程度上)通过从EventQueue.invokeLater方法调用main来确保这一点。这确保了大部分UI已经在EDT的上下文中被调用。

public static void main(String args[]) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            //...Your UI code here...
        }
    });
}

应该可以安全地假设您在其他所有时间都在EDT内。调用者应该负责确保这一点,而不是您的组件。我经常创建“安全”工厂方法,以便更容易构建一些UI组件(例如进度指示器),这些组件的设计和记录都是线程安全的。

查看Concurrency in SwingInitial Threads了解详情。

答案 1 :(得分:0)

只有一个AWT EDT。 (在Applet和WebStart中可以存在多个,但实际上只有一个。)

您的invokeLater发生的事情是,EventQueue上有一个事件,然后通过initGUI的调用者返回执行,之前排队的事件将被调度,然后是run {1}}方法已执行。

可能你应该将调用转移到代码的initGUI()