使用 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.
我正在编写此程序以在 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()
andrepaint()
the Container the component was added to so the layout manager can be invoked.