Chapter 35. The javax.swing.undo PackageThe classes and interfaces in this package form the undo framework for Swing applications. The UndoManager manages a list of UndoableEdit objects, each of which can be individually undone or redone. Any Swing application that wants to provide an undo capability will find this package useful. Figure 35-1 shows the class hierarchy of this package. Figure 35-1. The javax.swing.undo package
This class is a simple implementation of UndoableEdit. It enforces the restriction that an edit cannot be undone twice or redone without first being undone. Although the undo() and redo() methods do not actually undo or redo anything, subclasses should still call super.undo() and super.redo() in order to retain these restrictions. addEdit() and replaceEdit() return false; this implementation makes no attempt to merge events. getUndoPresentationName() and getRedoPresentationName() return the strings "Undo" and "Redo", followed by the string returned from getPresentationName(). Therefore, typical subclasses only need to override getPresentationName().
Hierarchy: Object-->AbstractUndoableEdit(Serializable,UndoableEdit) Subclasses: javax.swing.text.AbstractDocument.ElementEdit, javax.swing.text.DefaultStyledDocument.AttributeUndoableEdit, CompoundEdit, StateEdit
Signals that an UndoableEdit cannot be redone, perhaps because it has not been undone yet or because it has already been redone.
Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->CannotRedoException Thrown By: javax.swing.text.AbstractDocument.DefaultDocumentEvent.redo(), javax.swing.text.AbstractDocument.ElementEdit.redo(), javax.swing.text.DefaultStyledDocument.AttributeUndoableEdit.redo(), AbstractUndoableEdit.redo(), CompoundEdit.redo(), UndoableEdit.redo(), UndoManager.{redo(), redoTo(), undoOrRedo()}
Signals that an UndoableEdit cannot be undone, perhaps because it has already been undone.
Hierarchy: Object-->Throwable(Serializable)-->Exception-->RuntimeException-->CannotUndoException Thrown By: javax.swing.text.AbstractDocument.DefaultDocumentEvent.undo(), javax.swing.text.AbstractDocument.ElementEdit.undo(), javax.swing.text.DefaultStyledDocument.AttributeUndoableEdit.undo(), AbstractUndoableEdit.undo(), CompoundEdit.undo(), UndoableEdit.undo(), UndoManager.{undo(), undoOrRedo(), undoTo()}
This class is a compound UndoableEdit that collects a group of UndoableEdit objects into a single object and allows them to be undone and redone as a group. After creating a CompoundEdit object, you use addEdit() to add UndoableEdit objects to it. When you are done adding edits, call end(). Once end() has been called, you can freely use the undo() and redo() methods. The isInProgress() method returns true if end() has not been called yet and edits are still being added. While CompoundEdit maintains a list of UndoableEdit objects to undo and redo, the addEdit() method does not simply add edits to this list. When a new edit is added, CompoundEdit first attempts to merge it with the previously added edit by calling the addEdit() and replaceEdit() methods of the individual UndoableEdit objects. If these methods fail to merge the two edits into one, the new edit is added to the list of edits. The isSignificant() method returns true if any of the edits on the list of edits is significant and returns false otherwise. getPresentationName() returns the name of the last edit on the list, if it has one.
Hierarchy: Object-->AbstractUndoableEdit(Serializable,UndoableEdit)-->CompoundEdit Subclasses: javax.swing.text.AbstractDocument.DefaultDocumentEvent, UndoManager Returned By: UndoableEditSupport.createCompoundEdit() Type Of: UndoableEditSupport.compoundEdit
This class is an UndoableEdit implementation that works with StateEditable objects. First, create a StateEdit object, passing the StateEditable object to be edited to the constructor (and optionally specifying a presentation name for the StateEdit). The constructor queries the initial state of the StateEditable object and saves it. Next, make your edits to the StateEditable object and then call the end() method on your StateEdit object. This method queries the edited state of the object and saves that state. StateEdit implements the undo() method by restoring the saved preedit state and implements the redo() method by restoring the saved postedit state. For efficiency, StateEdit removes duplicate state entries from the preedit and postedit hashtables, so only the state that changes is saved.
Hierarchy: Object-->AbstractUndoableEdit(Serializable,UndoableEdit)-->StateEdit
This interface defines methods that allow an object to save and restore its state to and from a java.util.Hashtable. Objects that are able to implement this interface can easily support undo management with the StateEdit class.
Passed To: StateEdit.{init(), StateEdit()} Type Of: StateEdit.object
This interface defines methods that encapsulate an undoable and redoable change to the state of an application or component. The undo() and redo() methods are the most important: they must actually undo and redo the edit. They throw exceptions if an edit is undone twice or redone twice or if for some other reason an edit cannot be undone or redone. canUndo() and canRedo() specify whether an UndoableEdit can currently be undone or redone. die() tells an edit that it is no longer needed, so it can release any resources it is holding. Neither undo() nor redo() should be called once die() has been called. getPresentationName() returns a human-readable description of the edit. getUndoPresentationName() and getRedoPresentationName() return human-readable descriptions of undoing and redoing the edit. These two methods are usually implemented in terms of getPresentationName() and might return strings like "Undo typing" or "Redo deletion". isSignificant() specifies whether the edit is a significant one. Typically, significant edits are presented to the user in a user interface, while insignificant edits are simply undone and redone in conjunction with adjacent significant edits. The UndoManager class treats insignificant edits in this way, for example. addEdit() and replaceEdit() are used for merging two UndoableEdit objects into one. addEdit() is called to see if an existing UndoableEdit is willing to merge or absorb another edit into itself. For example, if the user strikes the Backspace key twice in a row, the UndoableEdit object generated by the first keystroke might absorb the UndoableEdit object generated by the second keystroke, changing itself from a "backspace 1" edit to a "backspace 2" edit. addEdit() should return true if it adds the edit and false otherwise. replaceEdit() has a similar purpose but operates in the other direction. It gives a new UndoableEdit object the opportunity to absorb and replace an existing UndoableEdit. For example, if the user of a text editor selects a paragraph of text and then deletes that paragraph, the "delete-paragraph" edit might simply subsume and replace the "select-paragraph" edit. replaceEdit() should return true if it replaces the specified UndoableEdit object.
Implementations: AbstractUndoableEdit Passed To: javax.swing.event.UndoableEditEvent.UndoableEditEvent(), javax.swing.text.AbstractDocument.DefaultDocumentEvent.addEdit(), AbstractUndoableEdit.{addEdit(), replaceEdit()}, CompoundEdit.addEdit(), UndoableEdit.{addEdit(), replaceEdit()}, UndoableEditSupport.{_postEdit(), postEdit()}, UndoManager.{addEdit(), redoTo(), undoTo()} Returned By: javax.swing.event.UndoableEditEvent.getEdit(), javax.swing.text.AbstractDocument.Content.{insertString(), remove()}, javax.swing.text.GapContent.{insertString(), remove()}, javax.swing.text.StringContent.{insertString(), remove()}, CompoundEdit.lastEdit(), UndoManager.{editToBeRedone(), editToBeUndone()}
This utility class is useful for classes that support undoable edits and send javax.swing.event.UndoableEditEvent events to javax.swing.event.UndoableEditListener objects. An object that generates undoable events must allow the registration and deregistration of event listeners for those events. Such an object can simply create an UndoableEditSupport object and delegate to its addUndoableEditListener() and removeUndoableEditListener() methods. UndoableEditSupport normally sends an UndoableEditEvent to all registered listeners when the postEdit() method is invoked. It also allows batching of edits into a CompoundEdit, however. If beginUpdate() is called, all UndoableEdit objects passed to postEdit() are batched into a CompoundEdit until endUpdate() is called. In this case, the UndoableEditEvent that contains the CompoundEdit is not sent to the registered UndoableEditListener objects until endUpdate() is invoked. If beginUpdate() is called more than once, endUpdate() must be called a matching number of times.
This class maintains a list of UndoableEdit objects and allows them to be undone and redone one significant edit at a time. Edits can be added explicitly by calling addEdit(). UndoManager implements the javax.swing.event.UndoableEditListener interface and automatically calls addEdit() to add an edit to its list when it receives a javax.swing.event.UndoableEditEvent. The addEdit() method works like the addEdit() method of CompoundEdit: it first attempts to merge the new edit with the last edit on the list by calling the addEdit() and replaceEdit() methods of those edits. The edit is added as a separate edit only if it could not be merged. After an edit is made and added to the UndoManager, the undo() method undoes it. After it is undone, the redo() method redoes it. However, if a new edit is made after the first is undone, that first undone edit is removed from the list and is no longer redoable. This is the normal and expected behavior for an undo system. UndoManager distinguishes between significant and insignificant edits. When you call undo(), it undoes all edits up to the last significant edit that occurred. When you call redo(), it redoes the next significant edit and all insignificant edits that follow it. A significant UndoableEdit is one whose isSignificant() method returns true. getUndoPresentationName() returns the undo presentation name of the significant UndoableEdit that is undone by undo(). getRedoPresentationName() returns the redo presentation name of the significant UndoableEdit that is performed by the redo() action. setLimit() and getLimit() set and query the maximum number of UndoableEdit objects that the UndoManager tracks. The default is 100. UndoManager is a subclass of CompoundEdit. If you call the end() method on an UndoManager, its behavior becomes that of a CompoundEdit and the list of edits is undone and redone all at once. This can occasionally be useful when doing nested edits.
Hierarchy: Object-->AbstractUndoableEdit(Serializable,UndoableEdit)-->CompoundEdit-->UndoManager(javax.swing.event.UndoableEditListener(java.util.EventListener)) Copyright © 2001 O'Reilly & Associates. All rights reserved. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|