Java Swing revalidate() 与 repaint()

问题描述:

我正在组装一个 Swing 应用程序,我经常想在其中替换 JPanel 的内容.为此,我调用 removeAll(),然后添加我的新内容,然后调用 revalidate().

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().

但是我发现旧内容实际上仍然可见(尽管被新内容掩盖了).如果我在 revalidate() 之外添加对 repaint() 的调用,它会按预期工作.

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() 就足够了.

I'm sure on other occasions I've experienced that just calling revalidate() is enough.

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

So basically my question is - should I need to call both functions and if not, when should I call each of them?

你需要调用repaint()revalidate().前者告诉 Swing 窗口的某个区域是脏的(这是擦除 removeAll() 删除的老孩子的图像所必需的);后者告诉布局管理器重新计算布局(这在添加组件时是必需的).这应该会导致面板的子项重新绘制,但可能不会导致面板本身重新绘制(请参阅 this 用于重绘触发器列表).

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 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.