Swing通常会组合多个repaint()请求,以便只驱动paintComponent()方法一次,从而提高性能。通常情况下,这是你想要的。如何避免Swing结合repaint()请求?
但是在我的应用程序中,这是不可取的。我的组件是一个充满文本的大屏幕(如文本编辑器)。每个字符都包含前景/背景颜色和样式等属性(如BOLD)。重绘整个屏幕(默认情况下重绘(())是一项昂贵的操作,并且在屏幕上仅更新几个不同字符时引入不必要的延迟。 ,高度)多次,但只适用于实际发生变化的区域(通常为50个字符或更少,可能分散在两个或三个独立的连续区域的屏幕上)。
问题是,在屏幕的顶部和底部会有字符变化,我为每个受影响的区域调用repaint,但Swing将我的多个repaint(...)请求合并为一个repaint(...)请求(这是默认行为)通过计算要重新绘制的区域的联合,这导致一次调用paintComponent(),但带有一个大的剪切矩形(由getClipBounds()返回),它包含所有要更新的区域。因此,无论如何(基于ClipBounds),我都会重新粉刷大面积的屏幕,这会产生不利影响,我希望避免这种情况,因为屏幕的一小部分实际上已被修改,因此需要粉刷一新。
问题:有什么办法可以减轻这种行为,这样我的paintComponent()方法只重绘那些已被修改的区域,并避免不必要地重绘未修改的区域?
的额外细节,如请求:
的类是从衍生的JComponent。基本上,这只是一个“空白”窗口,我使用Swing的API绘制文本字符。窗口的最大尺寸大约为83行×320列(这是在Apple Cinema显示屏上),所以对于8x16字体,这是2560x1328。
基本上,应用程序是一个文本编辑器(想想:vi)。显示屏的最后一行是状态行。在最坏的情况下,我可能会将光标移到窗口顶部的右边一个位置。这会导致窗口底部的状态行被更新以反映新的光标位置(行,列)。所以,我们在窗口顶部有几个位置发生变化,并且窗口底部有一些位置发生变化。我将发出2个重绘(...)请求,每个修改窗口的区域一个。然而,repaint()会合并这两个请求,并用一个边界矩形(定义要重新绘制的区域)调用paintComponent(),这个边界是实际更新的两个区域的union。由此产生的矩形将非常大,从窗口顶部延伸到底部。因此,在paintComponent()中,我重新绘制了大部分屏幕,甚至认为绝大部分屏幕没有被修改。这正是我想要避免的。
您是否考虑过使用文本组件(如'JTextPane'或'JEditorPane')? – MadProgrammer
你能提供更多信息吗?什么样的组件正在重新绘制? – mascoj