如何在Swing中调试不必要的重绘

时间:2011-03-21 01:41:26

标签: java swing repaint nimbus synth

我正在开发的Swing应用程序中重新绘制一些奇怪的问题。我发现当我设置某个组件的文本(它只是窗口最底部的状态栏文本标签)时,屏幕的一个非常不同的区域中的整个表被告知要重新绘制。这会导致一些性能问题,因为基本上每次设置状态栏文本时都会要求整个窗口重新绘制。

我一直在RepaintManager周围试图弄清楚发生了什么,并且在我尝试设置此文本的标签时发现我的整个主要JPanel被标记为脏组件。但是,我在正在发生的 调试时遇到了问题,而且为什么正在发生。我试图阅读重绘系统,但我无法确定为什么在设置其他文本标签时重写非重叠表是必要的。

我使用Swing Explorer尝试可视化布局边​​框,以确保事物不会以某种疯狂的方式重叠,并且一切看起来都很好。

我正在寻找一种方法来确定要求JTable重新绘制的调用序列。当我在其paintComponent()上添加一个断点并向上移动堆栈时,我最终进入了RepaintManager的paintDirtyRegions()调用,其中我的整个主JPanel(包含窗口中的所有内容)都位于tmpDirtyComponents变量中。

当我最初只设置一个状态文本标签时,有人可以解释我的整个JPanel是如何被标记为脏的吗?如果没有,你能提供一些关于在哪里找到错误的指导吗?

非常感谢您提供的任何帮助!

3 个答案:

答案 0 :(得分:1)

每当您更改Swing组件上的属性时,都会在组件上调用revalidate()和repaint()。设置文本可能会导致组件的首选大小发生变化,因此需要调用布局管理器并重新绘制整个面板。

我不确定如何解决这个问题。

答案 1 :(得分:1)

不知何故,我设法通过更改我的布局管理器来解决这个问题。我的主要面板是使用GroupLayout。由于整个GroupLayout非常简单,我决定尝试使用BorderLayout,将JPanel中的主窗口内容添加到BorderLayout.CENTER,将状态栏标签添加到BorderLayout.PAGE_END。当我设置状态标签文本时,它修复了整个窗口的奇怪失效和重绘!感谢大家提出的好建议!

答案 2 :(得分:1)

只是添加到camickr的注释中,覆盖麻烦组件的isValidateRoot()是解决此问题的正确方法,并且通常是解决不必要的重绘问题的正确解决方案。

缺点是如果对isValidateRoot组件的更改实际上需要组件更改大小,则需要手动强制重新生效(myValidateRoot.getParent()。invalidate()应该执行它)。