Java tutorial
import java.util.Enumeration; import java.util.Vector; import javax.swing.undo.AbstractUndoableEdit; import javax.swing.undo.CannotRedoException; import javax.swing.undo.CannotUndoException; import javax.swing.undo.UndoManager; import javax.swing.undo.UndoableEdit; public class UndoManagerDetails { public static void main(String[] args) { UndoManager mgr = new UndoManager(); mgr.addEdit(new SampleUndoableEdit(1, false, true, false)); mgr.addEdit(new SampleUndoableEdit(2, false, true, false)); mgr.addEdit(new SampleUndoableEdit(3, false, false, false)); mgr.addEdit(new SampleUndoableEdit(4, false, false, false)); System.out.println("Insignificant edit example"); mgr.undo(); mgr.redo(); System.out.println(mgr.canRedo()); // No more sig. edits // Show how edits that call add/replace are used. // // # adds? sig? replace? mgr.addEdit(new SampleUndoableEdit(5, true, true, false)); mgr.addEdit(new SampleUndoableEdit(6, false, true, false)); System.out.println("Absorbed (by addEdit) edit example"); mgr.undo(); mgr.discardAllEdits(); // # adds? sig? replace? mgr.addEdit(new SampleUndoableEdit(1, false, true, false)); mgr.addEdit(new SampleUndoableEdit(2, false, true, true)); System.out.println("Absorbed (by replaceEdit) edit example"); mgr.undo(); System.out.println(mgr.canUndo()); // Show how changing limit works. mgr.discardAllEdits(); // # adds? sig? replace? mgr.addEdit(new SampleUndoableEdit(1, false, true, false)); mgr.addEdit(new SampleUndoableEdit(2, false, true, false)); mgr.addEdit(new SampleUndoableEdit(3, false, true, false)); mgr.addEdit(new SampleUndoableEdit(4, false, true, false)); mgr.addEdit(new SampleUndoableEdit(5, false, true, false)); mgr.addEdit(new SampleUndoableEdit(6, false, true, false)); System.out.println("Changing limit example"); mgr.undo(); mgr.undo(); mgr.undo(); // Now 3 undoable, 3 redoable mgr.setLimit(4); // Now 2 undoable, 2 redoable! while (mgr.canUndo()) mgr.undo(); while (mgr.canRedo()) mgr.redo(); // undoOrRedo example mgr.discardAllEdits(); mgr.setLimit(1); // # adds? sig? replace? mgr.addEdit(new SampleUndoableEdit(1, false, true, false)); System.out.println("undoOrRedo example"); System.out.println(mgr.getUndoOrRedoPresentationName()); mgr.undoOrRedo(); System.out.println(mgr.getUndoOrRedoPresentationName()); mgr.undoOrRedo(); // Show how UndoManager becomes a CompositeEdit. mgr.discardAllEdits(); mgr.setLimit(100); // # adds? sig? replace? mgr.addEdit(new SampleUndoableEdit(1, false, true, false)); mgr.addEdit(new SampleUndoableEdit(2, false, true, false)); mgr.addEdit(new SampleUndoableEdit(3, false, true, false)); System.out.println("Transform to composite example"); mgr.end(); mgr.undo(); mgr.redo(); // Show that adds are no longer allowed. Note that addEdit() returns true in // pre-JDK 1.2 Swing releases. This is fixed in JDK 1.2. System.out.println(mgr.addEdit(new SampleUndoableEdit(4, false, true, false))); mgr.undo(); // note that edit 4 is not there } } class SampleUndoableEdit extends AbstractUndoableEdit { private boolean isSignificant; private boolean isReplacer; private int number; private boolean allowAdds; private Vector addedEdits; private UndoableEdit replaced; // Create a new edit with an identifying number. The boolean arguments define // the edit's behavior. public SampleUndoableEdit(int number, boolean allowAdds, boolean isSignificant, boolean isReplacer) { this.number = number; this.allowAdds = allowAdds; if (allowAdds) addedEdits = new Vector(); this.isSignificant = isSignificant; this.isReplacer = isReplacer; } // "Undo" the edit by printing a message to the screen. public void undo() throws CannotUndoException { super.undo(); System.out.print("Undo " + number); dumpState(); } // "Redo" the edit by printing a message to the screen. public void redo() throws CannotRedoException { super.redo(); System.out.print("Redo " + number); dumpState(); } // If allowAdds is true, we store the input edit. If not, just return false. public boolean addEdit(UndoableEdit anEdit) { if (allowAdds) { addedEdits.addElement(anEdit); return true; } else return false; } // If isReplacer is true, we store the edit we are replacing. public boolean replaceEdit(UndoableEdit anEdit) { if (isReplacer) { replaced = anEdit; return true; } else return false; } // Significance is based on constructor parameter. public boolean isSignificant() { return isSignificant; } // Just return our identifier. public String toString() { return "<" + number + ">"; } // Debug output. public void dumpState() { if (allowAdds && addedEdits.size() > 0) { Enumeration e = addedEdits.elements(); System.out.print(" (absorbed: "); while (e.hasMoreElements()) { System.out.print(e.nextElement()); } System.out.print(")"); } if (isReplacer && replaced != null) { System.out.print(" (replaced: " + replaced + ")"); } System.out.println(); } }