我正在尝试了解 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);
}
}
当单击菜单项时,将在 Controller 中调用:
public void menuCatch(JMenuItem eventSource) {
JOptionPane.showMessageDialog(gui.topLevelFrame, eventSource.getActionCommand());
}
由于 gui
是 JOptionPane 的父容器,并且是使用 invokeLater
创建的,这是否意味着新生成的 JOptionPane 已在 EDT 上调用或者它是否在 EDT 之外被调用?
如果这是重复的,我深表歉意 - 我似乎找不到这个问题的答案。
最佳答案
您的问题提出了两个关键问题:
Swing GUI 对象应该仅在 event dispatch thread 上构建和操作。 (美东时间)。这个example典型的是使用
EventQueue.invokeLater()
。请特别注意,Timer
的actionPerformed()
方法在 EDT 上运行。相反,您的GUITopLevel
似乎是在初始线程上实例化的,而不是在Runnable
中实例化的。模式对话框将阻止用户从同一应用程序的其他窗口进行输入,但 EDT 会继续运行。在 example ,在
run()
方法中添加一个对话框来查看效果。public void run() { ... f.setVisible(true); JOptionPane.showMessageDialog(dt, TITLE); }
关于Java EDT 和生成对话,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15990048/