Java swing如何在另一个线程中打开框架
我的自定义JFrame实现了runnable接口,因此它包含run方法,在我的main方法中,我尝试打开我的框架:
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
Cadre cadre = new Cadre();
}
}.start();
}
不幸的是,这并没有使帧出现,它似乎忽略了帧的run方法
这是我的课:
public class Cadre extends JFrame implements Runnable {
private PanneauHaut panneauHaut;
private PanneauBas panneauBas;
@Override
public void run() {
System.out.println("Thread started");
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setExtendedState(JFrame.MAXIMIZED_BOTH);
this.panneauHaut = new PanneauHaut();
this.panneauBas = new PanneauBas();
JPanel mainPanel = new JPanel();
JTextField kooltxt = new JTextField("hehehe");
mainPanel.setLayout(new BorderLayout());
mainPanel.add(panneauHaut, BorderLayout.NORTH);
mainPanel.add(panneauBas.getPanel(), BorderLayout.SOUTH);
this.setContentPane(mainPanel);
this.setVisible(true);
}
}
有什么不对劲吗
# 1 楼答案
你不能也不应该。Swing是单线程的,不安全。查看Concurrency in Swing了解更多详细信息
“主要”问题是,您正在
Thread
的run
方法中创建一个新实例Cadre
,但没有任何东西调用Cadre
srun
方法哪里叫
Cadre#run
“更好”的解决方案是做一些更像
EventQueue.invokeLater(new Cadre())
的事情,它将在事件调度线程的上下文中安全地执行Cadre
的run
方法对我来说效果很好——任何额外的问题都可能是你没有提供的代码中的其他地方,或者你需要进行清理和构建,以清除任何“过时”的二进制文件
# 2 楼答案
当然了。您已经实例化了
Thread
的一个匿名子类,其run()
方法只通过其默认构造函数实例化Cadre
。没有任何东西会导致新的Cadre
的run()
方法运行您可以通过接受
Runnable
的构造函数实例化股票Thread()
:。。。但这似乎毫无意义
请特别注意,Swing本身在另一个线程“事件调度线程”中完成所有工作,Swing和标准Swing组件不是线程安全的
那就更好了
(或
invokeLater(new Cadre())
),但这将导致Cadre
的run()
方法在事件调度线程上运行,而不是在您选择的其他随机线程上运行。事实上,这可能是您应该做的事情,因为所讨论的方法构造并显示了一个Swing GUI,但这并不是您似乎认为您想要做的事情