Java свинг, как открыть кадр в другом потоке - PullRequest
0 голосов
/ 04 декабря 2018

Мой пользовательский JFrame реализует интерфейс runnable, поэтому он содержит метод run, и в моем основном методе я пытаюсь открыть свой фрейм:

public static void main(String[] args) {

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

К сожалению, это не заставляет фрейм появляться, кажется, игнорирует метод запуска фрейма.

и вот мой класс:

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 голосов
/ 05 декабря 2018

кажется, что он игнорирует метод запуска фрейма

Ну, конечно, так и есть.Вы создали экземпляр анонимного подкласса Thread, чей метод run() не делает ничего, кроме как создает экземпляр Cadre через конструктор по умолчанию.Ничто из этого не приведет к запуску нового метода Cadre run().

Вместо этого вы можете создать экземпляр Thread() через конструктор, который принимает Runnable:

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

... но это кажется довольно бессмысленным.

Имейте в виду, в частности, что сам Swing выполняет всю свою работу в еще одном потоке, "потоке обработки событий", и чтоSwing и стандартные компоненты Swing не являются поточно-ориентированными.

Лучше тогда будет

SwingUtilities.invokeAndWait(new Cadre());

(или invokeLater(new Cadre())), но это вызовет Cadre 's run() метод для запуска в потоке Event-Dispatch, а не в каком-либо другом потоке по вашему выбору.Фактически, это, вероятно, то, что должен сделать, так как рассматриваемый метод создает и отображает графический интерфейс Swing, но это не то, что, как вам кажется, вы хотите сделать .

0 голосов
/ 05 декабря 2018

Вы не должны и не должны.Качели однопоточные И не безопасны.Посмотрите на Параллельность в Swing для получения более подробной информации

"Основная" проблема заключается в том, что вы создаете новый экземпляр Cadre в методе Thread run, но ничеговызывает метод Cadre s 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);
    }
  }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...