这个java paint程序中的绘图指南是如何工作的?

这个java paint程序中的绘图指南是如何工作的?,java,awt,mouse-listeners,Java,Awt,Mouse Listeners,我现在正在做一个画图程序,我们正在画正方形,当用户拖动鼠标时,他们必须在那里画。 我的教授用图形XOR模式教我们 我找到了这段代码,它看起来效率更高。 我对指南的工作原理感到困惑,它写给我的方式就像他们在拖动鼠标一样。它只会创建一组不同的矩形,它们都会留在屏幕上 为什么矩形会不断地更新到用户的鼠标上,而不是停留在屏幕上 是否因为形状未添加到ArrayList public DrawingBoard() { this.addMouseListener(new MouseAdapter()

我现在正在做一个画图程序,我们正在画正方形,当用户拖动鼠标时,他们必须在那里画。 我的教授用图形
XOR
模式教我们

我找到了这段代码,它看起来效率更高。 我对指南的工作原理感到困惑,它写给我的方式就像他们在拖动鼠标一样。它只会创建一组不同的矩形,它们都会留在屏幕上

为什么矩形会不断地更新到用户的鼠标上,而不是停留在屏幕上

是否因为形状未添加到
ArrayList

public DrawingBoard() {
    this.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            // When the mouse is pressed get x & y position
            drawStart = new Point(e.getX(), e.getY());
            drawEnd = drawStart;
            repaint();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            // Create a shape using the starting x & y
            // and finishing x & y positions
            Shape aShape = drawRectangle(drawStart.x, drawStart.y, e.getX(), e.getY());

            // Add shapes, fills and colors to there ArrayLists
            shapes.add(aShape);
            shapeFill.add(fillColor);
            shapeStroke.add(strokeColor);

            drawStart = null;
            drawEnd = null;

            // repaint the drawing area
            repaint();
        }
    });

    this.addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            // Get the final x & y position after the mouse is dragged
            drawEnd = new Point(e.getX(), e.getY());
            repaint();
        }
    });
}

public void paint(Graphics g) {
    // Class used to define the shapes to be drawn
    Graphics2D graphSettings = (Graphics2D) g;

    // Antialiasing cleans up the jagged lines and defines rendering rules
    graphSettings.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
            RenderingHints.VALUE_ANTIALIAS_ON);

    // Defines the line width of the stroke
    graphSettings.setStroke(new BasicStroke(2));

    // Iterators created to cycle through strokes and fills
    Iterator<Color> strokeCounter = shapeStroke.iterator();
    Iterator<Color> fillCounter = shapeFill.iterator();

    // Eliminates transparent setting below
    graphSettings.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));

    for (Shape s : shapes) {
        // Grabs the next stroke from the color arraylist
        graphSettings.setPaint(strokeCounter.next());
        graphSettings.draw(s);

        // Grabs the next fill from the color arraylist
        graphSettings.setPaint(fillCounter.next());
        graphSettings.fill(s);
    }

    // Guide shape used for drawing
    if (drawStart != null && drawEnd != null) {
        // Makes the guide shape transparent
        graphSettings.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f));

        // Make guide shape gray for professional look
        graphSettings.setPaint(Color.LIGHT_GRAY);

        // Create a new rectangle using x & y coordinates
        Shape aShape = drawRectangle(drawStart.x, drawStart.y, drawEnd.x, drawEnd.y);
        graphSettings.draw(aShape);
    }

}
公共绘图板(){
this.addMouseListener(新的MouseAdapter(){
@凌驾
公共无效鼠标按下(MouseEvent e){
//按下鼠标时,获取x&y位置
drawStart=新点(e.getX(),e.getY());
付款人=提款开始;
重新油漆();
}
@凌驾
公共无效MouseEvent(MouseEvent e){
//使用起始x&y创建形状
//和完成x&y位置
Shape aShape=drawRectangle(drawStart.x,drawStart.y,e.getX(),e.getY());
//向这些阵列列表添加形状、填充和颜色
形状。添加(aShape);
添加(填充颜色);
shapeStroke.add(strokeColor);
drawStart=null;
付款人=空;
//重新绘制绘图区域
重新油漆();
}
});
this.addMouseMotionListener(新的MouseMotionAdapter(){
@凌驾
公共无效鼠标标记(鼠标事件e){
//拖动鼠标后获取最终的x&y位置
抽屉=新点(e.getX(),e.getY());
重新油漆();
}
});
}
公共空间涂料(图g){
//类,用于定义要绘制的形状
Graphics2D图形设置=(Graphics2D)g;
//抗锯齿清除锯齿线并定义渲染规则
graphSettings.setRenderingHint(RenderingHits.KEY_抗锯齿,
RenderingHints.VALUE_ANTIALIAS_ON);
//定义笔划的线宽
图形设置。设定行程(新基本行程(2));
//创建迭代器以循环笔划和填充
迭代器strokeCounter=shapeStroke.Iterator();
迭代器fillCounter=shapeFill.Iterator();
//消除下面的透明设置
graphSettings.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,1.0f));
用于(形状s:形状){
//从颜色阵列列表中获取下一个笔划
graphSettings.setPaint(strokeCounter.next());
图形设置。绘制;
//从颜色阵列列表中获取下一个填充
graphSettings.setPaint(fillCounter.next());
图形设置。填充;
}
//用于绘图的导向形状
if(drawStart!=null&&draund!=null){
//使导向形状透明
graphSettings.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.40f));
//将导向器形状设置为灰色,打造专业外观
图形设置。设置油漆(颜色。浅灰色);
//使用x&y坐标创建新矩形
形状aShape=drawRectangle(drawStart.x,drawStart.y,drawEnd.x,drawEnd.y);
图形设置。绘制(aShape);
}
}

代码将存储用户创建的所有矩形。如果希望在屏幕中显示一个矩形,则可以绘制该矩形,而无需将其保存在arraylist中。删除与arraylist相关的所有代码。

看起来它们在每次鼠标移动时都会重新绘制整个帧-请注意对
repaint()的调用。不确定这是否比XOR更有效。代码也有问题——1)应该覆盖
paintComponent
,而不是
paint
,2)应该在覆盖
中调用super的绘画方法。我对指南的工作原理也感到困惑。根据提供的代码,它不应该工作,因为每次调用绘画方法时面板的背景都不会被清除,所以您应该看到“一堆不同的矩形”。您一定是缺少代码。无论如何,这不是一个好榜样。我建议你看一下,画得很好。关键是
super.paintComponent(…)
,它在重新绘制所有矩形之前清除背景。