我正在编写这个程序以在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();
}
}
我在 intelliJ 中的 Windows 10 64 位运行。 这是我的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)。运行后,每个更新 UI 的调用都应在EDT 中运行,例如通过调用SwingUtilities.invokeLater()
。
该规则有一些例外,当对象不可见(因此不呈现)时,明显地在构造函数中调用 UI 更新。一旦它变得可见,此类调用应推迟到 EDT。
因此,您应该在构造函数中布局 GUI,并在一切准备就绪后仅在最后调用setVisible(true)
。
正如 @camickr 所指出的,所有UI 对象构建也应推迟到 EDT。不这样做可能会导致未定义的行为(即它可能有效,也可能无效,因为它不是由JSR指定的)
关于为什么它没有显示,我再次引用@camickr的评论:
代码不起作用的原因是组件是在 GUI 可见之后添加的。默认情况下,组件的默认大小为 (0, 0)。所以没有什么可画的。如果将组件添加到可见 GUI,则需要
revalidate()
并repaint()
组件添加到的容器,以便可以调用布局管理器。