4

我有一个相对较小的类,叫做“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();}

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

我期待着您的回音!

~特拉维斯

4

2 回答 2

14

removeAll()正如@TomHawtintackline(给他+1)所说,不会转发到JFrames contentPane;喜欢add()remove()或者setLayout()是。

因此,当您这样做时,它JFrame#removeAll()删除. 请参阅如何使用根窗格以进行有趣的阅读,并可能对未来的努力卓有成效。JFrame

你应该做:

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

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

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

  • 我认为没有必要,validate()只有repaint()在将组件添加到可见容器时才应该调用这些。甚至不是 do revalidate()which 将适用于添加和删除组件(它反过来调用validate()

于 2013-01-11T17:52:02.560 回答
3

我猜想removeAll删除根窗格。

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

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

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

于 2013-01-11T17:50:37.503 回答