java - 在 Swing 面板上绘制多个矩形

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

最佳答案

不要在paintComponent中执行任何代码逻辑——该方法仅用于绘图,这就是错误的根源。释放鼠标时,将矩形添加到鼠标监听器中的 ArrayList。

当我完成一个类似的项目时,我通常有一个矩形字段,用于在鼠标拖动时通过鼠标监听器进行绘制,并且在 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());
    }
}

关于java - 在 Swing 面板上绘制多个矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37333936/

相关文章:

java - 使用 JAX-RS 和 Jackson 将 JPA 实体转换为 REST 表示的最佳方法

java - 为什么 JDateChooser 收不到焦点事件

java - 在我的框架中使用 GroupLayout

java - 在一个构建中支持 Swing Applet 和 Frame

java - 从滚动 Pane 中的文本 Pane 获取文本

java - 从内容 URI 获取目录路径

java - 如何使用 jOOQ 执行特定查询

javaPOS 将库添加到项目中

java - 如何在鼠标退出事件一定毫秒数后取消选择 jList 中的项目

java - 我的程序在 Eclipse 中读取 .txt 文件,但当我导出为 .jar 时却无法读取?