2

我有一个扩展 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);

ETC...

到这里一切都好。

现在,对于 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);
    }});
   } 
}

放置事件调度线程解决了我遇到的错误(可能是因为它预先阻塞了当前线程),我的问题是,这是正确的方法吗?

感谢您的任何建议。

4

2 回答 2

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 组件(例如进度指示器)。

查看SwingInitial Threads中的并发以获取更多详细信息。

于 2013-05-01T23:45:10.157 回答
0

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

你发生的事情invokeLater是一个事件被放置在 上EventQueue,然后执行通过调用者返回initGUI,先前排队的事件被调度,然后你的run方法被执行。

可能您应该将调用移动到initGUI()代码的下方。

于 2013-05-01T23:18:43.783 回答