我向形状 Arraylist 添加了一个矩形,但该形状不会显示在面板上

I added a rectangle to a shape Arraylist but the shape will not show up on the panel

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import java.util.ArrayList;

@SuppressWarnings("serial")
 public class GUI extends JFrame implements ActionListener, MouseListener {

    private boolean drawLine = false;
    private boolean drawRec = false;
    private boolean drawOval = false;
    private final JButton line;
    private final JButton oval;
    private final JButton rectangle;
    private final JPanel buttonPanel;
    public DrawStuff drawPanel = new DrawStuff();
    public int x1;
    public int x2;
    public int y1;
    public int y2;
    public int click;


     public GUI() {
        super("Graphics IO");
        this.click = 1;
        setSize(600, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1, 3));

        line = new JButton("Line");
        line.addActionListener(this);
        buttonPanel.add(line);

        oval = new JButton("Oval");
        oval.addActionListener(this);
        buttonPanel.add(oval);

        rectangle = new JButton("Rectangle");
        rectangle.addActionListener(this);
        buttonPanel.add(rectangle);

        Container contentPane = this.getContentPane();
        contentPane.add(buttonPanel, BorderLayout.SOUTH);
        //add(drawPanel);
        addMouseListener((MouseListener) this);

        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        Object source = event.getSource();

        if (source == line) {
            drawLine = true;
            repaint();
        } else if (source == oval) {

            drawOval = true;
            repaint();
        } else if (source == rectangle) {
            drawRec = true;
            repaint();
        }
    }

    public static void main(String[] args) {
        GUI guiIO = new GUI();

    }

    class DrawStuff extends JPanel {

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            this.setBackground(Color.BLUE);
            ArrayList<Shape> shapes = new ArrayList<>();

            if (drawLine) {
                drawLine = false;
            } else if (drawOval) {
                //no clue how to add an oval
                drawOval = false;
            } else if (drawRec) {
                Rectangle rec = new Rectangle(x1, y1,Math.abs(x2-x1) , Math.abs(y2-y1));
                shapes.add(rec);
                drawRec = false;
            }
            Graphics2D j = (Graphics2D)g;
            shapes.stream().map((s) -> {
                ((Graphics2D) j).draw((Shape) s);
                return s;
            }).forEach((_item) -> {
                repaint();
            });

    }
    }

    @Override
    public void mousePressed(MouseEvent me) {

        if (click == 1){
            x1 = me.getX();
            y1 = me.getY();
            System.out.println(x1);
            System.out.println(y1);
            click = 2;

        }else if (click == 2) {
            x2 = me.getX();
            y2 = me.getY();
            System.out.println(x2);
            System.out.println(y2);
            click = 1;
        }  


}
    @Override
    public void mouseReleased(MouseEvent e) {

    }
    @Override
    public void mouseEntered(MouseEvent e) {

    }
    @Override
    public void mouseExited(MouseEvent e) {

    }
    @Override
    public void mouseClicked(MouseEvent e) {

    }


    }

好的,所以我必须编写一个程序来使用两次鼠标单击来创建形状,然后才能 export/import 它们。我正在尝试为此使用 arraylist,但我很难让它工作。我创建的矩形不会显示在面板上。我究竟做错了什么?请帮助我。

让我们从 DrawStuff 实际上并没有被添加到任何能够绘制它的东西开始。

DrawStuff#paintComponent 应该决定更新 shapes List 的状态,相反,您的 ActionListenerMouseListener 应该做出这些决定(要添加什么,在哪里修改什么),DrawStuff 面板应该只是绘制 Shape 列表

中的内容

您也不应该在 paintComponent 中修改组件的状态,调用 setBackground 之类的东西可能会设置重复的重绘请求,如果不是您的 PC,这可能会削弱您的应用程序

修改 DrawStuff 使其拥有自己的 MouseListener 和允许您的 GUI 要求它创建新形状的方法。将 shapes List 设为实例字段,以便您可以更轻松地从 DrawStuff 内部进行管理

类似...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class GUI extends JFrame implements ActionListener {

    private boolean drawLine = false;
    private boolean drawRec = false;
    private boolean drawOval = false;
    private final JButton line;
    private final JButton oval;
    private final JButton rectangle;
    private final JPanel buttonPanel;
    public DrawStuff drawPanel = new DrawStuff();
    public int x1;
    public int x2;
    public int y1;
    public int y2;
    public int click;

    public GUI() {
        super("Graphics IO");
        this.click = 1;
        setSize(600, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1, 3));

        line = new JButton("Line");
        line.addActionListener(this);
        buttonPanel.add(line);

        oval = new JButton("Oval");
        oval.addActionListener(this);
        buttonPanel.add(oval);

        rectangle = new JButton("Rectangle");
        rectangle.addActionListener(this);
        buttonPanel.add(rectangle);

        Container contentPane = this.getContentPane();
        contentPane.add(buttonPanel, BorderLayout.SOUTH);
        add(drawPanel);

        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        Object source = event.getSource();

        if (source == line) {
            drawPanel.setDrawShape(DrawStuff.DrawShape.LINE);
        } else if (source == oval) {
            drawPanel.setDrawShape(DrawStuff.DrawShape.OVAL);
        } else if (source == rectangle) {
            drawPanel.setDrawShape(DrawStuff.DrawShape.RECTANGLE);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                GUI guiIO = new GUI();
            }
        });
    }

    public static class DrawStuff extends JPanel {

        public enum DrawShape {

            LINE, OVAL, RECTANGLE;
        }

        private ArrayList<Shape> shapes = new ArrayList<>();
        private DrawShape drawShape = DrawShape.LINE;
        private Shape currentShape;

        public DrawStuff() {
            setBackground(Color.BLUE);

            MouseAdapter ma = new MouseAdapter() {
                private Point clickPoint;

                @Override
                public void mousePressed(MouseEvent e) {
                    clickPoint = e.getPoint();
                    currentShape = null;
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                    if (currentShape != null) {
                        shapes.add(currentShape);
                        currentShape = null;
                        repaint();
                    }
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    Point p = e.getPoint();
                    switch (getDrawShape()) {
                        case LINE:
                            currentShape = new Line2D.Double(clickPoint, e.getPoint());
                            break;
                        case OVAL:
                        case RECTANGLE:
                            int x = clickPoint.x;
                            int y = clickPoint.y;
                            int width = p.x - clickPoint.x;
                            int height = p.y - clickPoint.y;

                            if (width < 0) {
                                x = p.x;
                                width *= -1;
                            }
                            if (height < 0) {
                                y = p.y;
                                height *= -1;
                            }
                            switch (getDrawShape()) {
                                case OVAL:
                                    currentShape = new Ellipse2D.Double(x, y, width, height);
                                    break;
                                case RECTANGLE:
                                    currentShape = new Rectangle2D.Double(x, y, width, height);
                                    break;
                            }
                            break;
                    }

                    repaint();
                }

            };

            addMouseListener(ma);
            addMouseMotionListener(ma);
        }

        public DrawShape getDrawShape() {
            return drawShape;
        }

        public void setDrawShape(DrawShape drawShape) {
            this.drawShape = drawShape;
            currentShape = null;
            repaint();
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.BLACK);

            for (Shape shape : shapes) {
                g2d.draw(shape);
            }

            if (currentShape != null) {

                g2d.setColor(Color.RED);
                g2d.draw(currentShape);

            }

        }
    }

}

例如。你总是需要问自己 "who is responsible for doing what"。在这种情况下 DrawStuff 面板实际上负责确定 "where" 绘制了一些东西,但它需要更多关于 "what" 的信息,然后根据该信息它可以执行实际操作