在Swing中在面板上绘制多个矩形

时间:2016-05-19 21:02:38

标签: java swing

我正在尝试在面板上绘制多个矩形。我创建了一个ArrayList<Shape>并在我的构造函数中初始化。在我的paintComponent方法中,我绘制一个矩形,然后将其添加到ArrayList。但是当我这样做时,我面板上的绘图结果变得奇怪。当我拖动绘制我的第一个矩形时,我得到了这个:

1]

这是我的代码的一部分:

public class MyMouseListener extends MouseAdapter {
    @Override
    public void mousePressed(final MouseEvent theEvent) {
        myStartPoint = theEvent.getPoint();
        repaint();

    }

    @Override
    public void mouseReleased(final MouseEvent theEvent) {
        myEndPoint = theEvent.getPoint();
        repaint();            
    }
}

public class MyMouseMotionHandler extends MouseMotionAdapter {
    @Override
    public void mouseDragged(final MouseEvent theEvent) {           
        myEndPoint = theEvent.getPoint();
        repaint(); 
    }       
}



/**
* Paints some rectangles.
* 
* @param theGraphics The graphics context to use for painting.
*/
@Override
public void paintComponent(final Graphics theGraphics) {
    super.paintComponent(theGraphics);
    final Graphics2D g2d = (Graphics2D) theGraphics;

    // for better graphics display
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                         RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setPaint(new Color(51, 0, 111));
    g2d.setStroke(new BasicStroke(3));

    final double x = myStartPoint.getX();
    final double y = myStartPoint.getY();
    final double xEnd = myEndPoint.getX();
    final double yEnd = myEndPoint.getY();

    if (xEnd> x && yEnd > y) { 
        final Shape rectangle = new Rectangle2D.
                Double(x, y, xEnd - x, yEnd - y);
        g2d.draw(rectangle);
        myDrawings.add(rectangle);
    }


    for (Shape s : myDrawings) {
        g2d.draw(s);
    }
}

1 个答案:

答案 0 :(得分:3)

不要在paintComponent中执行任何代码逻辑 - 该方法仅用于绘图和绘图,这是您的bug的来源。在鼠标释放时,将矩形添加到鼠标侦听器中的ArrayList。

当我完成一个类似的项目时,我通常会有一个Rectangle字段,我用它在鼠标拖动时用鼠标监听器绘制,并在paintComponent中绘制。然后在鼠标释放时,我将该矩形放入ArrayList,并将类字段设置为null。

如,

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

@SuppressWarnings("serial")
public class RectangleDraw extends JPanel {
    private static final int PREF_W = 800;
    private static final int PREF_H = 650;
    private static final Color TEMP_RECT_COLOR = Color.LIGHT_GRAY;
    private static final Color SHAPE_COLOR = Color.RED;
    private Rectangle tempRect = null;
    private List<Shape> shapes = new ArrayList<>();

    public RectangleDraw() {
        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        // draw the temporary rectangle if not null
        if (tempRect != null) {
            g2.setColor(TEMP_RECT_COLOR);
            g2.draw(tempRect);
        }

        // draw all the rectangles in the list
        g2.setColor(SHAPE_COLOR);
        for (Shape shape : shapes) {
            g2.draw(shape);
        }

    }

    // size the GUI to my specification
    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    // My mouse listener and mouse motion listener
    private class MyMouse extends MouseAdapter {
        private Point p1; // start point

        @Override
        public void mousePressed(MouseEvent e) {
            p1 = e.getPoint();
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            // create temporary rectangle
            tempRect = createRectangle(e);
            repaint();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            tempRect = null; // null temp rectangle and
            // add rectangle to List
            shapes.add(createRectangle(e));
            repaint();
        }

        // create a rectangle from start point and current point
        private Rectangle createRectangle(MouseEvent e) {
            Point p2 = e.getPoint();
            int x = Math.min(p1.x, p2.x);
            int y = Math.min(p1.y, p2.y);
            int w = Math.abs(p1.x - p2.x);
            int h = Math.abs(p1.y - p2.y);
            Rectangle rect = new Rectangle(x, y, w, h);
            return rect;
        }

    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("Rectangle Draw");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new RectangleDraw());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}