JFrame 中的 JPanel 有时不显示内容。为啥?

Posted

技术标签:

【中文标题】JFrame 中的 JPanel 有时不显示内容。为啥?【英文标题】:JPanel inside JFrame doesn't show content sometimes. Why?JFrame 中的 JPanel 有时不显示内容。为什么? 【发布时间】:2019-03-06 20:19:45 【问题描述】:

我设法修复了它,但我不明白为什么相同的代码会导致不同的结果。有些同学也遇到过同样的问题。

问题是我在chicha();之前使用miVentana.setVisible(true);,JPanel中的元素将在执行时显示,但如果我再次运行它,有时它们在我调整窗口大小之前不会可见,有几次甚至不可见JPanel 背景颜色可见。只需单击 IDE 上的“运行”底部,无需更改任何其他内容。

我只是连续尝试了 10 次,元素仅在第 4 次尝试时可见。

这可能来自之前执行代码时留下的一些内存垃圾吗?

我正在使用 Eclipse 版本:Photon Release (4.8.0)。

这是具有奇怪行为的代码:

public class Ej10 extends JFrame 

    public Ej10() 
        setLayout(null);
    

    static Ej10 miVentana = new Ej10();

    public static void main(String[] args) 
        miVentana.setTitle("Ejercicio10");
        miVentana.setBounds(20, 20, 500, 600);
        miVentana.setLocationRelativeTo(null);

        miVentana.setVisible(true);

        chicha();
        //miVentana.setVisible(true);

    

    static void chicha() 
        JPanel miPanel = new JPanel();
        miPanel.setLayout(new BoxLayout(miPanel, BoxLayout.PAGE_AXIS));
        miPanel.setBounds(20, 20, 350, 450);
        miPanel.setBackground(Color.CYAN);

        JLabel lUsuario = new JLabel("Usuario:");
        lUsuario.setVisible(true);
        JTextField campoUsuario = new JTextField();
        JLabel lPwd = new JLabel("Contraseña:");
        JPasswordField campoPwd = new JPasswordField();
        JButton bAcceso = new JButton("Acceder");

        miPanel.add(lUsuario);
        miPanel.add(campoUsuario);
        miPanel.add(lPwd);
        miPanel.add(campoPwd);
        miPanel.add(bAcceso);

        miPanel.setVisible(true);
        miVentana.add(miPanel);
    

【问题讨论】:

【参考方案1】:

在使框架可见之前,需要将组件添加到框架中。

setVisible() 方法的功能之一是调用布局管理器。否则组件的 size() 为 (0, 0),因此没有可绘制的内容。

另外,所有的 GUI 组件都应该在 Event Dispatch Thread (EDT) 上创建,否则你会得到随机结果。阅读 Concurrency 上的 Swing 教程部分了解更多信息。

查看How to Make Frames 中的FrameDemo,了解如何构建代码以避免出现问题的最基本示例。它展示了如何在 EDT 上创建组件以及如何使框架可见。

在我调整窗口大小之前,它们不会可见,

调整框架大小也会导致布局管理器被调用。

miPanel.setBounds(20, 20, 350, 450);

该语句不会执行任何操作,因为框架的布局管理器将根据布局管理器的规则确定面板的大小和位置。框架的默认布局管理器是 BorderLayout,因此基本上面板将获得框架可用的所有空间。

本教程还有一个关于Layout Managers 的部分,您应该阅读。

【讨论】:

以上是关于JFrame 中的 JPanel 有时不显示内容。为啥?的主要内容,如果未能解决你的问题,请参考以下文章

java swing编程问题:一个jframe中添加一个jpanel后,为jpanel添加一个滚动条,当jpanel中内容过多时滑动

如何在jframe中的jpanel中设置单选按钮?

使用框架状态变量更新 JFrame 中的 JPanel 内容

我如何编写代码来显示每个 JPanel 中的每个字母,以及如何旋转。 (JFrame、NetBeans)

java中jframe 和jpanel的区别

JMenuBar显示在JFrame和JPanel中