Java awt`Graphics`对象的撤消和重做方法

Java awt`Graphics`对象的撤消和重做方法,java,swing,graphics,paintcomponent,undo-redo,Java,Swing,Graphics,Paintcomponent,Undo Redo,我正在制作这个简单的画笔类型的绘画工具箱(在我的问题中有一些有趣的想法) 它目前运行良好,但我开始怀疑是否可以为图形对象实现撤消和重做方法。直观地说,应该有某种方法将创建的对象按“历史”顺序添加到某个表中。然后,用户应该能够在此表中导航 不幸的是,我没有使用这种方法的经验,尤其是在图形方面,所以任何建议都是非常受欢迎的。请看一下。我认为javaworld的文章对此进行了很好的解释 简而言之,您必须有一个包含undo和redo的接口。实现此功能的对象将添加到列表中。在撤消和重做时,可以在调用撤消和

我正在制作这个简单的画笔类型的绘画工具箱(在我的问题中有一些有趣的想法)

它目前运行良好,但我开始怀疑是否可以为
图形
对象实现撤消和重做方法。直观地说,应该有某种方法将创建的对象按“历史”顺序添加到某个表中。然后,用户应该能够在此表中导航

不幸的是,我没有使用这种方法的经验,尤其是在图形方面,所以任何建议都是非常受欢迎的。

请看一下。我认为javaworld的文章对此进行了很好的解释


简而言之,您必须有一个包含undo和redo的接口。实现此功能的对象将添加到列表中。在撤消和重做时,可以在调用撤消和重做的列表中导航。这意味着您可能需要编写更多的代码,因为对于您实际绘制的每个事件,您都必须编写相应的代码才能撤销它。

我建议您使用UndoManager

另请参见示例

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class MainClass2{
    static JLabel colorlabel = new JLabel(" Color ");
    public static JLabel xlab = new JLabel("0");
    public static JLabel ylab = new JLabel("0");

    static JFrame frame1 = new JFrame();
    static JButton quitbutton = new JButton("Quit");
    static JButton infobutton = new JButton("Info");
    static JButton clearbutton = new JButton("Clear");
    static JButton savebutton = new JButton("Save");
    private static int stroke1 = 4;
    static SpinnerNumberModel spinnervals = new SpinnerNumberModel(stroke1,1,15,1);

    static JSpinner spinnerbrush = new JSpinner(spinnervals);

    static JButton selectcolor = new JButton("Select Color");
    static JButton selectbg = new JButton("Select Background");
    public static Color col1 = Color.WHITE;
    private static Color col2 = Color.WHITE;

    static AuxClass4 panel1 = new AuxClass4(col1, col2, stroke1); 

    static JPanel panel2 = new JPanel();
    static JPanel panel3 = new JPanel();
    static JPanel panel4 = new JPanel();

    private static void addPanel1(){

        panel1.setPreferredSize(new Dimension(800,500));
    }
    private static void addPanel2(){
        ButtonAction inst1 = new ButtonAction();
        xlab.setMinimumSize(new Dimension(30,30));
        ylab.setMinimumSize(new Dimension(30,30));
        xlab.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        ylab.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        panel2.add(new JLabel(" X: "));
        panel2.add(xlab);
        panel2.add(new JLabel(" Y: "));
        panel2.add(ylab);

        panel2.add(savebutton);
        panel2.add(clearbutton);
        panel2.add(quitbutton);
        panel2.add(infobutton);
        panel2.setLayout(new FlowLayout());

        quitbutton.addActionListener(inst1);
        infobutton.addActionListener(inst1);
        clearbutton.addActionListener(inst1);
        savebutton.addActionListener(inst1);

        selectcolor.addActionListener(inst1);
        selectbg.addActionListener(inst1);
    }
    //add to panel3
    private static void addPanel3(){
        StrokeAction inst2 = new StrokeAction();
        spinnerbrush.addChangeListener(inst2);
        panel3.add(new JLabel("Stroke size"));
        panel3.add(spinnerbrush);
        panel3.add(selectcolor);
        panel3.add(new JLabel("Current color:"));
        colorlabel.setSize(20, 20);
        colorlabel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
        colorlabel.setOpaque(true);
        colorlabel.setBackground(Color.WHITE);
        colorlabel.setForeground(Color.WHITE);
        panel3.add(colorlabel);
        panel3.add(selectbg);

    }

    private static class ButtonAction implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent arg0) {
            if (arg0.getSource()==quitbutton){
                System.exit(0);
            }
            else if(arg0.getSource()==infobutton){
                JOptionPane.showMessageDialog(frame1, "Paint Toolbox designed in Java");
            }
            else if(arg0.getSource()==selectcolor){

                panel1.changeColor();

            }
            else if(arg0.getSource()==selectbg){
                panel1.changeBg();
            }
            else if(arg0.getSource()==clearbutton){
                panel1.colfg = panel1.colbg;
                colorlabel.setBackground(panel1.colfg);
                colorlabel.setForeground(panel1.colfg);
                panel1.setForeground(null);

            }
            else if(arg0.getSource()==savebutton){
                panel1.saveImage();
            }

        }

    }

    private static class StrokeAction implements ChangeListener{

        @Override
        public void stateChanged(ChangeEvent arg0) {
            if (arg0.getSource()==spinnerbrush){
                Object o1 = spinnervals.getValue();
                Integer int1 = (Integer) o1;
                stroke1 = int1.intValue();
                panel1.changeStroke(stroke1);
            }

            // TODO Auto-generated method stub      
        }

    }

    public static void main(String args[]){

        addPanel1();
        addPanel2();
        addPanel3();
        frame1.add(panel1, BorderLayout.NORTH);
        frame1.add(panel2, BorderLayout.SOUTH);
        frame1.add(panel3, BorderLayout.CENTER);
        frame1.setTitle("PaintBox v2.2");
        frame1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame1.setSize(800,600);
        frame1.setResizable(false);
        frame1.setLocationRelativeTo(null);
        frame1.setVisible(true);

    }

}

class AuxClass4 extends JPanel implements MouseMotionListener{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private int xval;
    private int yval;
    public Color colfg;
    public Color colbg;
    public int strokesize;
    public int fileorder;


    public AuxClass4(Color input1, Color input2, int input3){
        colfg=input1;
        colbg=input2;
        strokesize = input3;
        this.setBorder(BorderFactory.createLineBorder(Color.CYAN, 10));
        this.setBackground(colbg);
        //this.setMaximumSize(new Dimension(500,380));
        this.addMouseMotionListener(this);

    }

    public void paintComponent(Graphics g1){
        super.paintComponent(g1);
        g1.setColor(colfg);
        g1.fillRect(xval, yval, strokesize, strokesize);

    }

    @Override
    public void mouseDragged(MouseEvent arg0) {
        xval = arg0.getX();
        yval = arg0.getY();
        repaint(xval, yval, strokesize,strokesize);

        // TODO Auto-generated method stub

    }

    @Override
    public void mouseMoved(MouseEvent arg0) {
        xval = arg0.getX();
        yval = arg0.getY();
        String xvalret = Integer.toString(xval);
        String yvalret = Integer.toString(yval);
        MainClass2.xlab.setText(" " + xvalret + " ");
        MainClass2.ylab.setText(" " + yvalret + " ");

    }
    public void changeColor(){
        colfg = JColorChooser.showDialog(this, "Select color", colfg);
        MainClass2.colorlabel.setBackground(colfg);
        MainClass2.colorlabel.setForeground(colfg); 
    }

    public void changeBg(){
        colbg=JColorChooser.showDialog(this, "Select color", Color.WHITE);
        colfg=colbg;
        this.setBackground(colbg);
        MainClass1.colorlabel.setBackground(colfg); 
        MainClass1.colorlabel.setForeground(colfg); 


    }

    public void changeStroke(int inputstroke){
        strokesize=inputstroke;
    }

    public void saveImage(){
        final String dir = System.getProperty("user.dir");
        JOptionPane.showMessageDialog(this, "File saved under " + dir + "/saveimage" + fileorder +".png");
        fileorder+=1;

    }

}