简体   繁体   English

Java Swing revalidate()与repaint()

[英]Java Swing revalidate() vs repaint()

I'm putting together a Swing application where I often want to replace the contents of a JPanel. 我将一个Swing应用程序放在一起,我经常想替换JPanel的内容。 To do this, I'm calling removeAll() , then adding my new content, then calling revalidate() . 为此,我调用removeAll() ,然后添加新内容,然后调用revalidate()

However I'm finding that the old content is still actually visible (though obscured by the the new content). 但是我发现旧内容实际上仍然可见(尽管被新内容遮盖了)。 If I add a call to repaint() in addition to revalidate() , it works as expected. 如果我除了revalidate()之外还添加了对repaint()的调用,它将按预期工作。

I'm sure on other occasions I've experienced that just calling revalidate() is enough. 我确信在其他情况下,我经历过仅调用revalidate()就足够了。

So basically my question is - should I need to call both functions and if not, when should I call each of them? 因此,基本上我的问题是-我需要同时调用这两个函数吗?如果不需要,何时应分别调用它们?

You need to call repaint() and revalidate() . 您需要调用repaint()revalidate() The former tells Swing that an area of the window is dirty (which is necessary to erase the image of the old children removed by removeAll() ); 前者告诉Swing窗口的区域很脏(这对于擦除由removeAll()删除的旧孩子的图像是必需的); the latter tells the layout manager to recalculate the layout (which is necessary when adding components). 后者告诉布局管理器重新计算布局(添加组件时这是必需的)。 This should cause children of the panel to repaint, but may not cause the panel itself to do so (see this for the list of repaint triggers). 这应该会导致面板重绘的孩子 ,但可能不会导致面板本身这样做(见对于重绘触发的列表)。

On a more general note: rather than reusing the original panel, I'd recommend building a new panel and swapping them at the parent. 总的来说,我建议不要建立原始面板,而建议重新构建面板,并在父面板上交换它们。

Any time you do a remove() or a removeAll(), you should call 每当您执行remove()或removeAll()时,都应调用

  validate();
  repaint();

after you have completed add()'ing the new components. 完成add()后,添加新组件。

Calling validate() or revalidate() is mandatory when you do a remove() - see the relevant javadocs. 执行remove()时必须调用validate()或revalidate()-请参阅相关的Javadocs。

My own testing indicates that repaint() is also necessary. 我自己的测试表明repaint()也是必需的。 I'm not sure exactly why. 我不确定为什么。

revalidate is called on a container once new components are added or old ones removed. 一旦添加了新组件或删除了旧组件,就会在容器上调用revalidate this call is an instruction to tell the layout manager to reset based on the new component list. 该调用是告诉布局管理器根据新组件列表进行重置的指令。 revalidate will trigger a call to repaint what the component thinks are 'dirty regions.' revalidate将触发调用以重绘组件认为是“脏区”的内容。 Obviously not all of the regions on your JPanel are considered dirty by the RepaintManager . 显然, RepaintManager不会将JPanel上的所有区域都视为脏RepaintManager

repaint is used to tell a component to repaint itself. repaint用于告诉组件重绘自身。 It is often the case that you need to call this in order to cleanup conditions such as yours. 通常情况下,您需要调用此命令来清理诸如您的情况。

revalidate() just request to layout the container, when you experienced simply call revalidate() works, it could be caused by the updating of child components bounds triggers the repaint() when their bounds are changed during the re-layout. revalidate()只是请求对容器进行布局,当您体验简单地调用revalidate() ,可能是由于子组件边界的更新在重新布局期间更改其边界而触发repaint()时引起的。 In the case you mentioned, only component removed and no component bounds are changed, this case no repaint() is "accidentally" triggered. 在您提到的情况下,仅删除了组件并且没有更改组件边界,在这种情况下,不会“意外”触发repaint()

yes you need to call repaint(); 是的,您需要调用repaint();。 revalidate(); revalidate(); when you call removeAll() then you have to call repaint() and revalidate() 当您调用removeAll()时,您必须调用repaint()和revalidate()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM