Java 如何调试Swing中发生的不必要的重新绘制
我在开发一个Swing应用程序时遇到了一些奇怪的问题。我发现,当我设置某个组件的文本(它只是窗口底部的一个状态栏文本标签)时,屏幕上一个完全不同的区域中的整个表格都被告知要重新绘制。这会导致一些性能问题,因为每次我设置状态栏文本时,似乎都会要求整个窗口重新绘制 我一直在RepaitManager周围徘徊,试图弄清楚发生了什么,发现在我尝试设置此文本的标签时,我的整个主JPanel都被标记为脏组件。但是,我在调试发生的时间点以及发生的确切原因时遇到了问题。我曾尝试阅读过重新绘制系统,但我无法确定当设置了其他文本标签时,为什么非重叠表需要重新绘制 我使用Swing Explorer尝试可视化布局边界,以确保事情不会以某种疯狂的方式重叠,并且一切看起来都很好 我正在寻找一种方法来确定请求JTable重新绘制的调用序列。当我在其paintComponent()上添加断点并遍历堆栈时,我最终进入了RepaitManager的paintDirtyRegions()调用,在该调用中,我的整个主JPanel(包含窗口中的所有内容)都位于tmpDirtyComponents变量中 有人能解释一下,当我最初只设置一个状态文本标签时,我的整个JPanel怎么会被标记为脏的吗?如果没有,您能否提供一些指导,说明在何处查找错误Java 如何调试Swing中发生的不必要的重新绘制,java,swing,repaint,nimbus,synth,Java,Swing,Repaint,Nimbus,Synth,我在开发一个Swing应用程序时遇到了一些奇怪的问题。我发现,当我设置某个组件的文本(它只是窗口底部的一个状态栏文本标签)时,屏幕上一个完全不同的区域中的整个表格都被告知要重新绘制。这会导致一些性能问题,因为每次我设置状态栏文本时,似乎都会要求整个窗口重新绘制 我一直在RepaitManager周围徘徊,试图弄清楚发生了什么,发现在我尝试设置此文本的标签时,我的整个主JPanel都被标记为脏组件。但是,我在调试发生的时间点以及发生的确切原因时遇到了问题。我曾尝试阅读过重新绘制系统,但我无法确定当
非常感谢您提供的任何帮助 只要更改Swing组件的属性,就会在该组件上调用revalidate()和repaint()。设置文本可能会导致组件的首选大小发生更改,因此需要调用布局管理器并重新绘制整个面板
我不知道该如何解决这个问题。不知何故,我通过更改布局管理器成功地避开了这个问题。我的主面板使用了GroupLayout。由于整个GroupLayout非常简单,我决定尝试使用BorderLayout,将JPanel中的主窗口内容添加到BorderLayout.CENTER,并将状态栏标签添加到BorderLayout.PAGE_末尾。它修复了当我设置状态标签文本时整个窗口的奇怪失效和重画!谢谢大家的建议 再加上camickr的评论,为麻烦组件重写isValidateRoot()是解决此问题的正确方法,通常也是解决不必要的重新绘制问题的正确方法
缺点是,如果对isValidateRoot组件的更改确实需要该组件更改大小,则需要手动强制重新验证(myValidateRoot.getParent().invalidate()应执行此操作)。可能在JComponent.invalidate中设置断点,以查看这是否是创建脏区域的原因。当然,调试器捕捉应用程序本身会导致脏区域,因此,请将应用程序与调试器分开。是,当一个重绘触发了一个断点,该断点赋予调试器焦点,这意味着你必须返回到触发另一个重绘的应用程序,等等。这是否意味着强制文本标签组件的首选大小保持不变会阻止重绘的发生?我将尝试一些类似的方法…不确定是否有效。阅读revalidate()方法的API。也许您可以重写组件的isValidateRoot()方法,或者创建一个JPanel并重写此方法,然后将标签添加到其中。这可能会阻止重新验证整个帧。