【问题标题】:Unable to add to JFrame after removeAll()removeAll() 后无法添加到 JFrame
【发布时间】:2012-12-26 08:16:03
【问题描述】:

我有一个相对较小的类,叫做“LoadingWindow”,这个类有一个构造函数,它调用一个 Initialize 函数来设置框架。不是我在测试一些东西来试图解决为什么它不会更新。在测试时我添加了“this.removeAll();”到初始化方法的头部。事实证明,在那之后我不能添加任何东西。我添加的任何内容都不会显示。

这是一个略微精简的课程:

public class LoadingWindow extends JFrame{

public JPanel panel;

public JProgressBar bar;

private JLabel label;

public LoadingWindow()
{

    this.Initialize();

}

public void Initialize()
{
    this.removeAll();

    this.setSize(300, 150);

    panel = new JPanel(new BorderLayout());
    bar = new JProgressBar(0,100);
    label = new JLabel("Please remain calm, we're just loading...");

    panel.add(bar,BorderLayout.CENTER);
    panel.add(label,BorderLayout.SOUTH);

    this.add(panel);

    this.validate();
    this.repaint();
    this.setVisible(true);
}
}

窗口本身确实会正确弹出,并带有标题。但是窗口本身是完全空白的。

我静态实现这个类,以便其他四个对象可以在 EditorPanel 类中访问它。其定义为:

public static LoadingWindow loadingWindow;

并在构造函数中初始化:

loadingWindow = new LoadingWindow();

然后在使用它的函数中进行双重检查,以显示它是否隐藏。

if(!EditorPanel.loadingWindow.isVisible()){EditorPanel.loadingWindow.Initialize();}

总的来说,我对为什么没有显示内容感到有些困惑,我对提出的任何问题都非常感兴趣,并且愿意提供任何必要的信息。谷歌没有提供很多,我发现的每个答案我都已经实现了“例如重绘和验证”。

期待您的回音!

~特拉维斯

【问题讨论】:

  • 注意,不要调用JFrame.removeAll(),结果可能是删除RootPane,空容器只有ToolbarBorders,改用JFrame.getContentPane().removeAll()

标签: java swing jframe add removeall


【解决方案1】:

removeAll() 正如@TomHawtintackline 所说(给他+1),不会转发到JFrames contentPane;就像add()remove()setLayout() 一样。

因此,当您执行JFrame#removeAll() 时,它会删除JFrame根窗格。请参阅How to Use Root Panes 以获取有趣的阅读内容,并且可能会为未来的努力带来丰硕的成果。

你应该这样做:

getContentPane().removeAll();// 将确保我们删除所有 contentPane 中的组件

  • 也不要不必要地扩展JFrame(除非添加超出其当前能力的功能)而只是创建JFrame的实例并使用它

  • 不要调用setSize,而是使用适当的LayoutManager 和/或覆盖JPanelgetPreferredSize() 并返回适合图纸的尺寸,因此您可以在设置之前在JFrame 上调用pack()可见。

  • 我认为没有必要 validate()repaint() 只有在将组件添加到可见容器时才应该调用它们。甚至宁可使用revalidate() 来添加和删除组件(它反过来调用validate()

【讨论】:

  • getContentPane() 确实有效。但是为什么loadingWindow.setVisible(false);之后frame会重新出现空白? loadingWindow.Initialize(); ?
  • @TravisTruttschel 请提供SSCCE 以便我准确回答
  • +1 表示“不要不必要地扩展JFrame,并提出解决方案。
【解决方案2】:

我猜removeAll 会删除根窗格。

JFrame 是一个容器,包含许多组件,这些组件是我们认为的框架的一部分。在JFrame(和JApplet)中引入了一个hack,因此某些方法作用于内容窗格而不是框架本身。当转发不生效时,使用其他方法或特殊方法之一,它会搞砸。

请参阅JFrame.remove 的 API 文档并注意 removeAll 未被覆盖。

最安全的解决方案是忽略“有用”的转发,并操纵内容窗格本身(通过getContentPane,或者更好地创建自己的JPanel 并使用setContentPane)。 (也不要不必要地扩展类,例如 JFrameThread,并遵循标准编码约定。)

【讨论】:

    猜你喜欢
    • 2019-06-06
    • 2015-11-08
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多