Java 没有在JPanel上重新绘制行

Java 没有在JPanel上重新绘制行,java,swing,drawing,Java,Swing,Drawing,因此,我正在创建一个程序,允许用户在JPanel上绘制多个形状,类似于绘制程序。问题是,当我尝试向存储所有形状的ArrayList添加一行,然后在JPanel上重新绘制它们时,该行正在被存储,但没有被重新绘制 例如,假设我从顶部的JMenu中选择了line工具。然后单击并拖动鼠标,从单击的点到鼠标的当前位置,会出现一条线。我松开鼠标,线条仍然保留。当我去画另一条线,点击并拖动,第一条线消失后,我释放鼠标。我怎样才能得到它,使线路保持在JPanel上 import ... public clas

因此,我正在创建一个程序,允许用户在JPanel上绘制多个形状,类似于绘制程序。问题是,当我尝试向存储所有形状的ArrayList添加一行,然后在JPanel上重新绘制它们时,该行正在被存储,但没有被重新绘制

例如,假设我从顶部的JMenu中选择了line工具。然后单击并拖动鼠标,从单击的点到鼠标的当前位置,会出现一条线。我松开鼠标,线条仍然保留。当我去画另一条线,点击并拖动,第一条线消失后,我释放鼠标。我怎样才能得到它,使线路保持在JPanel上

import ...

public class GraphicsTest {

    public GraphicsTest() {
        JFrame frame = new JFrame("");
        Painter painter = new Painter();
        frame.setLayout(new BorderLayout());
    //  frame.setJMenuBar(painter.createMenuBar());
        frame.add(painter,BorderLayout.CENTER);        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(750,488);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new GraphicsTest();
            }
        });
    }

    public class Painter extends JPanel implements MouseListener, MouseMotionListener {
        private java.awt.geom.Line2D.Double line = new java.awt.geom.Line2D.Double();

        private List<Shape> shapeList = new ArrayList<Shape>();
        private List<Integer> opNumList = new ArrayList<Integer>();

        // Initial color
        private Color color = Color.black;

        // int variables that determine the position of various on-screen objects
        private int dragX = 0, dragY = 0, downX = 0, downY = 0, upX = 0, upY = 0;

        // Fields that determine which tool should be used
        private int PEN = 0, LINE = 1, RECTANGLE = 2, OVAL = 3;

        // Initial tool used
        private int toolNum = LINE;

        private Point clickPoint, releasePoint;

        /**
         * Sole and default constructor of this class
         **/
        public Painter() {
            // Adding listeners so that the mouse may be used to draw various objects
            addMouseListener(this);
            addMouseMotionListener(this);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int index = 0;
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setColor(color);

            if (toolNum == LINE) {
                g2.draw(new java.awt.geom.Line2D.Double(downX,downY,dragX,dragY));
            }

            System.out.println("Size: " + shapeList.size());
            if (!opNumList.isEmpty()) {
                for (Shape s : shapeList) {
              //    System.out.println("Index: " + index);
              //    System.out.println("Element: " + opNumList.get(index));
              //    System.out.println(s);
                    System.out.println();
                    switch (opNumList.get(index)) {
                        case 41: g2.setColor(Color.black);  g2.draw(s); break;
                        default: return;
                    }
                    index++;
                }
            }
        }

        /**
         * MouseListener interface methods
         **/
        @Override
        public void mouseClicked(MouseEvent ev) {}

        @Override
        public void mouseEntered(MouseEvent ev) {}

        @Override
        public void mouseExited(MouseEvent ev) {}

        @Override
        public void mousePressed(MouseEvent ev) {
            clickPoint = new Point(ev.getPoint());
            upX = ev.getX();
            upY = ev.getY();
            downX = ev.getX();
            downY = ev.getY();
        }

        @Override
        public void mouseReleased(MouseEvent ev) {
            upX = ev.getX();
            upY = ev.getY();
            releasePoint = new Point(ev.getPoint());

            line.x1 = clickPoint.x;
            line.y1 = clickPoint.y;
            line.x2 = releasePoint.x;
            line.y2 = releasePoint.y;

            if (toolNum == LINE)
                shapeList.add(line);

            if (color == Color.black) {
                if (toolNum == LINE)
                    opNumList.add(41);
            }
            repaint();
        }

        /**
         * MouseMotionListener interface methods
         **/
        @Override
        public void mouseMoved(MouseEvent ev) {}

        @Override
        public void mouseDragged(MouseEvent ev) {
            dragX = ev.getX();
            dragY = ev.getY();

            repaint();
        }
    }
}

您只能创建一个行的实例

然后更新该行的实例

这意味着shapeList中的每个条目都是相同的对象,具有相同的属性。所以,是的,您的代码正在绘制shapeList中的每一行,它只是多次绘制同一行

相反,每次要添加新行时,都要为其创建一个新实例

Line2D line = new java.awt.geom.Line2D.Double();
line.x1 = clickPoint.x;
line.y1 = clickPoint.y;
line.x2 = releasePoint.x;
line.y2 = releasePoint.y;

然后将其添加到shapeList…

有趣的。。。我没想到我会一直添加同一个线对象,只修改它们端点的坐标。谢谢
line.x1 = clickPoint.x;
line.y1 = clickPoint.y;
line.x2 = releasePoint.x;
line.y2 = releasePoint.y;
Line2D line = new java.awt.geom.Line2D.Double();
line.x1 = clickPoint.x;
line.y1 = clickPoint.y;
line.x2 = releasePoint.x;
line.y2 = releasePoint.y;