import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.undo.*;
import javax.swing.event.*;public class UndoTest extends JFrame {
    protected Container pane;
    protected UndoAction undoAction=new UndoAction();
    protected RedoAction redoAction=new RedoAction();
    protected UndoManager undoManager=new UndoManager();
    public static void main(String args[]) {
        UndoTest ut=new UndoTest();
        // ut.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ut.setSize(400,300);
        ut.setVisible(true);
    }
    public void BuildLayout() {
        pane=getContentPane();
        JMenuBar jmb=new JMenuBar();
        JMenu jm=new JMenu("Edit");
        jm.add(new JMenuItem("Test"));
        jm.add(new JMenuItem("Test2"));
        jm.add(undoAction);
        jm.add(redoAction);
        jmb.add(jm);
        this.setJMenuBar(jmb);        JTextField textfield=new JTextField(10);
        createUndoListener(textfield.getDocument());
        pane.setLayout(new BorderLayout());
        pane.add(textfield,BorderLayout.SOUTH);
        undoAction.refreshUndoState();
        redoAction.refreshRedoState();
        this.validate();
    }    protected void createUndoListener(Document document) {
        document.addUndoableEditListener(new UndoableEditListener() {
            public void undoableEditHappened(UndoableEditEvent uee){
                undoManager.addEdit(uee.getEdit());
                undoAction.refreshUndoState();
                redoAction.refreshRedoState();            }        });
    }    class UndoAction extends AbstractAction {
        public UndoAction() {
            super("Undo");
        }
        public void actionPerformed(ActionEvent event) {
            try {
                undoManager.undo();
            } catch (CannotUndoException cue) {
                JOptionPane.showMessageDialog(pane,"Unable to Undo:"+cue);            }
            refreshUndoState();
            redoAction.refreshRedoState();
        }
        protected void refreshUndoState() {
            if (undoManager.canUndo()) {
                setEnabled(true);
                putValue(Action.NAME,undoManager.getUndoPresentationName());
            }
            else {
                setEnabled(false);
                putValue(Action.NAME,"Undo");
            }        }
    }    class RedoAction extends AbstractAction {
        public  RedoAction() {
            super("Redo");
        }
        public void actionPerformed(ActionEvent event) {
            try {
                undoManager.redo();
            }  catch(CannotRedoException cre) {
                JOptionPane.showMessageDialog(pane,"Unable to redo:"+cre);
            }
            refreshRedoState();
            undoAction.refreshUndoState();
        }
        protected void refreshRedoState() {
            if (undoManager.canRedo()) {
                setEnabled(true);
                putValue(Action.NAME,undoManager.getRedoPresentationName());            }
            else {
                setEnabled(false);
                putValue(Action.NAME,"Redo");
            }
        }
    }    public UndoTest()
    {
        BuildLayout();
    }}