Java Swing revalidate() 与 repaint()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1097366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Swing revalidate() vs repaint()
提问by William
I'm putting together a Swing application where I often want to replace the contents of a JPanel. To do this, I'm calling removeAll()
, then adding my new content, then calling revalidate()
.
我正在组装一个 Swing 应用程序,我经常想在其中替换 JPanel 的内容。为此,我调用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.
但是我发现旧内容实际上仍然可见(尽管被新内容掩盖了)。如果我repaint()
在 之外添加一个调用revalidate()
,它会按预期工作。
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?
所以基本上我的问题是 - 我是否需要调用这两个函数,如果不需要,我应该什么时候调用它们?
采纳答案by kdgregory
You need to call repaint()
and 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()
); the latter tells the layout manager to recalculate the layout (which is necessary when adding components). This should cause childrenof the panel to repaint, but may not cause the panel itself to do so (see thisfor the list of repaint triggers).
您需要调用repaint()
和revalidate()
。前者告诉 Swing 窗口的某个区域是脏的(这是擦除被 移除的老孩子的图像所必需的removeAll()
);后者告诉布局管理器重新计算布局(添加组件时这是必需的)。这应当引起孩子的面板重新绘制,但可能不会导致面板本身这样做(见这对于重绘触发的列表)。
On a more general note: rather than reusing the original panel, I'd recommend building a new panel and swapping them at the parent.
更一般地说:我建议不要重用原始面板,而是建议构建一个新面板并在父面板上交换它们。
回答by akf
revalidate
is called on a container once new components are added or old ones removed. 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.' Obviously not all of the regions on your JPanel
are considered dirty by the RepaintManager
.
revalidate
添加新组件或删除旧组件后,在容器上调用。这个调用是告诉布局管理器根据新的组件列表重置的指令。 revalidate
将触发重新绘制组件认为是“脏区域”的调用。显然,并非所有区域JPanel
都被RepaintManager
.
repaint
is used to tell a component to repaint itself. It is often the case that you need to call this in order to cleanup conditions such as yours.
repaint
用于告诉组件重新绘制自身。通常情况下,您需要调用它以清除诸如您的条件。
回答by Noel Grandin
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()'ing 新组件之后。
Calling validate() or revalidate() is mandatory when you do a remove() - see the relevant javadocs.
执行 remove() 时必须调用 validate() 或 revalidate() - 请参阅相关的 javadoc。
My own testing indicates that repaint() is also necessary. I'm not sure exactly why.
我自己的测试表明 repaint() 也是必要的。我不确定到底是为什么。
回答by Som Adhikari
yes you need to call repaint(); revalidate(); when you call removeAll() then you have to call repaint() and revalidate()
是的,你需要调用 repaint(); 重新验证();当您调用 removeAll() 时,您必须调用 repaint() 和 revalidate()
回答by Antony Ng
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. In the case you mentioned, only component removed and no component bounds are changed, this case no repaint()
is "accidentally"triggered.
revalidate()
只是请求布局容器,当您遇到简单的调用revalidate()
工作时,可能是由于子组件边界的更新导致repaint()
重新布局期间其边界发生变化时触发。在您提到的情况下,仅删除了组件而没有更改组件边界,这种情况repaint()
是“意外”触发的。