简体   繁体   English

使用JWindow时结果不一致

[英]Inconsistent outcome when using JWindow

I'm writing this program to display JProgressbar in JWindow. 我正在编写此程序以在JWindow中显示JProgressbar。 But running this program in same machine without making any changes shows different results each time. 但是,在同一计算机上运行该程序而不进行任何更改,每次都会显示不同的结果。 Most of the time it shows empty JWindow without anything inside. 大多数情况下,它显示空的JWindow,里面没有任何东西。 Other times it shows how I expect it to appear. 其他时候,它显示了我期望它如何出现。 I don't know what is wrong. 我不知道怎么了

I have tried using JFrame. 我已经尝试过使用JFrame。 Then it works perfectly all the time. 然后,它一直都能完美运行。 But I want to use JWindow. 但是我想使用JWindow。

Here is my code : 这是我的代码:

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();
    }
}

I am running in Windows 10 64bit in intelliJ. 我正在intelliJ的Windows 10 64bit中运行。 Here is my java -version : 这是我的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)

Calling setVisible(true) will trigger the Event Dispatch Thread (EDT). 调用setVisible(true)将触发事件调度线程(EDT)。 Once running, every calls updating UI should be run inside the EDT, eg by calling SwingUtilities.invokeLater() . 一旦运行,每次调用更新UI应在美国东部时间运行,例如,通过调用SwingUtilities.invokeLater()

There are some exceptions to that rule, noticeably calling UI updates in constructors when the object is not visible (hence not rendered). 该规则有一些例外,当对象不可见 (因此未呈现)时,会在构造函数中明显调用UI更新。 As soon as it becomes visible, such calls should be deferred to EDT. 一旦可见,应将此类呼叫推迟到EDT。

So you should layout you GUI in your constructor , and call setVisible(true) only at the end, once everything is ready to be rendered. 因此,您应该在构造器中布局GUI ,并在准备好呈现所有内容后仅在最后调用setVisible(true)

As pointed out by @camickr, all UI object buildings should be deferred to EDT as well. 正如@camickr所指出的, 所有 UI对象构建也应推迟到EDT。 Not doing that might lead to undefined behaviour (ie it may or may not work, as it is not specified by the JSR) 不这样做可能导致未定义的行为(即,它可能会或可能不会起作用,因为JSR未指定)

Regarding the why it didn't show, I'm again citing @camickr's comment: 关于为什么不显示,我再次引用@camickr的评论:

The reason the code doesn't work is because components are added after the GUI is visible. 代码不起作用的原因是因为可见GUI 添加了组件。 By default components have a default size of (0, 0). 默认情况下,组件的默认大小为(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. 如果将组件添加到可见的GUI,则需要revalidate()repaint()将组件添加到的Container,以便可以调用布局管理器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM