2

我正在尝试学习 Swing 的复杂性,并阅读了大量有关事件调度​​线程的内容。我明白这是为了什么,但是我正在努力解决以下概念:

我有一个以正常方式调用的 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);
}
}

当一个菜单项被点击时,这在控制器中被调用:

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

guiJOptionPane 的父容器一样,并且已使用invokeLater.

抱歉,如果这是重复的 - 我似乎无法找到这个问题的答案。

4

1 回答 1

2

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

  • Swing GUI 对象应事件分派线程(EDT) 上构建和操作。这个例子是典型的,使用EventQueue.invokeLater(). 特别注意在EDT 上运行的actionPerformed()方法。Timer相反,您GUITopLevel似乎是在初始线程上实例化的,而不是在您的Runnable.

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

    public void run() {
        ...
        f.setVisible(true);
        JOptionPane.showMessageDialog(dt, TITLE);
    }
    

另请参阅此Q&A和此Q&A on MVC in Swing。

于 2013-04-13T18:55:06.920 回答