我有一个扩展 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);
等等...
到这里一切都很好。
现在,对于 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);
}});
}
}
放置事件调度线程可以解决我遇到的错误(可能是因为它之前阻塞了当前线程),我的问题是,这是正确的方法吗?
感谢您的建议。
最佳答案
基本上,您应该只在事件调度线程的上下文中创建对话框(以及所有其他 UI 组件)并与之交互。
您可以(在某种程度上)通过从 main
方法调用 EventQueue.invokeLater
来确保这一点。这可确保大部分 UI 已在 EDT 上下文中调用。
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
//...Your UI code here...
}
});
}
可以安全地假设您在所有其他时间都处于 EDT 范围内。确保这一点应该是调用者的责任,而不是您的组件。我经常创建“安全”工厂方法,以便更轻松地构造一些 UI 组件(例如进度指示器等),这些组件被设计和记录为线程安全的。
查看Concurrency in Swing和 Initial Threads了解更多详情。
关于java - 调用事件调度线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16327702/