FileDocCategorySizeDatePackage
ExtendedUndoManager.javaAPI DocExample3168Mon Nov 09 12:45:50 GMT 1998None

ExtendedUndoManager.java

// ExtendedUndoManager.java
//
import javax.swing.event.*;
import javax.swing.undo.*;
import java.util.Enumeration;
import java.util.Vector;

// An extension of UndoManager that provides two additional features: 
// (1) The ability to add & remove listeners and (2) the ability to gain more
// extensive access to the edits being managed.
public class ExtendedUndoManager extends UndoManager
  implements UndoableEditListener {

  // Return the complete list of edits in an array.
  public synchronized UndoableEdit[] getEdits() {
    UndoableEdit[] array = new UndoableEdit[edits.size()];
    edits.copyInto(array);
    return array;
  }

  // Return all currently significant undoable edits. The first edit will be the
  // next one to be undone.
  public synchronized UndoableEdit[] getUndoableEdits() {
    int size = edits.size();
    Vector v = new Vector(size);
    for (int i=size-1;i>=0;i--) {
      UndoableEdit u = (UndoableEdit)edits.elementAt(i);
      if (u.canUndo() && u.isSignificant())
        v.addElement(u);
    }
    UndoableEdit[] array = new UndoableEdit[v.size()];
    v.copyInto(array);
    return array;
  }

  // Return all currently significant redoable edits. The first edit will be the
  // next one to be redone.
  public synchronized UndoableEdit[] getRedoableEdits() {
    int size = edits.size();
    Vector v = new Vector(size);
    for (int i=0; i<size; i++) {
      UndoableEdit u = (UndoableEdit)edits.elementAt(i);
      if (u.canRedo() && u.isSignificant())
        v.addElement(u);
    }
    UndoableEdit[] array = new UndoableEdit[v.size()];
    v.copyInto(array);
    return array;
  }
  // UndoableEditListener Method Support (ExtendedUndoManager.java, part 2)
  //

  // Add an edit and notify our listeners.
  public synchronized boolean addEdit(UndoableEdit anEdit) {
    boolean b = super.addEdit(anEdit);
    if (b)
      support.postEdit(anEdit); // if the edit was added, notify listeners
    return b;
  }

  // When an edit is sent to us, call addEdit() to notify any of our listeners.
  public synchronized void undoableEditHappened(UndoableEditEvent ev) {
    UndoableEdit ue = ev.getEdit();
    source = ev.getSource();
    addEdit(ue);
  }

  // Add a listener to be notified each time an edit is added to this manager.
  // This makes it easy to update undo/redo menus as edits are added.
  public synchronized void addUndoableEditListener(UndoableEditListener l) {
    support.addUndoableEditListener(l);
  }

  // Remove a listener from this manager.
  public synchronized void removeUndoableEditListener(UndoableEditListener l) {
    support.removeUndoableEditListener(l);
  }

  private ExtendedUndoableEditSupport support =
    new ExtendedUndoableEditSupport();

  private Object source; // the source of the last edit

  // A simple extension of UndoableEditSupport that lets us specify the event
  // source each time we post an edit.
  class ExtendedUndoableEditSupport extends UndoableEditSupport {

    // Post an edit to added listeners.
    public synchronized void postEdit(UndoableEdit ue) {
      realSource = source; // from our enclosing manager object
      super.postEdit(ue);
    }
  }
}