我正在尝试学习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,或者在外部调用了它美国东部时间?
如果这是重复的道歉 - 我似乎找不到这个问题的答案。
答案 0 :(得分:2)
您的问题提出了两个关键问题:
应在event dispatch thread(EDT)上构建和操作Swing GUI对象 。这example是典型的,使用EventQueue.invokeLater()
。请特别注意actionPerformed()
的{{1}}方法在EDT上运行。相比之下,您的Timer
似乎在初始主题上实例化,而不是在GUITopLevel
中实例化。
模态对话框将阻止来自同一应用程序的其他窗口的用户输入,但EDT继续运行。在example中,向Runnable
方法添加一个对话框以查看效果。
run()