簡體   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