Java EDT和产卵对话

时间:2013-04-13 16:24:44

标签: java swing model-view-controller joptionpane event-dispatch-thread

我正在尝试学习Swing的复杂性,并且已经阅读了很多有关Event Dispatch Thread的内容。我理解的是什么,但是我正在努力解决以下概念:

我有一个以正常方式调用的JFrame:

public class Controller {
GUITopLevel gui = new GUITopLevel(this);

public void initiate() {        
    SwingUtilities.invokeLater(
            new Runnable() {
                @Override
                public void run() {
                    gui.init();
                }
            }
    );
}

public void menuCatch(JMenuItem eventSource) {
    JOptionPane.showMessageDialog(gui.topLevelFrame, eventSource.getActionCommand());
}
}

我想从gui生成JDialogs(代码因此):

public class GUITopLevel implements FrontOfHouse {    
JFrame topLevelFrame;

Controller control;

GUITopLevel(Controller c) {
    control = c;
}

@Override
public void GUI() {        
    // Create an action
    MenuAction action = new MenuAction(control);

    // Create the Frame
    topLevelFrame = new JFrame();

    // Create the menu bar
    JMenuBar menuBar = new JMenuBar();
    JMenu file = new JMenu("File");
    JMenu edit = new JMenu("Edit");

    JMenuItem file1 = new JMenuItem();
    JMenuItem file2 = new JMenuItem();
    JMenuItem file3 = new JMenuItem();

    JMenuItem edit1 = new JMenuItem();

    // Set the actions
    file1.setAction(action);
    file2.setAction(action);
    file3.setAction(action);
    edit1.setAction(action);

    // Add the menu items
    file.add(file1);
    file.add(file2);
    file.add(file3);

    edit.add(edit1);

    // Set the text
    file1.setText("Import Diagrams");
    file2.setText("Settings");
    file3.setText("Exit");
    edit1.setText("Cut");
    // Add the menus together
    menuBar.add(file);
    menuBar.add(edit);

    // Set size and add menu bar
    topLevelFrame.setSize(600,400);
    topLevelFrame.setJMenuBar(menuBar);

    topLevelFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

@Override
public void init() {
    GUI();
    //topLevelFrame.pack();
    topLevelFrame.setVisible(true);
}
}

单击menuitem时,会在控制器中调用它:

public void menuCatch(JMenuItem eventSource) {
    JOptionPane.showMessageDialog(gui.topLevelFrame, eventSource.getActionCommand());
 }

由于gui是JOptionPane的父容器,而且是用invokeLater创建的,这是否意味着在EDT上调用了新生成的JOptionPane,或者在外部调用了它美国东部时间?

如果这是重复的道歉 - 我似乎找不到这个问题的答案。

1 个答案:

答案 0 :(得分:2)

您的问题提出了两个关键问题:

  • 应在event dispatch thread(EDT)上构建和操作Swing GUI对象 。这example是典型的,使用EventQueue.invokeLater()。请特别注意actionPerformed()的{​​{1}}方法在EDT上运行。相比之下,您的Timer似乎在初始主题上实例化,而不是在GUITopLevel中实例化。

  • 模态对话框将阻止来自同一应用程序的其他窗口的用户输入,但EDT继续运行。在example中,向Runnable方法添加一个对话框以查看效果。

    run()

参见Swing中的MVC上的Q&AQ&A