如何在面板上连续绘制形状?

时间:2019-05-26 00:52:22

标签: java swing

我一直在尝试连续绘制形状而不删除以前的形状,但是我一直坚持下去。

我也在此站点上尝试过DrawOnImage https://tips4java.wordpress.com/2009/05/08/custom-painting-approaches/

这就是下面的代码与该示例大部分相似的原因:

public class exo {
static class DrawingArea extends JPanel {

        private final static int AREA_SIZE = 600;
        private BufferedImage image = new BufferedImage(AREA_SIZE, AREA_SIZE, BufferedImage.TYPE_INT_ARGB);
        public CustomShape shape;
        public Shape s1;

    public DrawingArea() {
        setBackground(Color.WHITE);
        MyMouseListener ml = new MyMouseListener();
        addMouseListener(ml);
        addMouseMotionListener(ml);

    }

    class MyMouseListener extends MouseInputAdapter {

        private Point pointStart;
        private Point pointEnd;

        public void mousePressed(MouseEvent e) {
            pointStart = e.getPoint();
            s1 = null;
            shape = new CustomShape();
            //System.out.println(pointStart);
        }

        public void mouseDragged(MouseEvent e) {
            pointEnd = e.getPoint();
            shape.setX1(pointStart.x);
            shape.setX2(pointEnd.x);
            shape.setY1(pointStart.y);
            shape.setY2(pointEnd.y);

            s1 = drawInductor(shape.getX1(), shape.getX2(), shape.getY1(), shape.getY2());
            repaint();
        }

        public void mouseReleased(MouseEvent e) {
            //pointEnd = e.getPoint();
            if (shape.getX1() != shape.getX2()) {
                addShape(s1, e.getComponent().getForeground());
            }
            //s1 = null;
            //System.out.println(pointEnd);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return isPreferredSizeSet()
                ? super.getPreferredSize() : new Dimension(AREA_SIZE, AREA_SIZE);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        //  Custom code to support painting from the BufferedImage
        if (image != null) {
            g.drawImage(image, 0, 0, null);
        }

        //  Paint the Rectangle as the mouse is being dragged
        if (shape != null) {
            Graphics2D g2d = (Graphics2D) g;

            g2d.draw(s1);
        }
    }

    public void addShape(Shape s, Color color) {
        //  Draw the Rectangle onto the BufferedImage

        Graphics2D g2d = (Graphics2D) image.getGraphics();
        g2d.draw(s);
        repaint();
    }

}
public static Shape drawInductor(double X1, double X2, double Y1, double Y2) {
    int count = 0;
    final int dx = 7;
    final int dy = 8;
    float x1, y1, x2, y2, x3, y3;
    final double alpha = Math.toRadians(75.0);
    double phi = Math.atan2((Y2 - Y1), (X2 - X1));
    double dist = Math.sqrt(Math.pow((X1 - X2), 2) + Math.pow((Y1 - Y2), 2));

    GeneralPath path = new GeneralPath();
    double x = X1;
    double y = Y1;

    path.moveTo(x, y);
    x += (float) (0.3 * dist);
    y = Y1;
    path.lineTo(x, y);

    do {
        path.curveTo(x - dx / 2, y + dy, x + dx + dx / 2, y + dy, x + dx, y);
        x += dx;
        y = Y1;
        count++;
    } while (x < X1 + 0.7 * dist && count < 35);

    x = X1 + (float) dist;
    y = Y1;
    path.lineTo(x, y);

    AffineTransform at = new AffineTransform();
    at.rotate(phi, X1, Y1);
    Shape resShape = at.createTransformedShape(path);
    return (resShape);
}
public static void main(String args[]) throws Exception {
    JFrame f = new JFrame("Run MTFK");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(
            600, 600);
    f.setLocation(
            300, 300);
    f.setResizable(
            false);
    DrawingArea drawingArea = new DrawingArea();
    f.getContentPane().add(drawingArea);

    f.setVisible(true);

}
}

我想知道我的问题在哪里以及如何处理。 非常感谢你!

1 个答案:

答案 0 :(得分:1)

为了在面板上连续绘制零部件,需要始终绘制先前的零部件,然后再绘制最新的零部件。因此,如果您在添加这些对象时要说出“列表”,则假设您要显示它们时,将在每个对象之后调用重绘。

假设每个图像都用数字表示。

Create image 1, add it to list and repaint
This draws 1.
Create image 2, add it to the list and repaint
This redraws 1 and now draws 2
Create image 3, add it to the list and repaint
This redraws 1,2 and now draws 3.

因此,如果您有一个名为shape的列表,则paintComponent方法将具有 像这样的东西。

for (Shape s : shapes) {
   g.draw(s); // notice the casting Graphics g to Graphics2D gives you access to draw()
}

绘画和事件处理均在EDT上完成,因此保持活动最少。在该线程外进行尽可能多的计算。