撤消JFrame中图形的按钮

Dan*_*nny 1 java user-interface swing

我正在绘制一些物体,JFrame如圆形,矩形和它们之间的弧形.

我想知道如何实现一个撤销按钮,记住我发现的那些按钮是针对文本字段并在其中写入的.

我没有要显示的代码,我希望收到有关如何实现它的建议.是否可以"注册"最后发生的事件然后将其删除?

我有一个关于删除圆圈的非常简单的代码.它只适用于他们,我知道这是完全错误的,因为我可以有其他事件,如矩形绘制或它们之间的弧.

任何帮助表示赞赏.

Arn*_*aud 5

您可以将Shape对象存储在a中List,让面板从中绘制每个形状List.

"撤消"操作只是删除最后一个元素并重新绘制面板.

下面的示例包含用于在随机位置创建矩形和椭圆的按钮,以及着名的"撤消"按钮,以便您了解该想法.

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolBar;

public class DrawingUndo {

    List<Shape> shapes = new ArrayList<>();

    public DrawingUndo() {

        final Random randomizer = new Random();

        JFrame frame = new JFrame("Undoable drawings");

        JToolBar bar = new JToolBar();

        final JPanel undoPanel = new UndoPanel();

        JButton addRectangleButton = new JButton("Rectangle");
        addRectangleButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {

                int randomX = 5 + randomizer.nextInt(100);
                int randomY = 5 + randomizer.nextInt(100);
                Rectangle shape = new Rectangle();
                shape.setBounds(randomX, randomY, 30, 20);
                shapes.add(shape);
                undoPanel.repaint();

            }
        });

        JButton addEllipseButton = new JButton("Ellipse");

        addEllipseButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {

                int randomX = 5 + randomizer.nextInt(100);
                int randomY = 5 + randomizer.nextInt(100);
                Ellipse2D shape = new Ellipse2D.Double(randomX, randomY, 80, 30);
                shapes.add(shape);
                undoPanel.repaint();

            }
        });

        JButton undoButton = new JButton("Undo");

        undoButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(final ActionEvent e) {

                if (!shapes.isEmpty()) {

                    shapes.remove(shapes.size() - 1);
                    undoPanel.repaint();

                }

            }
        });

        bar.add(addRectangleButton);
        bar.add(addEllipseButton);
        bar.add(Box.createHorizontalGlue());
        bar.add(undoButton);

        frame.add(bar, BorderLayout.NORTH);
        frame.add(undoPanel, BorderLayout.CENTER);

        frame.setSize(400, 200);

        frame.setVisible(true);
    }

    public static void main(final String[] args) {

        new DrawingUndo();
    }

    private class UndoPanel extends JPanel {

        @Override
        public void paintComponent(final Graphics g) {

            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g;
            for (Shape shape : shapes) {

                g2d.draw(shape);// or g2d.fill(shape) to have its interior filled
            }
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

请注意,例如Shape没有像颜色这样的东西.

如果需要这样的东西,请创建一个包含Shape其他所需参数的包装类,并使用这种对象的列表而不是简单Shape对象.