简体   繁体   中英

Java swing how to open frame in another thread

My custom JFrame implements runnable interface, so it contains the run method, and in my main method, this is how I try to open my frame:

public static void main(String[] args) {

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

Unfortunately this done not make the frame appear, it seems to ignore the frame's run method.

and here's my class:

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);
    }
}

What could be wrong?

You don't and you shouldn't. Swing is single threaded AND not thread safe. Look at Concurrency in Swing for more details

The "major" problem is, you are creating a new instance Cadre in the Thread 's run method, but nothing is calling the Cadre s run method...

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

Where is Cadre#run called?

A "better" solution would be to do something more like EventQueue.invokeLater(new Cadre()) , which will execute the Cadre 's run method within the context of the Event Dispatching Thread - safely

Nothing happens with invokeLater

Works fine for me - any additional problems are likely some where else in the code you've not provided, that or you need to do a clean and build to flush out any "stale" binaries.

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);
    }
  }

}

it seems to ignore the frame's run method

Well of course it does. You have instantiated an anonymous subclass of Thread whose run() method does nothing but instantiate a Cadre via its default constructor. Nothing there would cause the new Cadre 's run() method to run.

You could instead instantiate a stock Thread() via the constructor that accepts a Runnable :

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

... but that seems pretty pointless.

Be aware in particular that Swing itself does all its work in yet a different thread, the "Event-Dispatch Thread", and that Swing and standard Swing components are not thread-safe.

Better, then, would be

SwingUtilities.invokeAndWait(new Cadre());

(or invokeLater(new Cadre()) ), but that will cause the Cadre 's run() method to run on the Event-Dispatch thread, not on some random other thread of your choosing. In fact, that's probably what you should do, since the method in question constructs and displays a Swing GUI, but it's not what you seem to think you want to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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