我有一个名为“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();}
总体而言,我对于为什么没有内容显示感到有点困惑,我对所提出的任何问题都很感兴趣,并且我愿意提供任何必要的信息。谷歌并没有提供很多,而且我发现我已经实施了“重绘和验证”的每一个答案。
我期待着您的回复!
〜特拉维斯
答案 0 :(得分:13)
removeAll()
(+1给他),不会转发到JFrames
contentPane ;例如add()
,remove()
或setLayout()
。
因此当您执行JFrame#removeAll()
时,它会删除JFrame
的根窗格。请参阅How to Use Root Panes进行有趣的阅读,并证明未来的努力取得丰硕成果。
你应该这样做:
getContentPane()。removeAll(); //将确保我们删除所有 来自contentPane的组件
也不要不必要地扩展JFrame
(除非在当前功能之外添加功能)而只是创建JFrame
的实例并使用<{p>
请勿致电setSize
而是使用适当的LayoutManager
和/或覆盖getPreferredSize()
JPanel
并返回符合图纸的尺寸,这样您就可以致电{{} 1}}在pack()
之前将其设置为可见。
我认为不需要JFrame
和validate()
只有在将组件添加到可见容器时才会调用它们。甚至比repaint()
更适合添加和删除组件(它会调用revalidate()
)
答案 1 :(得分:3)
我猜removeAll
删除了根窗格。
JFrame
是一个容器,包含许多组件,这些组件是我们认为的框架的一部分。在JFrame
(和JApplet
)中引入了一个hack,因此某些方法会对内容窗格而不是框架本身起作用。当转发不生效时,使用不同的方法或一种特殊方法,它会搞砸。
请参阅JFrame.remove
的API文档,并注意removeAll
未被覆盖。
最安全的解决方案是忽略“有用”转发,并操纵内容窗格本身(通过getContentPane
,或者更好地创建自己的JPanel
并使用setContentPane
)。 (也不要不必要地扩展类,例如JFrame
或Thread
,并遵循标准编码约定。)