使用 JWindow 时结果不一致

Inconsistent outcome when using JWindow

我正在编写此程序以在 JWindow 中显示 JProgressbar。但是 运行 这个程序在同一台机器上没有做任何更改,每次都会显示不同的结果。大多数情况下,它显示空的 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();
    }
}

我是 运行 in Windows 10 64 位 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)

调用 setVisible(true) 将触发事件调度线程 (EDT)。一旦 运行ning,每个更新 UI 的调用都应该在 运行 内部 EDT,例如通过调用 SwingUtilities.invokeLater().

该规则有一些例外,当对象不可见(因此不呈现)时,请注意在构造函数中调用 UI 更新。一旦它变得可见,此类调用应推迟到美国东部时间。

所以你应该在你的构造函数中布局你的GUI,并且只在最后调用setVisible(true),一旦一切都准备好渲染。

正如@camickr 所指出的,所有 UI 对象建筑物也应推迟到 EDT。不这样做可能会导致未定义的行为(即它可能会或可能不会工作,因为它不是由 JSR 指定的)

关于为什么它没有显示,我再次引用@camickr 的评论:

The reason the code doesn't work is because components are added after the GUI is visible. By default components have a default size of (0, 0). So there is nothing to paint. If you add components to a visible GUI then you need to revalidate() and repaint() the Container the component was added to so the layout manager can be invoked.