Java Layout не отображает компоненты (иногда)

Я пишу MathQuiz для своих учеников, включая JLatexMath для рендеринга и jinput для зуммеров. Проблема в том, что иногда (каждый четвертый раз) при запуске программы ни один из компонентов не виден. Они появляются после изменения размера JFrame. Сначала я думал об ошибках в библиотеках jinput или jlatexMath, но я получаю ту же ошибку даже с этим минимальным кодом:

public class Shell extends JFrame{

  private JButton button1;
  private JButton button2;
  private Formula formula;

  public Shell() {
    super("blaBla");
    this.setSize(800, 600);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
    this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));
    Box b = Box.createHorizontalBox();
    button1 = new JButton(" ");
    button1.setEnabled(false);
    b.add(button1);
    b.add(Box.createHorizontalGlue());
    button2 = new JButton(" ");
    button2.setEnabled(false);
    b.add(button2);
    add(b);
    JPanel formulaPanel = new JPanel();
    add(Box.createVerticalStrut(20));
    add(formulaPanel);
  } 

  public static void main(String[] args) {
    Shell s = new Shell();
  }
}

Что не так с кодом?


person user3648884    schedule 31.10.2014    source источник
comment
Что ж, если у вас есть странные проблемы с Swing, лучше прислушаться к документации и убедиться, что все Swing-код выполняется в потоке отправки событий. Начните с него.   -  person markspace    schedule 31.10.2014
comment
Хорошо, спасибо за быстрый ответ. Когда я добавляю System.out.println(javax.swing.SwingUtilities.isEventDispatchThread()); в конструктор я получаю false на консоли. Как я могу сделать свой поток EventDispatchThread?   -  person user3648884    schedule 31.10.2014
comment
Слева от той ссылки, которую я вам дал, есть несколько ссылок. Лучше прочитать ВСЮ документацию, иначе кто знает, что вы пропустили. Попробуйте эту ссылку, но вам нужно прочитать ее целиком раздел о параллелизме в Java. Как минимум.   -  person markspace    schedule 31.10.2014
comment
Да, ссылки я заметил :-) Я уже выяснил, что создание JFrame должно выглядеть так: SwingUtilities.invokeLater(new Runnable() { public void run() { new Shell(); } }); но буду читать...   -  person user3648884    schedule 31.10.2014


Ответы (1)


Начните с перемещения setVisible(true); в конец конструктора.

Вместо того, чтобы быть здесь...

public Shell() {
    super("blaBla");
    this.setSize(800, 600);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
    //...
} 

Переместите сюда...

public Shell() {
    super("blaBla");
    //...
    add(Box.createVerticalStrut(20));
    add(formulaPanel);
    setVisible(true);
} 

Чтобы защититься от любых других возможных графических сбоев, вы всегда должны запускать свой пользовательский интерфейс из потока диспетчеризации событий, см. Начальные темы для получения дополнительной информации.

person MadProgrammer    schedule 31.10.2014
comment
setVisible в конце конструктора пока работает нормально. Спасибо за вашу помощь :-) - person user3648884; 31.10.2014