Java Swing revalidate()vs repaint()

时间:2009-07-08 10:58:32

标签: java swing

我正在整理一个Swing应用程序,我常常想要替换JPanel的内容。为此,我正在调用removeAll(),然后添加新内容,然后调用revalidate()

但是我发现旧内容实际上仍然可见(虽然被新内容遮挡了)。如果我在repaint()之外添加了对revalidate()的调用,则会按预期工作。

我确信在其他场合我经历过只是打电话给revalidate()就足够了。

所以基本上我的问题是 - 我是否需要调用这两个函数?如果没有,我何时应该调用它们?

5 个答案:

答案 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)

是的,你需要打电话     重绘();     重新验证(); 当你调用removeAll()然后你必须调用repaint()和revalidate()