简体   繁体   English

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

[英]Drawing multiple rectangles on a panel in Swing

I'm trying to draw multiple rectangles on a panel. 我正在尝试在面板上绘制多个矩形。 I created an ArrayList<Shape> and initialized in my constructor. 我创建了一个ArrayList<Shape>并在构造函数中初始化。 In my paintComponent method, I draw a rectangle and then add it to the ArrayList . 在我的paintComponent方法中,我绘制了一个矩形,然后将其添加到ArrayList But when I do that, the drawing outcome on my panel turns out weird. 但是,当我这样做时,面板上的绘制结果却很奇怪。 As I drag to draw my first rectangle, I get this: 当我拖动以绘制第一个矩形时,得到以下信息:

1]

Here's part of my code: 这是我的代码的一部分:

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);
    }
}

Don't do any code logic within paintComponent -- that method is for drawing and drawing only, and that is the source of your bug. 不要在paintComponent内执行任何代码逻辑-该方法仅用于绘制和绘制,这是您的错误的来源。 Add the rectangle to the ArrayList in the mouse listener, on mouse release. 释放鼠标时,将矩形添加到鼠标侦听器中的ArrayList中。

When I have done a similar project, I usually have one Rectangle field that I use to draw with the mouse listener on mouse drag, and which is draw within paintComponent. 完成类似项目后,通常会有一个Rectangle字段,该字段用于在鼠标拖动时与鼠标侦听器一起绘制,并且在paintComponent中绘制。 Then on mouse release I place that rectangle into the ArrayList, and set the class field as null. 然后在释放鼠标时,将那个矩形放到ArrayList中,并将class字段设置为null。

eg, 例如,

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());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM