Непоследовательный результат при использовании JWindow - PullRequest
0 голосов
/ 12 июня 2019

Я пишу эту программу для отображения JProgressbar в JWindow. Но запуск этой программы на одной машине без каких-либо изменений каждый раз показывает разные результаты. Большую часть времени он показывает пустой JWindow без чего-либо внутри. В других случаях это показывает, как я ожидаю его появления. Я не знаю, что не так.

Я пытался использовать JFrame. Тогда это работает отлично все время. Но я хочу использовать JWindow.

Вот мой код:

package des;

import javax.swing.*;
import java.awt.*;

public class Test extends JWindow {
    JPanel panel = new JPanel();
    JLabel messageLabel = new JLabel();
    JProgressBar progressBar = new JProgressBar(0, 100);
    Test() {
        setVisible(true);
        setSize(480, 100);
        setLocationRelativeTo(null);//put it in center of screen

        messageLabel.setText("Hello World");
        messageLabel.setAlignmentX(JLabel.CENTER);
        progressBar.setValue(0);

        panel.setLayout(new BorderLayout());
        panel.add(messageLabel, BorderLayout.CENTER);
        panel.add(progressBar, BorderLayout.SOUTH);
        panel.setBackground(Color.cyan);
        add(panel,BorderLayout.CENTER);



    }

    public static void main(String[] args) {
        new Test();
    }
}

Я использую 64-разрядную версию Windows 10 в IntelliJ. Вот моя версия Java:

openjdk version "12.0.1" 2019-04-16
OpenJDK Runtime Environment (build 12.0.1+12)
OpenJDK 64-Bit Server VM (build 12.0.1+12, mixed mode, sharing)

1 Ответ

1 голос
/ 12 июня 2019

Вызов setVisible(true) вызовет поток рассылки событий (EDT). После запуска все пользовательские интерфейсы обновления вызовов должны запускаться внутри EDT, например, позвонив по номеру SwingUtilities.invokeLater().

Существуют некоторые исключения из этого правила, заметно вызывающие обновления пользовательского интерфейса в конструкторах, когда объект не виден (следовательно, не отображается). Как только это становится видимым, такие вызовы должны быть отложены до EDT.

Таким образом, вы должны расположить свой GUI в конструкторе и вызывать setVisible(true) только в конце, как только все будет готово к визуализации.

Как отмечает @camickr, все здания объекта пользовательского интерфейса также должны быть перенесены на EDT. Невыполнение этого требования может привести к неопределенному поведению (т. Е. Оно может работать или не работать, так как оно не указано в JSR)

Относительно почему это не показывалось, я снова цитирую комментарий @ camickr:

Причина, по которой код не работает, заключается в том, что компоненты добавляются после , когда отображается графический интерфейс. По умолчанию компоненты имеют размер по умолчанию (0, 0). Так что красить нечего. Если вы добавляете компоненты в видимый графический интерфейс, вам нужно revalidate() и repaint() Контейнер, в который был добавлен компонент, чтобы можно было вызвать диспетчер компоновки.

...