Java Swing如何在另一个线程中打开框架

时间:2018-12-04 20:47:56

标签: java swing

我的自定义JFrame实现了可运行的接口,因此它包含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);
    }
}

怎么了?

2 个答案:

答案 0 :(得分:2)

您不应该,也不应该。摆动是单线程的,并且不是线程安全的。查看Concurrency in Swing了解更多详细信息

“主要”问题是,您正在Cadre的{​​{1}}方法中创建新实例Thread,但是没有调用run s {{ 1}}方法...

Cadre

run在哪里叫?

“更好”的解决方案是做类似new Thread() { @Override public void run() { Cadre cadre = new Cadre(); } }.start(); 的事情,它将在事件分发线程的上下文中安全地执行Cadre#run的{​​{1}}方法

  

invokeLater不会发生任何事情

对我来说很好-任何其他问题都可能在您未提供的代码中的其他地方出现,或者您需要清理并构建以清除任何“陈旧”的二进制文件。

EventQueue.invokeLater(new Cadre())

答案 1 :(得分:1)

  

似乎忽略了框架的运行方法

当然可以。您已经实例化了Thread的匿名子类,该子类的run()方法只通过其默认构造函数实例化了Cadre。没有什么会导致新的 Cadre run()方法运行。

您可以改为通过接受Thread()的构造函数实例化股票Runnable

new Thread(new Cadre()).start();

...但是那似乎毫无意义。

尤其要注意,Swing本身是在另一个线程(“事件调度线程”)中完成所有工作的,并且Swing和标准Swing组件也不是线程安全的。

那就更好了

SwingUtilities.invokeAndWait(new Cadre());

(或invokeLater(new Cadre())),但这将导致Cadre的{​​{1}}方法在Event-Dispatch线程上运行,而不是在您选择的某个随机其他线程上运行。实际上,这可能是您应该要做的,因为所讨论的方法会构造并显示一个Swing GUI,但这似乎并不是您想想要要做的。 / p>