2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-03-23 14:11:05 +08:00

StateEdit.java (getPresentationName): Docfix.

2003-11-26  Sascha Brawer  <brawer@dandelis.ch>

	* javax/swing/undo/StateEdit.java (getPresentationName): Docfix.
	* javax/swing/undo/AbstractUndoableEdit.java (canUndo, canRedo,
	isSignificant): Likewise.

2003-11-26  Sascha Brawer  <brawer@dandelis.ch>

	* javax/swing/undo/CompoundEdit.java: Re-format, document.
	(inProgress): Set initial value to true.
	(undo, redo, die, canUndo, canRedo): Also call inherited
	implementation; simplify code structure.
	(getPresentationName, getUndoPresentationName,
	getRedoPresentationName): Make behavior dependent on lastEdit.
	(addEdit, isSignificant): Completely re-written.

2003-11-26  Sascha Brawer  <brawer@dandelis.ch>

	* javax/swing/undo/StateEdit.java: Re-format, document.
	(undo, redo): Also call inherited implementation.

2003-11-26  Sascha Brawer  <brawer@dandelis.ch>

	* javax/swing/undo/StateEditable.java: Re-format, document.

2003-11-26  Sascha Brawer  <brawer@dandelis.ch>

	* javax/swing/undo/AbstractUndoableEdit.java: Re-format, document.
	(AbstractUndoableEdit): Initialize hasBeenDone to true.
	(canUndo, canRedo): Simplify.
	(getUndoPresentationName, getRedoPresentationName): Support
	localized message; call getPresentationName() only once.

From-SVN: r73967
This commit is contained in:
Sascha Brawer 2003-11-26 23:23:40 +01:00 committed by Michael Koch
parent 034f23169e
commit aef81a9acb
7 changed files with 814 additions and 430 deletions

@ -1,3 +1,36 @@
2003-11-26 Sascha Brawer <brawer@dandelis.ch>
* javax/swing/undo/StateEdit.java (getPresentationName): Docfix.
* javax/swing/undo/AbstractUndoableEdit.java (canUndo, canRedo,
isSignificant): Likewise.
2003-11-26 Sascha Brawer <brawer@dandelis.ch>
* javax/swing/undo/CompoundEdit.java: Re-format, document.
(inProgress): Set initial value to true.
(undo, redo, die, canUndo, canRedo): Also call inherited
implementation; simplify code structure.
(getPresentationName, getUndoPresentationName,
getRedoPresentationName): Make behavior dependent on lastEdit.
(addEdit, isSignificant): Completely re-written.
2003-11-26 Sascha Brawer <brawer@dandelis.ch>
* javax/swing/undo/StateEdit.java: Re-format, document.
(undo, redo): Also call inherited implementation.
2003-11-26 Sascha Brawer <brawer@dandelis.ch>
* javax/swing/undo/StateEditable.java: Re-format, document.
2003-11-26 Sascha Brawer <brawer@dandelis.ch>
* javax/swing/undo/AbstractUndoableEdit.java: Re-format, document.
(AbstractUndoableEdit): Initialize hasBeenDone to true.
(canUndo, canRedo): Simplify.
(getUndoPresentationName, getRedoPresentationName): Support
localized message; call getPresentationName() only once.
2003-11-26 David Belanger <dbelan2@cs.mcgill.ca>
* java/util/zip/ZipFile (Zipfile(File)): Set file path as name.

@ -1,4 +1,4 @@
/* AbstractTableModel.java --
/* AbstractUndoableEdit.java
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -39,180 +39,285 @@ exception statement from your version. */
package javax.swing.undo;
import java.io.Serializable;
import javax.swing.UIManager;
/**
* AbstractUndoableEdit
* @author Andrew Selkirk
* A default implementation of <code>UndoableEdit</code> that can be
* used as a base for implementing editing operations.
*
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public class AbstractUndoableEdit implements UndoableEdit, Serializable
public class AbstractUndoableEdit
implements UndoableEdit, Serializable
{
/**
* The serialization ID. Verified using the <code>serialver</code>
* tool of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5, and Sun JDK
* 1.4.1_01 on GNU/Linux.
*/
static final long serialVersionUID = 580150227676302096L;
//-------------------------------------------------------------
// Constants --------------------------------------------------
//-------------------------------------------------------------
/**
* String returned by getRedoPresentationName()
*/
protected static final String RedoName = "Redo";
/**
* String returned by getUndoPresentationName()
* The constant string &#x201c;Undo&#x201d;, which was returned by
* {@link #getUndoPresentationName()} on early versions of the
* platform. However, this field has become obsolete with version
* 1.3.1. That method now retrieves a localized string from the
* {@link javax.swing.UIManager}, using the key
* <code>&#x201c;AbstractUndoableEdit.undoText&#x201d;</code>.
*/
protected static final String UndoName = "Undo";
//-------------------------------------------------------------
// Variables --------------------------------------------------
//-------------------------------------------------------------
/**
* TODO
* The constant string &#x201c;Redo&#x201d;, which was returned by
* {@link #getRedoPresentationName()} on early versions of the
* platform. However, this field has become obsolete with version
* 1.3.1. That method now retrieves a localized string from the
* {@link javax.swing.UIManager}, using the key
* <code>&#x201c;AbstractUndoableEdit.redoText&#x201d;</code>.
*/
private boolean hasBeenDone = false;
protected static final String RedoName = "Redo";
/**
* The edit is alive
* Indicates whether this editing action has been executed. A value
* of <code>true</code> means that the action was performed, or that
* a redo operation was successful. A value of <code>false</code>
* means that the action has not yet performed, or that an undo
* operation was successful.
*/
private boolean alive = true;
private boolean hasBeenDone;
//-------------------------------------------------------------
// Initialization ---------------------------------------------
//-------------------------------------------------------------
/**
* Create new AbstractUndoableEdit
* Indicates whether this editing action is still alive. The value
* is set to <code>true</code> by the constructor, and to
* <code>false</code> by the {@link #die()} method.
*/
private boolean alive;
/**
* Constructs a new <code>AbstractUndoableEdit</code>. The initial
* state is that the editing action is alive, and
* <code>hasBeenDone</code> is <code>true</code>.
*/
public AbstractUndoableEdit()
{
} // AbstractUndoableEdit()
// The API specification is not clear, but Mauve test code has
// determined that hasBeenDone is initially set to true.
alive = hasBeenDone = true;
}
//-------------------------------------------------------------
// Interface: UndoableEdit ------------------------------------
//-------------------------------------------------------------
/**
* addEdit
* @param anEdit TODO
* @returns TODO
* Undoes this editing action.
*
* @throws CannotUndoException if {@link #canUndo()} returns
* <code>false</code>, for example because this action has already
* been undone.
*
* @see #canUndo()
* @see #redo()
*/
public boolean addEdit(UndoableEdit anEdit)
public void undo()
throws CannotUndoException
{
return false;
} // addEdit()
if (!canUndo())
throw new CannotUndoException();
hasBeenDone = false;
}
/**
* canRedo()
* @returns true if redoable, false otherwise
*/
public boolean canRedo()
{
if (alive == true && hasBeenDone == false)
return true;
return false;
} // canRedo()
/**
* canUndo()
* @returns true if undoable, false otherwise
* Determines whether it would be possible to undo this editing
* action.
*
* @return <code>true</code> to indicate that this action can be
* undone, <code>false</code> otherwise.
*
* @see #undo()
* @see #canRedo()
*/
public boolean canUndo()
{
if (alive == true && hasBeenDone == true)
return true;
return false;
} // canUndo()
return alive && hasBeenDone;
}
/**
* Redoes this editing action.
*
* @throws CannotRedoException if {@link #canRedo()} returns
* <code>false</code>, for example because this action has not
* yet been undone.
*
* @see #canRedo()
* @see #undo()
*/
public void redo()
throws CannotRedoException
{
if (!canRedo())
throw new CannotRedoException();
hasBeenDone = true;
}
/**
* Determines whether it would be possible to redo this editing
* action.
*
* @return <code>true</code> to indicate that this action can be
* redone, <code>false</code> otherwise.
*
* @see #redo()
* @see #canUndo()
*/
public boolean canRedo()
{
return alive && !hasBeenDone;
}
/**
* die
* Informs this edit action that it will no longer be used. Some
* actions might use this information to release resources, for
* example open files. Called by {@link UndoManager} before this
* action is removed from the edit queue.
*/
public void die()
{
alive = false;
} // die()
}
/**
* getPresentation
* @returns TODO
* Incorporates another editing action into this one, thus forming a
* combined action.
*
* <p>The default implementation always returns <code>false</code>,
* indicating that the editing action could not be incorporated.
*
* @param edit the editing action to be incorporated.
*/
public String getPresentationName()
public boolean addEdit(UndoableEdit edit)
{
return "";
} // getPresentationName()
return false;
}
/**
* getRedoPresentationName
* @returns TODO
* Incorporates another editing action into this one, thus forming a
* combined action that replaces the argument action.
*
* <p>The default implementation always returns <code>false</code>,
* indicating that the argument action should not be replaced.
*
* @param edit the editing action to be replaced.
*/
public String getRedoPresentationName()
public boolean replaceEdit(UndoableEdit edit)
{
if (getPresentationName().equals(""))
return RedoName;
return RedoName + " " + getPresentationName();
} // getRedoPresentationName()
return false;
}
/**
* getUndoPresentationName
* @returns TODO
*/
public String getUndoPresentationName()
{
if (getPresentationName().equals(""))
return UndoName;
return UndoName + " " + getPresentationName();
} // getUndoPresentationName()
/**
* isSignificant
* @returns true
* Determines whether this editing action is significant enough for
* being seperately undoable by the user. A typical significant
* action would be the resizing of an object. However, changing the
* selection in a text document would usually not be considered
* significant.
*
* <p>The default implementation returns <code>true</code>.
*
* @return <code>true</code> to indicate that the action is
* significant enough for being separately undoable, or
* <code>false</code> otherwise.
*/
public boolean isSignificant()
{
return true;
} // isSignificant()
}
/**
* redo
* @throws CannotRedoException TODO
* Returns a human-readable, localized name that describes this
* editing action and can be displayed to the user.
*
* <p>The default implementation returns an empty string.
*/
public void redo() throws CannotRedoException
public String getPresentationName()
{
if (! canRedo())
throw new CannotRedoException();
hasBeenDone = true;
} // redo()
/**
* replaceEdit
* @param anEdit TODO
* @returns TODO
*/
public boolean replaceEdit(UndoableEdit anEdit)
{
return false;
} // replaceEdit()
/**
* String representation
* @returns String representation
*/
public String toString()
{
return (super.toString() + " hasBeenDone: " + hasBeenDone
+ " alive: " + alive);
return "";
}
/**
* undo
* @throws CannotUndoException TODO
* Calculates a localized name for presenting the undo action to the
* user.
*
* <p>The default implementation returns the concatenation of the
* string &#x201c;Undo&#x201d; and the action name, which is
* determined by calling {@link #getPresentationName()}.
*
* <p>The string &#x201c;Undo&#x201d; is retrieved from the {@link
* javax.swing.UIManager}, using the key
* <code>&#x201c;AbstractUndoableEdit.undoText&#x201d;</code>. This
* allows the text to be localized.
*/
public void undo() throws CannotUndoException
public String getUndoPresentationName()
{
if (! canUndo())
throw new CannotUndoException();
hasBeenDone = false;
} // undo()
} // AbstractUndoableEdit
String msg, pres;
msg = UIManager.getString("AbstractUndoableEdit.undoText");
if (msg == null)
msg = UndoName;
pres = getPresentationName();
if ((pres == null) || (pres.length() == 0))
return msg;
else
return msg + ' ' + pres;
}
/**
* Calculates a localized name for presenting the redo action to the
* user.
*
* <p>The default implementation returns the concatenation of the
* string &#x201c;Redo&#x201d; and the action name, which is
* determined by calling {@link #getPresentationName()}.
*
* <p>The string &#x201c;Redo&#x201d; is retrieved from the {@link
* javax.swing.UIManager}, using the key
* <code>&#x201c;AbstractUndoableEdit.redoText&#x201d;</code>. This
* allows the text to be localized.
*/
public String getRedoPresentationName()
{
String msg, pres;
msg = UIManager.getString("AbstractUndoableEdit.redoText");
if (msg == null)
msg = RedoName;
pres = getPresentationName();
if ((pres == null) || (pres.length() == 0))
return msg;
else
return msg + ' ' + pres;
}
public String toString()
{
return super.toString()
+ " hasBeenDone: " + hasBeenDone
+ " alive: " + alive;
}
}

@ -1,5 +1,5 @@
/* AbstractTableModel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
/* CannotRedoException.java
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -38,17 +38,19 @@ exception statement from your version. */
package javax.swing.undo;
/**
* CannotRedoException
* @author Andrew Selkirk
* An exception which indicates that an editing action cannot be
* redone.
*
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public class CannotRedoException extends RuntimeException {
/**
* Create exception
*/
public CannotRedoException() {
super();
} // CannotRedoException()
} // CannotRedoException
public class CannotRedoException
extends RuntimeException
{
/**
* Constructs a new instance of a <code>CannotRedoException</code>.
*/
public CannotRedoException()
{
}
}

@ -1,5 +1,5 @@
/* AbstractTableModel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
/* CannotUndoException.java
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -37,18 +37,21 @@ exception statement from your version. */
package javax.swing.undo;
/**
* CannotUndoException
* @author Andrew Selkirk
* An exception which indicates that an editing action cannot be
* undone.
*
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public class CannotUndoException extends RuntimeException {
/**
* Create exception
*/
public CannotUndoException() {
super();
} // CannotUndoException()
} // CannotUndoException
public class CannotUndoException
extends RuntimeException
{
/**
* Constructs a new instance of a <code>CannotUndoException</code>.
*/
public CannotUndoException()
{
}
}

@ -1,5 +1,5 @@
/* AbstractTableModel.java --
Copyright (C) 2002 Free Software Foundation, Inc.
/* CompoundEdit.java -- Combines multiple UndoableEdits.
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -41,242 +41,352 @@ package javax.swing.undo;
import java.util.Vector;
/**
* CompoundEdit
* @author Andrew Selkirk
* An editing action that consists of multiple
* <code>UndoableEdits</code>.
*
* <p>The use of a <code>CompoundEdit</code> is divided in two separate
* phases.
*
* <ol><li>In the first phase, the <code>CompoundEdit</code> is
* initialized. After a new instance of <code>CompoundEdit</code> has
* been created, {@link #addEdit(UndoableEdit)} is called for each
* element of the compound. To terminate the initialization phase,
* call {@link #end()}.</li>
*
* <li>In the second phase, the the <code>CompoundEdit</code> can be
* used, typically by invoking {@link #undo()} and {@link
* #redo()}.</li></ol>
*
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public class CompoundEdit extends AbstractUndoableEdit {
//-------------------------------------------------------------
// Variables --------------------------------------------------
//-------------------------------------------------------------
/**
* The collection of UndoableEdits undone/redone en
* masse by this CompoundEdit
*/
protected Vector edits = new Vector();
/**
* TODO
*/
private boolean inProgress = false;
public class CompoundEdit
extends AbstractUndoableEdit
{
/**
* The <code>UndoableEdit</code>s being combined into a compound
* editing action.
*/
protected Vector edits;
//-------------------------------------------------------------
// Initialization ---------------------------------------------
//-------------------------------------------------------------
/**
* Create new Compound Edit
*/
public CompoundEdit() {
} // CompoundEdit()
/**
* Indicates whether the creation of this CompoundEdit is still in
* progress. Initially, the value of this flag is
* <code>true</code>. The {@link #end()} method changes the flag to
* <code>false</code>.
*/
private boolean inProgress;
//-------------------------------------------------------------
// Interface: UndoableEdit ------------------------------------
//-------------------------------------------------------------
/**
* Constructs a new CompoundEdit.
*/
public CompoundEdit()
{
edits = new Vector();
inProgress = true;
}
/**
* addEdit
* @param anEdit TODO
* @returns TODO
*/
public boolean addEdit(UndoableEdit anEdit) {
/**
* Undoes all edits that are part of of this
* <code>CompoundEdit</code>. The compound elements will receive the
* <code>undo</code> message in the reverse order of addition.
*
* @throws CannotUndoException if {@link #canUndo()} returns
* <code>false</code>. This can happen if {@link #end()} has not
* been called on this <code>CompoundEdit</code>, or if this edit
* has already been undone.
*
* @see #canUndo()
* @see #redo()
*/
public void undo()
throws CannotUndoException
{
// AbstractUndoableEdit.undo() will throw a CannotUndoException if
// canUndo returns false.
super.undo();
// Variables
UndoableEdit lastEdit;
if (inProgress == true) {
// Get Last Edit
lastEdit = lastEdit();
// Check for null
if (lastEdit != null) {
if (lastEdit.addEdit(anEdit) == false) {
if (lastEdit.replaceEdit(anEdit) == false) {
edits.add(anEdit);
}
}
} // if: lastEdit
return true;
} else {
return false;
}
} // addEdit()
/**
* canRedo
* @returns TODO
*/
public boolean canRedo() {
if (isInProgress() == true || super.canRedo() == false) {
return false;
}
return true;
} // canRedo()
/**
* canUndo
* @returns TODO
*/
public boolean canUndo() {
if (isInProgress() == true || super.canUndo() == false) {
return false;
}
return true;
} // canUndo()
/**
* die
*/
public void die() {
// Variables
int index;
UndoableEdit current;
// Loop through all contained UndoableEdits
for (index = edits.size() - 1; index >= 0; index--) {
current = (UndoableEdit) edits.elementAt(index);
current.die();
} // for: index
} // die()
/**
* end
*/
public void end() {
inProgress = false;
} // end()
/**
* getPresentationName
* @returns TODO
*/
public String getPresentationName() {
if (edits.size() == 0) {
return super.getPresentationName();
} else {
return lastEdit().getPresentationName();
}
} // getPresentationName()
/**
* getRedoPresentationName
* @returns TODO
*/
public String getRedoPresentationName() {
if (edits.size() == 0) {
return super.getRedoPresentationName();
} else {
return lastEdit().getRedoPresentationName();
}
} // getRedoPresentationName()
/**
* getUndoPresentationName
* @returns TODO
*/
public String getUndoPresentationName() {
if (edits.size() == 0) {
return super.getUndoPresentationName();
} else {
return lastEdit().getUndoPresentationName();
}
} // getUndoPresentationName()
/**
* isInProgress
* @returns TODO
*/
public boolean isInProgress() {
return inProgress;
} // isInProgress()
for (int i = edits.size() - 1; i >= 0; i--)
((UndoableEdit) edits.elementAt(i)).undo();
}
/**
* isSignigicant
* @returns TODO
*/
public boolean isSignificant() {
/**
* Redoes all edits that are part of of this
* <code>CompoundEdit</code>. The compound elements will receive the
* <code>undo</code> message in the same order as they were added.
*
* @throws CannotRedoException if {@link #canRedo()} returns
* <code>false</code>. This can happen if {@link #end()} has not
* been called on this <code>CompoundEdit</code>, or if this edit
* has already been redone.
*
* @see #canRedo()
* @see #undo()
*/
public void redo()
throws CannotRedoException
{
// AbstractUndoableEdit.redo() will throw a CannotRedoException if
// canRedo returns false.
super.redo();
// Variables
int index;
UndoableEdit current;
for (int i = 0; i < edits.size(); i++)
((UndoableEdit) edits.elementAt(i)).redo();
}
// Check each edit
for (index = 0; index < edits.size(); index++) {
current = (UndoableEdit) edits.elementAt(index);
if (current.isSignificant() == true) {
return true;
}
} // for: index
return false;
} // isSignificant()
/**
* lastEdit
* @returns TODO
*/
protected UndoableEdit lastEdit() {
if (edits.size() == 0) {
return null;
}
return (UndoableEdit) edits.elementAt(edits.size() - 1);
} // lastEdit()
/**
* redo
* @throws CannotRedoException TODO
*/
public void redo() throws CannotRedoException {
// Variables
int index;
UndoableEdit current;
// Loop through all contained UndoableEdits
for (index = 0; index < edits.size(); index++) {
current = (UndoableEdit) edits.elementAt(index);
current.redo();
} // for: index
} // redo()
/**
* String representation
* @returns String representation
*/
public String toString() {
return null; // TODO
} // toString()
/**
* undo
* @throws CannotUndoException TODO
*/
public void undo() throws CannotUndoException {
// Variables
int index;
UndoableEdit current;
// Loop through all contained UndoableEdits
for (index = edits.size() - 1; index >= 0; index--) {
current = (UndoableEdit) edits.elementAt(index);
current.undo();
} // for: index
} // undo()
/**
* Returns the the <code>UndoableEdit</code> that was last added to
* this compound.
*/
protected UndoableEdit lastEdit()
{
if (edits.size() == 0)
return null;
else
return (UndoableEdit) edits.elementAt(edits.size() - 1);
}
} // CompoundEdit
/**
* Informs this edit action, and all compound edits, that they will
* no longer be used. Some actions might use this information to
* release resources such as open files. Called by {@link
* UndoManager} before this action is removed from the edit queue.
*
* <p>The compound elements will receive the
* <code>die</code> message in the reverse order of addition.
*/
public void die()
{
for (int i = edits.size() - 1; i >= 0; i--)
((UndoableEdit) edits.elementAt(i)).die();
super.die();
}
/**
* Incorporates another editing action into this one, thus forming a
* combined edit.
*
* <p>If this edit&#x2019;s {@link #end()} method has been called
* before, <code>false</code> is returned immediately. Otherwise,
* the {@linkplain #lastEdit() last added edit} is given the
* opportunity to {@linkplain UndoableEdit#addEdit(UndoableEdit)
* incorporate} <code>edit</code>. If this fails, <code>edit</code>
* is given the opportunity to {@linkplain
* UndoableEdit#replaceEdit(UndoableEdit) replace} the last added
* edit. If this fails as well, <code>edit</code> gets added as a
* new compound to {@link #edits}.
*
* @param edit the editing action being added.
*
* @return <code>true</code> if <code>edit</code> could somehow be
* incorporated; <code>false</code> if <code>edit</code> has not
* been incorporated because {@link #end()} was called before.
*/
public boolean addEdit(UndoableEdit edit)
{
UndoableEdit last;
// If end has been called before, do nothing.
if (!inProgress)
return false;
last = lastEdit();
// If edit is the very first edit, just add it to the list.
if (last == null)
{
edits.add(edit);
return true;
}
// Try to incorporate edit into last.
if (last.addEdit(edit))
return true;
// Try to replace last by edit.
if (edit.replaceEdit(last))
{
edits.set(edits.size() - 1, edit);
return true;
}
// If everything else has failed, add edit to the list of compound
// edits.
edits.add(edit);
return true;
}
/**
* Informs this <code>CompoundEdit</code> that its construction
* phase has been completed. After this method has been called,
* {@link #undo()} and {@link #redo()} may be called, {@link
* #isInProgress()} will return <code>false</code>, and all attempts
* to {@linkplain #addEdit(UndoableEdit) add further edits} will
* fail.
*/
public void end()
{
inProgress = false;
}
/**
* Determines whether it would be possible to undo this editing
* action. The result will be <code>true</code> if {@link #end()}
* has been called on this <code>CompoundEdit</code>, {@link #die()}
* has not yet been called, and the edit has not been undone
* already.
*
* @return <code>true</code> to indicate that this action can be
* undone; <code>false</code> otherwise.
*
* @see #undo()
* @see #canRedo()
*/
public boolean canUndo()
{
return !inProgress && super.canUndo();
}
/**
* Determines whether it would be possible to redo this editing
* action. The result will be <code>true</code> if {@link #end()}
* has been called on this <code>CompoundEdit</code>, {@link #die()}
* has not yet been called, and the edit has not been redone
* already.
*
* @return <code>true</code> to indicate that this action can be
* redone; <code>false</code> otherwise.
*
* @see #redo()
* @see #canUndo()
*/
public boolean canRedo()
{
return !inProgress && super.canRedo();
}
/**
* Determines whether the initial construction phase of this
* <code>CompoundEdit</code> is still in progress. During this
* phase, edits {@linkplain #addEdit(UndoableEdit) may be
* added}. After initialization has been terminated by calling
* {@link #end()}, {@link #undo()} and {@link #redo()} can be used.
*
* @return <code>true</code> if the initialization phase is still in
* progress; <code>false</code> if {@link #end()} has been called.
*
* @see #end()
*/
public boolean isInProgress()
{
return inProgress;
}
/**
* Determines whether this editing action is significant enough for
* being seperately undoable by the user. A typical significant
* action would be the resizing of an object. However, changing the
* selection in a text document would usually not be considered
* significant.
*
* <p>A <code>CompoundEdit</code> is significant if any of its
* elements are significant.
*/
public boolean isSignificant()
{
for (int i = edits.size() - 1; i >= 0; i--)
if (((UndoableEdit) edits.elementAt(i)).isSignificant())
return true;
return false;
}
/**
* Returns a human-readable, localized name that describes this
* editing action and can be displayed to the user.
*
* <p>The implementation delegates the call to the {@linkplain
* #lastEdit() last added edit action}. If no edit has been added
* yet, the inherited implementation will be invoked, which always
* returns an empty string.
*/
public String getPresentationName()
{
UndoableEdit last;
last = lastEdit();
if (last == null)
return super.getPresentationName();
else
return last.getPresentationName();
}
/**
* Calculates a localized message text for presenting the undo
* action to the user.
*
* <p>The implementation delegates the call to the {@linkplain
* #lastEdit() last added edit action}. If no edit has been added
* yet, the {@linkplain
* AbstractUndoableEdit#getUndoPresentationName() inherited
* implementation} will be invoked.
*/
public String getUndoPresentationName()
{
UndoableEdit last;
last = lastEdit();
if (last == null)
return super.getUndoPresentationName();
else
return last.getUndoPresentationName();
}
/**
* Calculates a localized message text for presenting the redo
* action to the user.
*
* <p>The implementation delegates the call to the {@linkplain
* #lastEdit() last added edit action}. If no edit has been added
* yet, the {@linkplain
* AbstractUndoableEdit#getRedoPresentationName() inherited
* implementation} will be invoked.
*/
public String getRedoPresentationName()
{
UndoableEdit last;
last = lastEdit();
if (last == null)
return super.getRedoPresentationName();
else
return last.getRedoPresentationName();
}
/**
* Calculates a string that may be useful for debugging.
*/
public String toString()
{
return super.toString()
+ " inProgress: " + inProgress
+ " edits: " + edits;
}
}

@ -1,4 +1,4 @@
/* StateEdit.java --
/* StateEdit.java -- UndoableEdit for StateEditable implementations.
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -42,59 +42,118 @@ import java.util.Hashtable;
import java.util.Iterator;
/**
* StateEdit
* @author Andrew Selkirk
* A helper class, making it easy to support undo and redo.
*
* <p>The following example shows how to use this class.
*
* <pre> Foo foo; // class Foo implements {@link StateEditable}
* StateEdit edit;
*
* edit = new StateEdit(foo, "Name Change");
* foo.setName("Jane Doe");
* edit.end();
* undoManager.addEdit(edit);</pre>
*
* <p>If <code>Foo</code>&#x2019;s implementation of {@link
* StateEditable} considers the name as part of the editable state,
* the user can now choose &#x201c;Undo Name Change&#x201d; or
* &#x201c;Redo Name Change&#x201d; from the respective menu. No
* further undo support is needed from the application.
*
* <p>The following explains what happens in the example.
*
* <p><ol><li>When a <code>StateEdit</code> is created, the associated
* {@link StateEditable} gets asked to store its state into a hash
* table, {@link #preState}.</li>
*
* <li>The application will now perform some changes to the edited
* object. This typically happens by invoking methods on the edited
* object.</li>
*
* <li>The editing phase is terminated by invoking the {@link #end()}
* method of the <code>StateEdit</code>. The <code>end()</code> method
* does two things.
*
* <ul><li>The edited object receives a second request for storing
* its state. This time, it will use a different hash table, {@link
* #postState}.</li>
*
* <li>To increase efficiency, the <code>StateEdit</code> now removes
* any entries from {@link #preState} and {@link #postState} that have
* the same key, and whose values are equal. Equality is determined
* by invoking the <code>equals</code> method inherited from
* {@link java.lang.Object}.</li></ul></li>
*
* <li>When the user later chooses to undo the <code>StateEdit</code>,
* the edited object is asked to {@linkplain StateEditable#restoreState
* restore its state} from the {@link #preState} table. Similarly,
* when the user chooses to <i>redo</i> the <code>StateEdit</code>,
* the edited object gets asked to restore its state from the {@link
* #postState}.</li></ol>
*
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public class StateEdit extends AbstractUndoableEdit
public class StateEdit
extends AbstractUndoableEdit
{
//-------------------------------------------------------------
// Variables --------------------------------------------------
//-------------------------------------------------------------
/**
* RCSID
* The ID of the Java source file in Sun&#x2019;s Revision Control
* System (RCS). This certainly should not be part of the API
* specification. But in order to be API-compatible with
* Sun&#x2019;s reference implementation, GNU Classpath also has to
* provide this field. However, we do not try to match its value.
*/
protected static final String RCSID = ""; // TODO
protected static final String RCSID = "";
/**
* object
* The object which is being edited by this <code>StateEdit</code>.
*/
protected StateEditable object;
/**
* preState
* The state of <code>object</code> at the time of constructing
* this <code>StateEdit</code>.
*/
protected Hashtable preState;
/**
* postState
* The state of <code>object</code> at the time when {@link #end()}
* was called.
*/
protected Hashtable postState;
/**
* undoRedoName
* A human-readable name for this edit action.
*/
protected String undoRedoName;
//-------------------------------------------------------------
// Initialization ---------------------------------------------
//-------------------------------------------------------------
/**
* Constructor StateEdit
* @param obj Object to edit
* Constructs a <code>StateEdit</code>, specifying the object whose
* state is being edited.
*
* @param obj the object whose state is being edited by this
* <code>StateEdit</code>.
*/
public StateEdit(StateEditable obj)
{
init(obj, null);
}
/**
* Constructor StateEdit
* @param obj Object to edit
* @param name Presentation name
* Constructs a <code>StateEdit</code>, specifying the object whose
* state is being edited.
*
* @param obj the object whose state is being edited by this
* <code>StateEdit</code>.
*
* @param name the human-readable name of the editing action.
*/
public StateEdit(StateEditable obj, String name)
{
@ -102,14 +161,13 @@ public class StateEdit extends AbstractUndoableEdit
}
//-------------------------------------------------------------
// Methods ----------------------------------------------------
//-------------------------------------------------------------
/**
* Initialize this object.
* @param obj Object to edit
* @param name Presentation name
* Initializes this <code>StateEdit</code>. The edited object will
* be asked to store its current state into {@link #preState}.
*
* @param obj the object being edited.
*
* @param name the human-readable name of the editing action.
*/
protected void init(StateEditable obj, String name)
{
@ -120,9 +178,12 @@ public class StateEdit extends AbstractUndoableEdit
obj.storeState(preState);
}
/**
* Indicate that all edits are finished, and update this object
* with final state.
* Informs this <code>StateEdit</code> that all edits are finished.
* The edited object will be asked to store its state into {@link
* #postState}, and any redundant entries will get removed from
* {@link #preState} and {@link #postState}.
*/
public void end()
{
@ -130,33 +191,56 @@ public class StateEdit extends AbstractUndoableEdit
removeRedundantState();
}
/**
* Undo this edit by applying the initial state to the edited object.
* Undoes this edit operation. The edited object will be asked to
* {@linkplain StateEditable#restoreState restore its state} from
* {@link #preState}.
*
* @throws CannotUndoException if {@link #canUndo()} returns
* <code>false</code>, for example because this action has already
* been undone.
*/
public void undo()
{
super.undo();
object.restoreState(preState);
}
/**
* Undo this edit by applying the final state to the edited object.
* Redoes this edit operation. The edited object will be asked to
* {@linkplain StateEditable#restoreState restore its state} from
* {@link #postState}.
*
* @throws CannotRedoException if {@link #canRedo()} returns
* <code>false</code>, for example because this action has not yet
* been undone.
*/
public void redo()
{
super.redo();
object.restoreState(postState);
}
/**
* Return the presentation name of this object.
* @returns The name, or null if not set
* Returns a human-readable, localized name that describes this
* editing action and can be displayed to the user.
*
* @return the name, or <code>null</code> if no presentation
* name is available.
*/
public String getPresentationName()
{
return undoRedoName;
}
/**
* removeRedundantState
* Removes all redundant entries from the pre- and post-edit state
* hash tables. An entry is considered redundant if it is present
* both before and after the edit, and if the two values are equal.
*/
protected void removeRedundantState()
{

@ -1,4 +1,4 @@
/* StateEditable.java --
/* StateEditable.java -- Interface for collaborating with StateEdit.
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -37,29 +37,76 @@ exception statement from your version. */
package javax.swing.undo;
// Imports
import java.util.Hashtable;
/**
* StateEditable public interface
* @author Andrew Selkirk
* The interface for objects whose state can be undone or redone by a
* {@link StateEdit} action.
*
* <p>The following example shows how to write a class that implements
* this interface.
*
* <pre> class Foo
* implements StateEditable
* {
* private String name;
*
* public void setName(String n) { name = n; }
*
* public void restoreState(Hashtable h)
* {
* if (h.containsKey("name"))
* setName((String) h.get("name"));
* }
*
* public void storeState(Hashtable s)
* {
* s.put("name", name);
* }
* }</pre>
*
* @see StateEdit
*
* @author Andrew Selkirk (aselkirk@sympatico.ca)
* @author Sascha Brawer (brawer@dandelis.ch)
*/
public interface StateEditable
{
/**
* Restore State
* @param state State
* The ID of the Java source file in Sun&#x2019;s Revision Control
* System (RCS). This certainly should not be part of the API
* specification. But in order to be API-compatible with
* Sun&#x2019;s reference implementation, GNU Classpath also has to
* provide this field. However, we do not try to match its value.
*/
static final String RCSID = "";
/**
* Performs an edit action, taking any editable state information
* from the specified hash table.
*
* <p><b>Note to implementors of this interface:</b> To increase
* efficiency, the <code>StateEdit</code> class {@linkplan
* StateEdit#removeRedundantState() removes redundant state
* information}. Therefore, implementations of this interface must be
* prepared for the case where certain keys were stored into the
* table by {@link #storeState}, but are not present anymore
* when the <code>restoreState</code> method gets called.
*
* @param state a hash table containing the relevant state
* information.
*/
void restoreState(Hashtable state);
/**
* Store State
* @param state State
*/
void storeState(Hashtable state);
/**
* For some reason, Sun made the RCS IDs visible.
* Stores any editable state information into the specified hash
* table.
*
* @param state a hash table for storing relevant state
* information.
*/
String RCSID = "We aren't compatible";
} // StateEditable
void storeState(Hashtable state);
}