[英]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.