java - 使用 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();
}
}
我在 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)
解决方案
调用setVisible(true)
将触发事件调度线程 (EDT)。一旦运行,每个更新 UI 的调用都应该在 EDT内SwingUtilities.invokeLater()
运行,例如通过调用.
该规则有一些例外,当对象不可见(因此未呈现)时,明显地在构造函数中调用 UI 更新。一旦它变得可见,此类调用应推迟到 EDT。
所以你应该在你的构造函数中布局你的 GUI,并且setVisible(true)
只在最后调用,一旦一切都准备好渲染。
正如@camickr 所指出的,所有UI 对象的构建也应该推迟到 EDT。不这样做可能会导致未定义的行为(即它可能工作也可能不工作,因为它没有由 JSR 指定)
关于为什么它没有显示,我再次引用@camickr 的评论:
代码不起作用的原因是在 GUI 可见之后添加了组件。默认情况下,组件的默认大小为 (0, 0)。所以没有什么可画的。如果您将组件添加到可见的 GUI,那么您需要
revalidate()
和repaint()
组件被添加到的容器,以便可以调用布局管理器。
推荐阅读
- python - python:itk没有属性'VTKImageToImageFilter'
- html - 在 div 内设置边框
- angular - ERR_CONNECTION_REFUSED 将 Angular 站点部署到 Firebase 托管(本地主机...?)
- bash - 在 grep 之后将文本添加到每行的开头
- django - 将列表从前端(react)传递到后端(django)
- javascript - 如何找到子字符串,然后用 javascript 中方法的返回替换它们?
- r - 如何使用马尔可夫聚类算法很好地执行空间聚类(Lat/Lng)分析
- java - java.time 中 Calendar.roll 的等价物是什么?
- python - 使用 NumPy 旋转 5D 立方体
- java - 我正在使用 java swing 概念。组合框的值类似于“GST 18.00%”。我只需要 (18.00) 作为浮点数。有什么办法可以完成这项任务