【问题标题】:Java Swing revalidate() vs repaint()Java Swing revalidate() 与 repaint()
【发布时间】:2010-11-09 00:02:54
【问题描述】:

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

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

我敢肯定,在其他情况下,我只需要拨打revalidate() 就足够了。

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

【问题讨论】:

标签: java swing


【解决方案1】:

revalidate() 只是请求布局容器,当您遇到简单调用revalidate() 工作时,可能是由于子组件边界的更新触发repaint() 在重新布局期间更改其边界。在您提到的情况下,仅删除了组件并且没有更改组件边界,这种情况下没有repaint()“意外”触发。

【讨论】:

    【解决方案2】:

    是的,您需要致电 重绘(); 重新验证(); 当您调用 removeAll() 时,您必须调用 repaint() 和 revalidate()

    【讨论】:

      【解决方案3】:

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

      更笼统地说:与其重复使用原始面板,我建议构建一个新面板并在父面板处交换它们。

      【讨论】:

      • 您能否解释一下为什么构建新面板比使用旧面板更好的解决方案? :)
      • @Arttu - 它的工作量更少,因此更不容易出错。
      【解决方案4】:

      任何时候你执行 remove() 或 removeAll(),你都应该调用

        validate();
        repaint();
      

      在您完成添加()新组件之后。

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

      我自己的测试表明 repaint() 也是必要的。我不确定到底是什么原因。

      【讨论】:

        【解决方案5】:

        revalidate 在添加新组件或删除旧组件后在容器上调用。此调用是告诉布局管理器根据新组件列表重置的指令。 revalidate 将触发重新绘制组件认为是“脏区”的调用。显然,JPanel 上并非所有区域都被 RepaintManager 认为是脏的。

        repaint 用于告诉组件重新绘制自己。通常情况下,您需要调用它来清理像您这样的条件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-12-05
          • 1970-01-01
          • 1970-01-01
          • 2016-12-15
          • 1970-01-01
          • 1970-01-01
          • 2015-05-13
          相关资源
          最近更新 更多