3

我试图了解如何使用 Swing 进行绘画。为此,我一直在阅读 Oracle 教程:http ://docs.oracle.com/javase/tutorial/uiswing/painting/step3.html

我的问题很简单:为什么对同一函数(重绘)的两次调用具有不同的行为?UI Delegate 是如何在之前绘制的矩形上绘制背景,但在新区域上绘制一个新矩形?我在paintComponent() 上没有看到任何特殊原因。

我还阅读了http://docs.oracle.com/javase/tutorial/uiswing/painting/closer.html试图了解情况。似乎与组件的 opaque 属性有某种联系。在我们创建一个新的矩形后这个属性是否会改变,所以它是真的(因此,如前所述,ui.update() 会将它设置为背景颜色)。为什么paintComponent() 没有在那里绘制一个新的矩形?

4

2 回答 2

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 被重新执行,这两个区域被更新。红色矩形只放置在新位置,旧位置更新为“空”。

于 2012-11-09T15:29:52.457 回答
1

您对opaque 属性是正确的,它true适用于典型PanelUI实现。特别是,paintComponent()说,

如果您不调用 super 的实现,则必须遵守 opaque 属性...如果您不遵守 opaque 属性,您可能会看到视觉伪影。

您的代码确实通过调用super.paintComponent(g). 这两个调用都repaint()将绘图矩形清除为背景颜色。尝试在构造函数中设置不同的背景颜色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);
    ...
}
于 2012-11-09T18:58:46.127 回答