我正在整理一个Swing应用程序,我常常想要替换JPanel的内容。为此,我正在调用removeAll()
,然后添加新内容,然后调用revalidate()
。
但是我发现旧内容实际上仍然可见(虽然被新内容遮挡了)。如果我在repaint()
之外添加了对revalidate()
的调用,则会按预期工作。
我确信在其他场合我经历过只是打电话给revalidate()
就足够了。
所以基本上我的问题是 - 我是否需要调用这两个函数?如果没有,我何时应该调用它们?
答案 0 :(得分:153)
您需要致电repaint()
和revalidate()
。前者告诉Swing窗口的一个区域是脏的(这是擦除由removeAll()
移除的旧孩子的图像所必需的);后者告诉布局管理器重新计算布局(添加组件时这是必要的)。这应该导致面板的 children 重绘,但可能不会导致面板本身这样做(请参阅this了解重绘触发器列表)。
更一般地说:我不建议重新使用原始面板,而是建议建立一个新面板并将其交换为父面板。
答案 1 :(得分:82)
每次执行remove()或removeAll()时,都应该调用
validate();
repaint();
完成add()新组件之后
。执行remove()时,必须调用validate()或revalidate() - 请参阅相关的javadoc。
我自己的测试表明repaint()也是必要的。我不确定为什么。
答案 2 :(得分:58)
revalidate
。此调用是指示布局管理器根据新组件列表重置的指令。 revalidate
将触发调用以重新绘制组件认为“脏区域”的内容。显然,JPanel
并未将RepaintManager
上的所有区域视为脏。
repaint
用于告诉组件重绘自己。通常情况下,您需要调用此方法来清理诸如您的条件。
答案 3 :(得分:3)
revalidate()
只是请求布局容器,当您遇到简单调用revalidate()
时,它可能是由更新子组件边界引起的,当它们的边界发生变化时触发repaint()
在重新布局期间。在您提到的情况下,只删除了组件并且没有更改组件边界,这种情况下repaint()
"意外地" 被触发。
答案 4 :(得分:-4)