Methods Summary |
---|
public synchronized boolean | addEdit(javax.swing.undo.UndoableEdit anEdit)If inProgress, inserts anEdit at indexOfNextAdd, and removes
any old edits that were at indexOfNextAdd or later. The die
method is called on each edit that is removed is sent, in the
reverse of the order the edits were added. Updates
indexOfNextAdd.
If not inProgress , acts as a
CompoundEdit .
boolean retVal;
// Trim from the indexOfNextAdd to the end, as we'll
// never reach these edits once the new one is added.
trimEdits(indexOfNextAdd, edits.size()-1);
retVal = super.addEdit(anEdit);
if (inProgress) {
retVal = true;
}
// Maybe super added this edit, maybe it didn't (perhaps
// an in progress compound edit took it instead. Or perhaps
// this UndoManager is no longer in progress). So make sure
// the indexOfNextAdd is pointed at the right place.
indexOfNextAdd = edits.size();
// Enforce the limit
trimForLimit();
return retVal;
|
public synchronized boolean | canRedo()Overridden to preserve usual semantics: returns true if a redo
operation would be successful now, false otherwise
if (inProgress) {
UndoableEdit edit = editToBeRedone();
return edit != null && edit.canRedo();
} else {
return super.canRedo();
}
|
public synchronized boolean | canUndo()Overridden to preserve usual semantics: returns true if an undo
operation would be successful now, false otherwise
if (inProgress) {
UndoableEdit edit = editToBeUndone();
return edit != null && edit.canUndo();
} else {
return super.canUndo();
}
|
public synchronized boolean | canUndoOrRedo()Return true if calling undoOrRedo will undo or redo. Suitable
for deciding to enable a command that toggles between the two
functions, which only makes sense to use if limit == 1.
if (indexOfNextAdd == edits.size()) {
return canUndo();
} else {
return canRedo();
}
|
public synchronized void | discardAllEdits()Empty the undo manager, sending each edit a die message
in the process.
Enumeration cursor = edits.elements();
while (cursor.hasMoreElements()) {
UndoableEdit e = (UndoableEdit)cursor.nextElement();
e.die();
}
edits = new Vector(limit);
indexOfNextAdd = 0;
// PENDING(rjrjr) when vector grows a removeRange() method
// (expected in JDK 1.2), trimEdits() will be nice and
// efficient, and this method can call that instead.
|
protected javax.swing.undo.UndoableEdit | editToBeRedone()Returns the the next significant edit to be redone if redo is
called. May return null
int count = edits.size();
int i = indexOfNextAdd;
while (i < count) {
UndoableEdit edit = (UndoableEdit)edits.elementAt(i++);
if (edit.isSignificant()) {
return edit;
}
}
return null;
|
protected javax.swing.undo.UndoableEdit | editToBeUndone()Returns the the next significant edit to be undone if undo is
called. May return null
int i = indexOfNextAdd;
while (i > 0) {
UndoableEdit edit = (UndoableEdit)edits.elementAt(--i);
if (edit.isSignificant()) {
return edit;
}
}
return null;
|
public synchronized void | end()Sending end() to an UndoManager turns it into a plain old
(ended) CompoundEdit.
Calls super's end() method (making inProgress false), then
sends die() to the unreachable edits at indexOfNextAdd and
beyond, in the reverse of the order in which they were added.
super.end();
this.trimEdits(indexOfNextAdd, edits.size()-1);
|
public synchronized int | getLimit()Returns the maximum number of edits this UndoManager will
hold. Default value is 100.
return limit;
|
public synchronized java.lang.String | getRedoPresentationName()If inProgress, returns getRedoPresentationName of the
significant edit that will be redone when redo() is invoked.
If there is none, returns AbstractUndoableEdit.redoText from the
defaults table.
If not inProgress, acts as a CompoundEdit
if (inProgress) {
if (canRedo()) {
return editToBeRedone().getRedoPresentationName();
} else {
return UIManager.getString("AbstractUndoableEdit.redoText");
}
} else {
return super.getRedoPresentationName();
}
|
public synchronized java.lang.String | getUndoOrRedoPresentationName()Return the appropriate name for a command that toggles between
undo and redo. Only makes sense to use such a command if limit
== 1 and we're not in progress.
if (indexOfNextAdd == edits.size()) {
return getUndoPresentationName();
} else {
return getRedoPresentationName();
}
|
public synchronized java.lang.String | getUndoPresentationName()If inProgress, returns getUndoPresentationName of the
significant edit that will be undone when undo() is invoked.
If there is none, returns AbstractUndoableEdit.undoText from the
defaults table.
If not inProgress, acts as a CompoundEdit
if (inProgress) {
if (canUndo()) {
return editToBeUndone().getUndoPresentationName();
} else {
return UIManager.getString("AbstractUndoableEdit.undoText");
}
} else {
return super.getUndoPresentationName();
}
|
public synchronized void | redo()If this UndoManager is inProgress ,
redoes the last significant UndoableEdit at
indexOfNextAdd or after, and all insignificant
edits up to it. Updates indexOfNextAdd accordingly.
If not inProgress , indexOfNextAdd
is ignored and super's routine is called.
if (inProgress) {
UndoableEdit edit = editToBeRedone();
if (edit == null) {
throw new CannotRedoException();
}
redoTo(edit);
} else {
super.redo();
}
|
protected void | redoTo(javax.swing.undo.UndoableEdit edit)Redoes all changes from indexOfNextAdd to edit. Updates indexOfNextAdd accordingly.
boolean done = false;
while (!done) {
UndoableEdit next = (UndoableEdit)edits.elementAt(indexOfNextAdd++);
next.redo();
done = next == edit;
}
|
public synchronized void | setLimit(int l)Set the maximum number of edits this UndoManager will hold. If
edits need to be discarded to shrink the limit, they will be
told to die in the reverse of the order that they were added.
if (!inProgress) throw new RuntimeException("Attempt to call UndoManager.setLimit() after UndoManager.end() has been called");
limit = l;
trimForLimit();
|
public java.lang.String | toString()Returns a string that displays and identifies this
object's properties.
return super.toString() + " limit: " + limit +
" indexOfNextAdd: " + indexOfNextAdd;
|
protected void | trimEdits(int from, int to)Tell the edits in the given range (inclusive) to die, and
remove them from edits. from > to is a no-op.
if (from <= to) {
// System.out.println("Trimming " + from + " " + to + " with index " +
// indexOfNextAdd);
for (int i = to; from <= i; i--) {
UndoableEdit e = (UndoableEdit)edits.elementAt(i);
// System.out.println("JUM: Discarding " +
// e.getUndoPresentationName());
e.die();
// PENDING(rjrjr) when Vector supports range deletion (JDK
// 1.2) , we can optimize the next line considerably.
edits.removeElementAt(i);
}
if (indexOfNextAdd > to) {
// System.out.print("...right...");
indexOfNextAdd -= to-from+1;
} else if (indexOfNextAdd >= from) {
// System.out.println("...mid...");
indexOfNextAdd = from;
}
// System.out.println("new index " + indexOfNextAdd);
}
|
protected void | trimForLimit()Reduce the number of queued edits to a range of size limit,
centered on indexOfNextAdd.
if (limit >= 0) {
int size = edits.size();
// System.out.print("limit: " + limit +
// " size: " + size +
// " indexOfNextAdd: " + indexOfNextAdd +
// "\n");
if (size > limit) {
int halfLimit = limit/2;
int keepFrom = indexOfNextAdd - 1 - halfLimit;
int keepTo = indexOfNextAdd - 1 + halfLimit;
// These are ints we're playing with, so dividing by two
// rounds down for odd numbers, so make sure the limit was
// honored properly. Note that the keep range is
// inclusive.
if (keepTo - keepFrom + 1 > limit) {
keepFrom++;
}
// The keep range is centered on indexOfNextAdd,
// but odds are good that the actual edits Vector
// isn't. Move the keep range to keep it legal.
if (keepFrom < 0) {
keepTo -= keepFrom;
keepFrom = 0;
}
if (keepTo >= size) {
int delta = size - keepTo - 1;
keepTo += delta;
keepFrom += delta;
}
// System.out.println("Keeping " + keepFrom + " " + keepTo);
trimEdits(keepTo+1, size-1);
trimEdits(0, keepFrom-1);
}
}
|
public synchronized void | undo()If this UndoManager is inProgress, undo the last significant
UndoableEdit before indexOfNextAdd, and all insignificant edits back to
it. Updates indexOfNextAdd accordingly.
If not inProgress, indexOfNextAdd is ignored and super's routine is
called.
if (inProgress) {
UndoableEdit edit = editToBeUndone();
if (edit == null) {
throw new CannotUndoException();
}
undoTo(edit);
} else {
super.undo();
}
|
public synchronized void | undoOrRedo()Undo or redo as appropriate. Suitable for binding to an action
that toggles between these two functions. Only makes sense
to send this if limit == 1.
if (indexOfNextAdd == edits.size()) {
undo();
} else {
redo();
}
|
protected void | undoTo(javax.swing.undo.UndoableEdit edit)Undoes all changes from indexOfNextAdd to edit. Updates indexOfNextAdd accordingly.
boolean done = false;
while (!done) {
UndoableEdit next = (UndoableEdit)edits.elementAt(--indexOfNextAdd);
next.undo();
done = next == edit;
}
|
public void | undoableEditHappened(javax.swing.event.UndoableEditEvent e)Called by the UndoabledEdit sources this UndoManager listens
to. Calls addEdit with e.getEdit().
addEdit(e.getEdit());
|