当我绘制另一个矩形时,如何保留我在 Jpanel 上绘制的矩形?

How to keep the rectangle that I drew on the Jpanel when I draw another rectangle?

我在 JAVA 中有这段代码,当我在面板上拖动鼠标时,它会像绘图应用程序一样绘制一个矩形。每次我单击并拖动以创建一个新矩形时,之前的矩形都会消失。我想知道是否有办法让它留在面板上。并且对于有多个矩形,就像 windows.

上的绘画应用程序一样

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

    public class DrawRect extends JPanel {

        int x, y, x2, y2;

        public static void main(String[] args) {
            JFrame f = new JFrame("Draw Box Mouse 2");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setContentPane(new DrawRect());
            f.setSize(300, 300);
            f.setVisible(true);
        }

        DrawRect() {
            x = y = x2 = y2 = 0; // 
            MyMouseListener listener = new MyMouseListener();
            addMouseListener(listener);
            addMouseMotionListener(listener);
        }

        public void setStartPoint(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public void setEndPoint(int x, int y) {
            x2 = (x);
            y2 = (y);
        }

        public void drawPerfectRect(Graphics g, int x, int y, int x2, int y2) {
            int px = Math.min(x,x2);
            int py = Math.min(y,y2);
            int pw=Math.abs(x-x2);
            int ph=Math.abs(y-y2);
            g.drawRect(px, py, pw, ph);
        }

        class MyMouseListener extends MouseAdapter {

            public void mousePressed(MouseEvent e) {
                setStartPoint(e.getX(), e.getY());
            }

            public void mouseDragged(MouseEvent e) {
                setEndPoint(e.getX(), e.getY());
                repaint();
            }

            public void mouseReleased(MouseEvent e) {
                setEndPoint(e.getX(), e.getY());
                repaint();
            }
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            drawPerfectRect(g, x, y, x2, y2);
        }

    }

在编写 Swing 图形程序时要记住一些有用的事情:

  • paintComponent每次调用都会重新绘制整个组件,所以你需要绘制所有你想要出现的东西。您对 Graphics 对象执行的操作只会持续到下一次调用 paintComponent.
  • Graphics2DGraphics 更能干。它使用浮点坐标、各种线条样式等绘制很好的抗锯齿形状。 paintComponentGraphics 参数实际上始终是一个 Graphics2D 实例,您可以放心地将其转换为一个实例。
  • 组件的继承层次也是一个绘画层次,所以你需要在你的paintComponent方法的开头调用super.paintComponent(g)。有关详细信息,请参阅

所以我对你的程序做了一些修改:

  • 添加了一个字段,List<Rectangle2D> rectangles 以记住用户创建的矩形。每次抬起鼠标按钮时,都会将一个矩形添加到此列表中。
  • 添加了对 super.paintComponent
  • 的调用
  • 使用Graphics2D绘制矩形,线条风格更有趣(Stroke)
  • 更改了 paintComponent 以绘制列表中的每个矩形,以及用户当前正在绘制的 'rubber-band' 矩形。

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

public class DrawRect extends JPanel {

    int x, y, x2, y2;
    // this is the list of all the rectangles the user has drawn so far
    List<Rectangle2D> rectangles = new ArrayList<>();

    public static void main(String[] args) {
        JFrame f = new JFrame("Draw Box Mouse 2");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(new DrawRect());
        f.setSize(300, 300);
        f.setVisible(true);
    }

    DrawRect() {
        x = y = x2 = y2 = 0; //
        MyMouseListener listener = new MyMouseListener();
        addMouseListener(listener);
        addMouseMotionListener(listener);
    }

    public void setStartPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void setEndPoint(int x, int y) {
        x2 = (x);
        y2 = (y);
    }

    // this creates a new rectangle object instead of drawing one
    public Rectangle2D makePerfectRect(int x, int y, int x2, int y2) {
        int px = Math.min(x,x2);
        int py = Math.min(y,y2);
        int pw=Math.abs(x-x2);
        int ph=Math.abs(y-y2);
        return new Rectangle2D.Float(px, py, pw, ph);
    }

    class MyMouseListener extends MouseAdapter {

        public void mousePressed(MouseEvent e) {
            setStartPoint(e.getX(), e.getY());
        }

        public void mouseDragged(MouseEvent e) {
            setEndPoint(e.getX(), e.getY());
            repaint();
        }

        public void mouseReleased(MouseEvent e) {
            setEndPoint(e.getX(), e.getY());
            // when the mouse is released, we add the current rectangle to our list
            rectangles.add(makePerfectRect(x,y,x2,y2));
            repaint();
        }
    }

    public void paintComponent(Graphics g) {
        // use Graphics2D, you can draw much nicer lines
        Graphics2D g2d = (Graphics2D) g;
        super.paintComponent(g);
        g.setColor(Color.RED);
        // draw the rectangle the user is currently drawing
        g2d.draw(makePerfectRect(x,y,x2,y2));
        g.setColor(Color.BLUE);

                Stroke oldStroke = g2d.getStroke();
        g2d.setStroke(new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0.0f));
        for (Rectangle2D r : rectangles) {
            g2d.draw(r);
        }
        g2d.setStroke(oldStroke); // restore the original Stroke
    }

}