繁体   English   中英

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

[英]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中的并发。

“主要”问题是,您正在Threadrun方法中创建一个新的实例Cadre ,但没有调用Cadrerun方法。

new Thread() {
    @Override
    public void run() {
        Cadre cadre = new Cadre();
    }
}.start();

Cadre#run在哪里叫?

一种“更好”的解决方案是做更多类似EventQueue.invokeLater(new Cadre())事情,该事件将在事件调度线程的上下文中安全地执行Cadrerun方法。

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()) ),但这将导致Cadrerun()方法在Event-Dispatch线程上运行,而不是在您选择的某个随机其他线程上运行。 实际上,这可能是您应该做的,因为所讨论的方法会构造并显示Swing GUI,但您似乎并不是这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM