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
应该在新正方形的位置绘制另一个正方形。但这实际上并没有发生。相反,前一个方块消失了,新的方块被涂上了。
当前一个方块消失时,新方块是如何绘制的?
答案 0 :(得分:1)
您链接的文档可以回答您的问题,至少在一般情况下如此:
尽管我们在同一个事件处理程序中连续两次调用
repaint
,但Swing足够聪明,可以在一次绘制操作中获取该信息并重新绘制屏幕的这些部分。
当你致电repaint
时,你实际上并没有画任何东西,但是在将来的某个时间要求重新制作 。
虽然repaint
JavaDoc没有详细说明,但它包含指向" Painting in AWT and Swing"的链接,其中包含" {{3 }}"第二部分,第二部分适用于此:
(B)[当]绘画请求来自对
repaint()
扩展名javax.swing.JComponent
的调用时:
JComponent.repaint()
向组件RepaintManager
注册一个异步重绘请求,该请求使用invokeLater()
对Runnable
进行排队,以便稍后处理事件调度请求线程。
后来在那一节:
注意:如果在处理重绘请求之前在组件或其任何Swing祖先上发生多次
repaint()
调用,那么这些多个请求可能会折叠成单个回调到paintImmediately()
[。 ..]
当您的事件处理程序返回时,JPanel
的某些部分将被标记为重新绘制,可能是所有部分。这些被称为"脏区"。 Swing(最终)立刻重新绘制所有脏区域,并且只重复一次。在事件处理程序返回后,发生了这个绘画 - 意味着JPanel
的外观已经改变了 - 所以彩色方块出现在新的位置,没有任何"剩菜和#34;在它的旧位置。
简而言之,不要将repaint
视为"立即重新粉饰此区域",但是"将此区域添加到您的一些东西到后面的东西 - #34;。
答案 1 :(得分:1)
致电repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
后,它不会立即重新绘制该组件。但它添加了在EDT中的事件队列中再次绘制组件的请求。
每个代码行中发生的事情都在下面进行了解释..
(squareX,squareY,squareW+OFFSET,squareH+OFFSET)
标记由正方形RepaintManager
限定的区域将重新绘制。但是在squareX=x;
squareY=y;
这样做之前不会重新粉刷。
squareX
更改squareY
和repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
的值。但它不会改变之前标记的区域以进行重新绘制。现在,要重新绘制的区域是先前的值。
(squareX,squareY,squareW+OFFSET,squareH+OFFSET)
标记由正方形RepaintManager
限定的区域将重新绘制。现在有两个部分RepaintManager
必须重新绘制。以前的广场和新广场。但是在RepaintManager
这样做之前不会重新粉刷。
最后,到时候,protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("This is my custom Panel!",10,20);
g.setColor(Color.RED);
g.fillRect(squareX,squareY,squareW,squareH);
g.setColor(Color.BLACK);
g.drawRect(squareX,squareY,squareW,squareH);
}
绘制组件。
repaint()
现在该组件仅绘制了2个区域。 (上一个方块和新方块)但红色方块只能在新方块内绘制。在旧广场上没有什么可画的。所以先前绘制的东西将被删除..
实际上,虽然paintComponents()
有2个方法调用,但RepaintManager
只会被调用一次。要重新绘制的总面积由paintComponents()
处理,gridApi
仅调用一次..
答案 2 :(得分:0)
Oracle docs给出了很好的解释:
defaultdict
方法不是一次调用重绘方法,而是调用两次。第一次调用告诉Swing重新绘制先前正方形的组件区域(继承的行为使用UI委托用当前背景颜色填充该区域。)第二次调用绘制当前正方形的组件区域