[英]Java swing how to open frame in another thread
我的自定义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);
}
}
有什么事吗
你不应该,也不应该。 摆动是单线程的,并且不是线程安全的。 有关更多详细信息,请参见Swing中的并发。
“主要”问题是,您正在Thread
的run
方法中创建一个新的实例Cadre
,但没有调用Cadre
的run
方法。
new Thread() {
@Override
public void run() {
Cadre cadre = new Cadre();
}
}.start();
Cadre#run
在哪里叫?
一种“更好”的解决方案是做更多类似EventQueue.invokeLater(new Cadre())
事情,该事件将在事件调度线程的上下文中安全地执行Cadre
的run
方法。
invokeLater没有任何反应
对我来说很好用-任何其他问题都可能在您未提供的代码中的其他地方出现,或者您需要清理并构建以清除任何“陈旧”的二进制文件。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class Test {
public static void main(String[] args) {
EventQueue.invokeLater(new Cadre());
}
public static 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(kooltxt);
// mainPanel.add(panneauHaut, BorderLayout.NORTH);
// mainPanel.add(panneauBas.getPanel(), BorderLayout.SOUTH);
this.setContentPane(mainPanel);
pack();
setLocationRelativeTo(null);
this.setVisible(true);
}
}
}
似乎忽略了框架的运行方法
当然可以。 您已经实例化了Thread
的一个匿名子类,该子类的run()
方法只通过其默认构造函数实例化了Cadre
。 什么都不会导致新Cadre
的 run()
方法运行。
您可以改为通过接受Runnable
的构造函数实例化一个库存Thread()
:
new Thread(new Cadre()).start();
...但这似乎毫无意义。
特别要注意,Swing本身在不同的线程(“事件分发线程”)中完成所有工作,并且Swing和标准Swing组件不是线程安全的。
更好的是
SwingUtilities.invokeAndWait(new Cadre());
(或invokeLater(new Cadre())
),但这将导致Cadre
的run()
方法在Event-Dispatch线程上运行,而不是在您选择的某个随机其他线程上运行。 实际上,这可能是您应该做的,因为所讨论的方法会构造并显示Swing GUI,但您似乎并不是想这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.