Swing GUI中validate()、revalidate()和invalidate()的区别

123

Swing组件有多个与屏幕布局更新相关的方法,特别是:

Java文档从技术角度定义了这些方法,但它们的使用方式并不是非常清晰。

这些方法之间有什么区别?在什么情况下应该使用其中的一个而不是其他方法?

2个回答

74

invalidate() 会将容器标记为无效,这意味着内容出现了某些问题,必须重新布局。但它只是一种标记/标志。可能需要稍后刷新多个无效的容器。

validate() 执行重新布局。这意味着请求所有大小的无效内容,并通过LayoutManager设置所有子组件的大小为适当值。

revalidate() 只是两者的总和。它将容器标记为无效,并对容器执行布局。

更新:

来自Component.java的一些代码:

public void revalidate() {
    revalidateSynchronously();
}

/**
 * Revalidates the component synchronously.
 */
final void revalidateSynchronously() {
    synchronized (getTreeLock()) {
        invalidate();

        Container root = getContainer();
        if (root == null) {
            // There's no parents. Just validate itself.
            validate();
        } else {
            while (!root.isValidateRoot()) {
                if (root.getContainer() == null) {
                    // If there's no validate roots, we'll validate the
                    // topmost container
                    break;
                }

                root = root.getContainer();
            }

            root.validate();
        }
    }
}

3
revalidate()方法不会调用doLayout()方法,而validate()方法会。因此,它并不完全等同于两者的总和 - revalidate()并不总是能够替代validate() - Meo
那是用于AWT的,而这是Swing中revalidate的样子:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/javax/swing/JComponent.java#JComponent.revalidate%28%29 - Meo
在这种情况下,我猜(从未尝试过)RepaintManager将调用validate。 - StanislavL
我正在处理一个棘手的 bug,将 revalidate 替换为 validate(调用 doLayout)解决了它... - Meo
我们如何从静态方法中调用validate()? - Kunal Tyagi

72

validate() : 在Swing中创建一个组件时,它的valid属性是false,即该组件不是有效的。当组件的宽度、高度、位置等属性已经确定后,就可以说该组件是有效的。通常使用直接或间接调用validate()方法来实现这一点。当我们在容器上调用validate()时,如果容器是无效的,它将通过调用其doLayout()方法来验证容器,这通常会调用LayoutManager。现在,该容器中放置的每个子元素都将递归验证,使整个树形结构变为有效并进行布局。

revalidate() : 当更改影响容器宽度/高度的属性时,应调用revalidate();当更改影响组件外观的属性时,应调用repaint()。例如,如果您的JFrame包含一个JPanel,现在在某个时间点上,您将该JPanel移除并插入一个新的JPanel,则取决于新放置的JPanel的内容,JPanel中的组件以及容器本身(由于使用的布局管理器)的大小会发生变化,从而使其变为无效状态。因此,为了验证此更改,必须显式地调用revalidate()

invalidate() : 我从未使用过这个方法,因此可能无法提供太多信息。但是,上述情况似乎可以给出一些提示,说明在使用invalidate()时会发生什么。


2
我认为invalidate()在您更新多个组件并希望在最终使用revalidate()validate()重新计算布局之前将它们标记为无效时非常有用。 - Qix - MONICA WAS MISTREATED
1
@Qix:在我看来,没有必要调用invalidate(),因为它会自动被调用。此外,revalidate()本身就会执行这个任务(正如Java文档中所述,它作为同时调用'invalidate()'和'validate()'的便捷方法)。 - nIcE cOw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接