使用多个重绘调用对Swing组件进行java自定义绘制
private void moveSquare(int x, int y) {
int OFFSET = 1;
if ((squareX!=x) || (squareY!=y)) {
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
squareX=x;
squareY=y;
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
}
}
在上面的代码中(完整的代码可以在“执行自定义绘制”Java教程的Demo App中找到),第一个repaint
方法应该在前一个正方形的位置绘制一个正方形,第二个repaint
应该在新正方形的位置绘制另一个正方形。但这实际上并没有发生。取而代之的是,前一个方块消失了,新的方块被粉刷了
当前一个广场消失时,新广场是如何被粉刷的
# 1 楼答案
您链接以回答问题的文档,至少在一般情况下:
当您调用
repaint
时,实际上您还没有绘制任何东西,而是请求在将来某个时间重新绘制虽然^{} JavaDoc 没有详细说明,但它包含一个指向“Painting in AWT and Swing”的链接,该链接在“Paint Processing”部分中包含两个案例,第二个案例适用于此处:
在这一节的后面:
当事件处理程序返回时,
JPanel
的某些部分将被标记为重新绘制,可能是全部。这些区域被称为“脏区域”。Swing(最终)一次(并且仅一次)重新绘制所有脏区域。此绘制发生在事件处理程序返回后(即JPanel
的外观已更改后),因此彩色方形显示在其新位置,而在其旧位置没有任何“剩余”简言之,不要认为
repaint
是“立即重新绘制此区域,”,而是“稍后将此区域添加到要绘制的内容列表中”# 2 楼答案
Oracle docs给出了很好的解释:
moveSquare
方法调用repait方法不是一次,而是两次。第一个调用告诉Swing重新绘制组件的区域,该区域以前是正方形(继承的行为使用UI委托使用当前背景色填充该区域)第二个调用绘制当前正方形所在的组件区域# 3 楼答案
调用
repaint()
后,它不会立即重新绘制组件。但它添加了在EDT的事件队列中再次绘制组件的请求每个代码行中发生的情况如下所示
标记将要重新绘制的正方形
(squareX,squareY,squareW+OFFSET,squareH+OFFSET)
所包围的区域。但是直到RepaintManager
重新绘制之前,它不会被重新绘制更改
squareX
和squareY
的值。但它不会更改要重新绘制的早期标记区域。现在,要重新绘制的区域也是以前的值标记将要重新绘制的正方形
(squareX,squareY,squareW+OFFSET,squareH+OFFSET)
所包围的区域。现在有两部分需要重新绘制。旧广场和新广场。但是直到RepaintManager
重新绘制之前,它不会被重新绘制最后,当时机成熟时,
RepaintManager
绘制组件现在,该组件仅绘制了2个区域。(以前的广场和新广场)但红场将仅在新广场内绘制。在老广场上没有什么可画的。所以以前画的东西会被抹掉
实际上,尽管有两个方法调用
repaint()
,但paintComponents()
将只调用一次。要重新绘制的总面积由RepaintManager
处理,paintComponents()
只调用一次