我正在编写此程序以在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 64bit中运行。 这是我的java -version:
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)
答案 0 :(得分:1)
调用setVisible(true)
将触发事件调度线程(EDT)。运行后,每个呼叫更新用户界面都应在EDT内部 中运行,例如通过致电SwingUtilities.invokeLater()
。
该规则有一些例外,当对象不可见(因此未呈现)时,会在构造函数中明显调用UI更新。一旦可见,应将此类呼叫推迟到EDT。
因此,您应该在构造函数中布局GUI ,并在准备好呈现所有内容后仅在最后调用setVisible(true)
。
@camickr指出,所有 UI对象的构建也应推迟到EDT。不这样做可能导致未定义的行为(即,它可能会或可能不会起作用,因为JSR未指定)
关于未显示为什么的原因,我再次引用@camickr的评论:
代码不起作用的原因是因为在可见GUI后 后添加了组件。默认情况下,组件的默认大小为(0,0)。因此,没有什么可绘画的。如果将组件添加到可见的GUI,则需要
revalidate()
和repaint()
组件被添加到的容器,以便可以调用布局管理器。