Java Swing revalidate()与repaint()


211

我将一个Swing应用程序放在一起,我经常想替换JPanel的内容。为此,我先打电话removeAll(),然后添加我的新内容,然后打电话revalidate()

但是我发现旧内容实际上仍然可见(尽管被新内容遮盖了)。如果我repaint()除了添加呼叫revalidate(),它会按预期工作。

我敢肯定,在其他情况下,我经历过仅打个电话revalidate()就足够了。

所以基本上我的问题是-我需要同时调用这两个函数吗?如果不需要,什么时候应分别调用它们?


6
Oracle的本教程指出:“始终在重新验证后调用重新绘制”。虽然没有提供解释。
2014年

Answers:


154

您需要致电repaint()revalidate()。前者告诉Swing窗口的区域很脏(这对于删除删除的大孩子的图像是必要的removeAll());后者告诉布局管理器重新计算布局(添加组件时必须这样做)。这应当引起孩子的面板重新绘制,但可能不会导致面板本身这样做(见对于重绘触发的列表)。

总的来说,我建议不要建立重复使用的面板,而应该建立一个新的面板并将其交换给父面板。


1
您能合理地解释为什么建立一个新的面板比使用旧面板更好的解决方案吗?:)
阿图(Arttu)

3
@Arttu-它工作量少,因此不易出错。
kdgregory

86

每当您执行remove()或removeAll()时,都应调用

  validate();
  repaint();

完成add()后,添加新组件。

执行remove()时必须调用validate()或revalidate()-请参阅相关的Javadocs。

我自己的测试表明repaint()也是必需的。我不确定为什么。


59

revalidate一旦添加了新组件或删除了旧组件,就会在容器上调用。该调用是告诉布局管理器根据新组件列表进行重置的指令。 revalidate将触发一个调用,以重画组件认为是“脏区”的内容。显然,并非您的所有区域JPanel都被脏了RepaintManager

repaint用于告诉组件重新绘制自身。通常情况下,您需要调用此命令来清理您的情况。


5

revalidate()只是要求对容器进行布局,当您经历简单的调用revalidate()工作时,可能是由于子组件边界触发repaint()在重新布局期间更改其边界时更新而引起的。在您提到的情况下,仅删除了组件,而没有更改组件边界,在这种情况下repaint()“偶然”触发了no 。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.