Swing通常会组合多个repaint()请求,以便仅驱动paintComponent()方法一次,从而提高性能。通常,这就是你想要的。
然而,在我的申请中,这是不可取的。我的组件是一个充满文本的大屏幕(如文本编辑器)。每个角色都包含前景/背景颜色和样式(如BOLD)等属性。重新绘制整个屏幕(默认情况下重绘((默认))是一项昂贵的操作,并且只在屏幕上更新几个不同的字符时会引入不必要的延迟。
因此,我多次调用重绘(x,y,宽度,高度),但仅适用于那些实际发生变化的区域(通常为50个字符或更少,可能分散在两个或三个屏幕上,连续的区域)。
问题是,通常我会在屏幕的顶部和底部更改字符。我为每个受影响的区域调用repaint,但是Swing通过计算要重新绘制的区域的并集将我的多个重绘(...)请求组合成单个重绘(...)请求(这是默认行为)。这导致对paintComponent()的单个调用,但是具有大的剪切矩形(由getClipBounds()返回),其包含要更新的所有区域。因此,我最终重新粉刷了屏幕的大部分区域(基于ClipBounds),这是适得其反的,我希望避免,因为屏幕的一小部分实际上已被修改,因此需要重新绘制。
问题:有没有办法缓解这种行为,以便我的paintComponent()方法只重绘那些已修改的区域,并避免不必要的重新绘制未修改的区域?
根据要求提供更多细节:
该类派生自JComponent。基本上,它只是一个“空”窗口,我使用Swing的API绘制文本字符。窗口的最大大小约为每行320行×320列(这是在Apple Cinema显示器上),因此对于8x16字体,则为2560x1328。
基本上,应用程序是文本编辑器(想想:vi)。显示屏的最后一行是状态行。在最坏的情况下,我可能会将光标移动到窗口顶部的右侧一个位置。这将导致窗口底部的状态行被更新以反映新的光标位置(行,列)。因此,我们在窗口顶部更改了一些位置,并在窗口底部更改了一些位置。我会发出2个重绘(...)请求,一个用于窗口的每个修改区域。但是,repaint()将组合这两个请求,并使用边界矩形(定义要重新绘制的区域)调用paintComponent()一次,该边界是实际更新的两个区域的 union 。得到的矩形将非常大,从窗口的顶部延伸到底部。因此,在paintComponent()中,我最终重新绘制了大部分屏幕,甚至认为绝大多数都没有被修改过。这就是我想要避免的。
答案 0 :(得分:0)
是否有任何方法可以缓解此行为,以便我的paintComponent()方法仅重新绘制已修改的区域,
您可以尝试使用paintImmediately(...)
类的JComponent
方法。
这将导致在没有RepaintManager
的好处的情况下立即完成多个较小的绘制请求。只有您可以决定多个较小的请求的性能优于单个较大的绘制请求。