我试图了解Swing的绘画是如何工作的。为此,我一直在阅读Oracle教程:http://docs.oracle.com/javase/tutorial/uiswing/painting/step3.html
我的问题很简单: 为什么对同一个函数(重绘)的两次调用有不同的行为? UI委托如何在先前绘制的矩形上绘制背景,但在新区域上绘制一个新矩形?我没有在paintComponent()上看到任何特殊原因。
我也读过http://docs.oracle.com/javase/tutorial/uiswing/painting/closer.html试图了解情况。似乎与组件的opaque属性有一些联系。在我们创建一个新矩形后,此属性是否会更改,因此它是真的(因此,如上所述,ui.update()会将其设置为背景颜色)。为什么paintComponent()不会在那里绘制一个新的矩形?
答案 0 :(得分:3)
使用不同的参数调用该函数:
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
squareX=x;
squareY=y;
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
在第一次调用repaint()时,squareX和squareY表示先前绘制的对象的位置。在第二次调用中,squareX和squareY更改为当前鼠标位置。
关于repaint()的JComponent API文档:
如果组件是,则将指定的区域添加到脏区列表中 展示。该组件将在所有当前重新绘制后重新绘制 已发送待处理事件。
也就是说,第一次调用repaint()会将之前的位置标记为脏,第二次将当前位置标记为脏。当事件(moveSquare)完成时,将重新执行paintComponent,并更新这两个区域。红色矩形仅放置在新位置,旧位置更新为“空”。
答案 1 :(得分:1)
您的the opaque property是正确的,true
对于典型的PanelUI
实施而言是super.paintComponent(g)
。特别是,paintComponent()
说,
如果你没有调用super的实现,你必须尊重opaque属性......如果你不尊重opaque属性,你可能会看到视觉伪像。
您的代码 通过调用repaint()
来支持opaque属性。 两次调用MyPanel
将绘图矩形清除为背景颜色。尝试在super
构造函数中设置不同的背景颜色,并省略public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
setBackground(Color.cyan);
...
}
@Override
protected void paintComponent(Graphics g) {
//super.paintComponent(g);
g.drawString("This is my custom Panel!", 10, 20);
...
}
调用以查看效果:
{{1}}