-
Enhancement
-
Resolution: Fixed
-
P2
-
5.0, 6
-
b92
-
generic, x86
-
generic, windows_xp
A DESCRIPTION OF THE PROBLEM :
The Javadoc should specify that setLimit(-1) means no limit should be imposed.
URL OF FAULTY DOCUMENTATION :
http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/undo/UndoManager.html#setLimit(int)
###@###.### 2005-1-10 22:06:44 GMT
Suggested fix provided by java.net member leouser:
A DESCRIPTION OF THE FIX :
BUG ID: 6215849 javax.swing.undo.UndoManager.setLimit() should state that -1 means "no limit"
JDK: jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
FILE AFFECTED: javax.swing.undo.UndoManager
DISCUSION(embeded in javadoc):
/**
* BUG-ID: 6215849 javax.swing.undo.UndoManager.setLimit should state that -1 means "no limit"
* This is a bad description of the bug, the problem is in essence: there does
* not appear to be a way to take off the bounds of the UndoManager. Using -1
* as an indicator is bad, -1 means nothing on its own. Therefore I have chosen
* to supplement the UndoManager with 2 new methods: setIgnoreLimit and getIgnoreLimit
* When set to true, the UndoManager will not trim. You can call trimToLimit but
* it will not affect the quantity of UndoableEdits that have accumalated. Also
* to ensure clients do not confuse values less than 0 with some kind of special
* flag I have ensured that setLimit throws an IllegalArgumentException if it is
* passed a value < 0.
*
* ANTI-RATIONALE:
* 1. You can acheive the same effect by subclassing the UndoManager and add these * methods as well as instrumenting the trimToLimit method to ignore calls to it.
* 2. UndoManager is not final, subclasses may have added mechanisms to deal with
* unbounded adding or methods that have names that clash with it. Or the new
* methods may not work in an already existing subclass given that it may in turn
* override the trimToLimit method.
*
* TESTING STRATEGY: Exercise each new method and described functionality.
*
* A NOTE ON WARNINGS:
* I have removed the cause of I believe 8 warnings. The Vector inside of the
* UndoManager was not properly generified. Its superclass appears to have
* been generified but it was not being used as so in the UndoManager.
*
* OTHER IDEAS and API Analysis:
* The UndoManager in my experience has hooks which are good to dig into it. But
* in many cases when Ive used it Ive had to subclass to get at its guts. For
* example Ive needed to know the amount of undo's in the stack at one time.
* There is absolutely no method that will return this value to us. Another
* time I needed to inspect the guts of the UndoableEdits so I could present
* a good undo dialog to the user. Again I had to subclass. So this indicates
* to me:
* 1. The API for the UndoManager is not sufficient for any use cases that go
* beyond just store and undo/redo.
* It may be better to create a new UndoManager class that offers variations on
* the UndoManager theme... maybe an UndoManager that takes only a certain type
* of UndoableEdit. At this juncture I consider all these ideas out of scope
* for this RFE, but are illustrative of holes in the API. If there truly
* are holes then it may make it impossible in the general case to compose a
* solution with the UndoManager as a component. Prefering Composition over
* inheritence cannot be realised.
*
* JDK VERSION:
* jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
*
* FILE AFFECTED: javax.swing.undo.UndoManager
* test ran succesfully on a SUSE 7.3 Linux distribution
*
* Brian Harry
* ###@###.###
* Thu Jan 11, 2006
*
*/
UNIFIED DIFF:
--- /home/nstuff/java6/jdk1.6.0/javax/swing/undo/UndoManager.java Thu Dec 15 02:17:58 2005
+++ /home/javarefs/javax/swing/undo/UndoManager.java Wed Jan 11 14:19:43 2006
@@ -116,8 +116,10 @@
* @version 1.38, 11/17/05
*/
public class UndoManager extends CompoundEdit implements UndoableEditListener {
+ static final long serialVersionUID = -2077529998244066750L;
int indexOfNextAdd;
int limit;
+ boolean ignoreLimit;
/**
* Creates a new <code>UndoManager</code>.
@@ -127,6 +129,7 @@
indexOfNextAdd = 0;
limit = 100;
edits.ensureCapacity(limit);
+ ignoreLimit = false;
}
/**
@@ -147,12 +150,12 @@
* @see AbstractUndoableEdit#die
*/
public synchronized void discardAllEdits() {
- Enumeration cursor = edits.elements();
+ Enumeration<UndoableEdit> cursor = edits.elements();
while (cursor.hasMoreElements()) {
- UndoableEdit e = (UndoableEdit)cursor.nextElement();
+ UndoableEdit e = cursor.nextElement();
e.die();
}
- edits = new Vector();
+ edits = new Vector<UndoableEdit>();
indexOfNextAdd = 0;
// PENDING(rjrjr) when vector grows a removeRange() method
// (expected in JDK 1.2), trimEdits() will be nice and
@@ -164,6 +167,7 @@
* centered on the index of the next edit.
*/
protected void trimForLimit() {
+ if(ignoreLimit) return;
if (limit >= 0) {
int size = edits.size();
// System.out.print("limit: " + limit +
@@ -221,7 +225,7 @@
// System.out.println("Trimming " + from + " " + to + " with index " +
// indexOfNextAdd);
for (int i = to; from <= i; i--) {
- UndoableEdit e = (UndoableEdit)edits.elementAt(i);
+ UndoableEdit e = edits.elementAt(i);
// System.out.println("JUM: Discarding " +
// e.getUndoPresentationName());
e.die();
@@ -249,15 +253,53 @@
* order they were added. The default is 100.
*
* @param l the new limit
+ * @throws IllegalArgumentException if l is < 0.
* @see #addEdit
* @see #getLimit
*/
public synchronized void setLimit(int l) {
if (!inProgress) throw new RuntimeException("Attempt to call UndoManager.setLimit() after UndoManager.end() has been called");
+ else if(l < 0)
+ throw new IllegalArgumentException("l must be >= 0 was " + l);
limit = l;
trimForLimit();
}
-
+
+ /**
+ * Sets whether or not this <code>UndoManager</code> instance
+ * will ignore the limit property. If set to true, this
+ * <code>UndoManager</code> will not place any bounds upon how
+ * many <code>UndoableEdits</code> it will accumulate. If set to
+ * false the <code>UndoManager</code> instance will ensure that the
+ * limit is maintained. Setting this value to false when the
+ * limit has been exceeded will result in the size of the
+ * <code>UndoableEdits</code> held to be reduced to the limit.
+ * Default value is false.
+ *
+ * @param ignore whether to ignore the limit or not.
+ * @see #getIgnoreLimit
+ */
+ public synchronized void setIgnoreLimit(boolean ignore){
+ if(!inProgress) throw new RuntimeException("Attempt to call UndoManager.setIgnoreLimit(boolean ignore) after UndoManager.end() has been called");
+ ignoreLimit = ignore;
+ trimForLimit();
+ }
+
+ /**
+ * Returns whether or not the limit is being ignored. If
+ * the limit is ignored then the <code>UndoManager</code> instance
+ * will place no bounds upon the amount of <code>UndoableEdits</code>
+ * that can accumalate. If the limit is not ignored, this will
+ * be the maximum amount of <code>UndoableEdits</code> this
+ * <code>UndoManager</code> can accumalate.
+ * Default value is false.
+ *
+ * @return boolean whether the limit is ignored or not.
+ * @see #setIgnoreLimit
+ */
+ public synchronized boolean getIgnoreLimit(){
+ return ignoreLimit;
+ }
/**
* Returns the the next significant edit to be undone if <code>undo</code>
@@ -269,7 +311,7 @@
protected UndoableEdit editToBeUndone() {
int i = indexOfNextAdd;
while (i > 0) {
- UndoableEdit edit = (UndoableEdit)edits.elementAt(--i);
+ UndoableEdit edit = edits.elementAt(--i);
if (edit.isSignificant()) {
return edit;
}
@@ -290,7 +332,7 @@
int i = indexOfNextAdd;
while (i < count) {
- UndoableEdit edit = (UndoableEdit)edits.elementAt(i++);
+ UndoableEdit edit = edits.elementAt(i++);
if (edit.isSignificant()) {
return edit;
}
@@ -309,7 +351,7 @@
protected void undoTo(UndoableEdit edit) throws CannotUndoException {
boolean done = false;
while (!done) {
- UndoableEdit next = (UndoableEdit)edits.elementAt(--indexOfNextAdd);
+ UndoableEdit next = edits.elementAt(--indexOfNextAdd);
next.undo();
done = next == edit;
}
@@ -325,7 +367,7 @@
protected void redoTo(UndoableEdit edit) throws CannotRedoException {
boolean done = false;
while (!done) {
- UndoableEdit next = (UndoableEdit)edits.elementAt(indexOfNextAdd++);
+ UndoableEdit next = edits.elementAt(indexOfNextAdd++);
next.redo();
done = next == edit;
}
JUnit TESTCASE :
import junit.framework.TestCase;
import junit.textui.TestRunner;
import static java.lang.System.out;
import javax.swing.undo.*;
/**
* BUG-ID: 6215849 javax.swing.undo.UndoManager.setLimit should state that -1 means "no limit"
* This is a bad description of the bug, the problem is in essence: there does
* not appear to be a way to take off the bounds of the UndoManager. Using -1
* as an indicator is bad, -1 means nothing on its own. Therefore I have chosen
* to supplement the UndoManager with 2 new methods: setIgnoreLimit and getIgnoreLimit
* When set to true, the UndoManager will not trim. You can call trimToLimit but
* it will not affect the quantity of UndoableEdits that have accumalated. Also
* to ensure clients do not confuse values less than 0 with some kind of special
* flag I have ensured that setLimit throws an IllegalArgumentException if it is
* passed a value < 0.
*
* ANTI-RATIONALE:
* 1. You can acheive the same effect by subclassing the UndoManager and add these * methods as well as instrumenting the trimToLimit method to ignore calls to it.
* 2. UndoManager is not final, subclasses may have added mechanisms to deal with
* unbounded adding or methods that have names that clash with it. Or the new
* methods may not work in an already existing subclass given that it may in turn
* override the trimToLimit method.
*
* TESTING STRATEGY: Exercise each new method and described functionality.
*
* A NOTE ON WARNINGS:
* I have removed the cause of I believe 8 warnings. The Vector inside of the
* UndoManager was not properly generified. Its superclass appears to have
* been generified but it was not being used as so in the UndoManager.
*
* OTHER IDEAS and API Analysis:
* The UndoManager in my experience has hooks which are good to dig into it. But
* in many cases when Ive used it Ive had to subclass to get at its guts. For
* example Ive needed to know the amount of undo's in the stack at one time.
* There is absolutely no method that will return this value to us. Another
* time I needed to inspect the guts of the UndoableEdits so I could present
* a good undo dialog to the user. Again I had to subclass. So this indicates
* to me:
* 1. The API for the UndoManager is not sufficient for any use cases that go
* beyond just store and undo/redo.
* It may be better to create a new UndoManager class that offers variations on
* the UndoManager theme... maybe an UndoManager that takes only a certain type
* of UndoableEdit. At this juncture I consider all these ideas out of scope
* for this RFE, but are illustrative of holes in the API. If there truly
* are holes then it may make it impossible in the general case to compose a
* solution with the UndoManager as a component. Prefering Composition over
* inheritence cannot be realised.
*
* JDK VERSION:
* jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
*
* FILE AFFECTED: javax.swing.undo.UndoManager
* test ran succesfully on a SUSE 7.3 Linux distribution
*
* Brian Harry
* ###@###.###
* Thu Jan 11, 2006
*
*/
public class TestUM extends TestCase{
public TestUM(String method){
super(method);
}
public static class UE implements UndoableEdit{
boolean cr;
boolean cu;
public UE(){
cu = true;
cr = false;
}
public boolean addEdit(UndoableEdit ue){
return false;
}
public boolean canRedo(){
return cr;
}
public boolean canUndo(){
return cu;
}
public void die(){
cu = cr = false;
}
public String getPresentationName(){
return "I do nothing";
}
public String getRedoPresentationName(){
return "I do nothing";
}
public String getUndoPresentationName(){
return "I do nothing";
}
public boolean isSignificant(){ return true; }
public void redo(){
cr = false;
cu = true;
}
public void undo(){
cr = true;
cu = false;
}
public boolean replaceEdit(UndoableEdit ue){
return false;
}
}
public void testUMIgnore(){
out.println("");
out.println("Testing to see if limit is ignored...");
UndoManager um = new UndoManager();
um.setLimit(100);
um.setIgnoreLimit(true);
out.println( "Limit is " + um.getLimit() );
out.println( "Adding 1000 UndoableEdit instances" );
for(int i = 0; i < 1000;i++)
um.addEdit(new UE());
out.println("Let us see if the limit is ignored...");
int x = 0;
while(um.canUndo()){
um.undo();
x++;
}
assertEquals(1000,x);
out.println("Limit was ignored! success!");
}
public void testUMNotIgnore(){
out.println("");
out.println("Testing to see if limit is not ignored...");
UndoManager um = new UndoManager();
um.setLimit(100);
um.setIgnoreLimit(false);
out.println( "Limit is " + um.getLimit() );
out.println( "Adding 1000 UndoableEdit instances" );
for(int i = 0; i < 1000;i++)
um.addEdit(new UE());
out.println("Let us see if the limit is not ignored...");
int x = 0;
while(um.canUndo()){
um.undo();
x++;
}
assertEquals(100,x);
out.println("Limit was not ignored! success!");
}
public void testUMTrim(){
out.println("");
out.println("Testing to see if setIgnoreLimit will trim if set to false after adding 1000 UEs ");
UndoManager um = new UndoManager();
um.setLimit(100);
um.setIgnoreLimit(true);
out.println( "Limit is " + um.getLimit() );
out.println( "Adding 1000 UndoableEdit instances" );
for(int i = 0; i < 1000;i++)
um.addEdit(new UE());
um.setIgnoreLimit(false);
out.println("Let us see if the setIgnoreLimit trims...");
int x = 0;
while(um.canUndo()){
um.undo();
x++;
}
assertEquals(100,x);
out.println("trim was executed!");
}
public void testUMLTZ(){
out.println("");
out.println("Testing to see if setLimit with values less than 0 will throw an IllegalArgumentException");
try{
UndoManager um = new UndoManager();
um.setLimit(-1);
}
catch(IllegalArgumentException iae){
out.println( "IllegalArgumentException is tossed as expected");
}
}
public static void main(String ... args){
TestCase tc = new TestUM("testUMIgnore");
TestRunner.run(tc);
TestCase tc2 = new TestUM("testUMNotIgnore");
TestRunner.run(tc2);
TestCase tc3 = new TestUM("testUMTrim");
TestRunner.run(tc3);
TestCase tc4 = new TestUM("testUMLTZ");
TestRunner.run(tc4);
}
}
FIX FOR BUG NUMBER:
6215849
The Javadoc should specify that setLimit(-1) means no limit should be imposed.
URL OF FAULTY DOCUMENTATION :
http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/undo/UndoManager.html#setLimit(int)
###@###.### 2005-1-10 22:06:44 GMT
Suggested fix provided by java.net member leouser:
A DESCRIPTION OF THE FIX :
BUG ID: 6215849 javax.swing.undo.UndoManager.setLimit() should state that -1 means "no limit"
JDK: jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
FILE AFFECTED: javax.swing.undo.UndoManager
DISCUSION(embeded in javadoc):
/**
* BUG-ID: 6215849 javax.swing.undo.UndoManager.setLimit should state that -1 means "no limit"
* This is a bad description of the bug, the problem is in essence: there does
* not appear to be a way to take off the bounds of the UndoManager. Using -1
* as an indicator is bad, -1 means nothing on its own. Therefore I have chosen
* to supplement the UndoManager with 2 new methods: setIgnoreLimit and getIgnoreLimit
* When set to true, the UndoManager will not trim. You can call trimToLimit but
* it will not affect the quantity of UndoableEdits that have accumalated. Also
* to ensure clients do not confuse values less than 0 with some kind of special
* flag I have ensured that setLimit throws an IllegalArgumentException if it is
* passed a value < 0.
*
* ANTI-RATIONALE:
* 1. You can acheive the same effect by subclassing the UndoManager and add these * methods as well as instrumenting the trimToLimit method to ignore calls to it.
* 2. UndoManager is not final, subclasses may have added mechanisms to deal with
* unbounded adding or methods that have names that clash with it. Or the new
* methods may not work in an already existing subclass given that it may in turn
* override the trimToLimit method.
*
* TESTING STRATEGY: Exercise each new method and described functionality.
*
* A NOTE ON WARNINGS:
* I have removed the cause of I believe 8 warnings. The Vector inside of the
* UndoManager was not properly generified. Its superclass appears to have
* been generified but it was not being used as so in the UndoManager.
*
* OTHER IDEAS and API Analysis:
* The UndoManager in my experience has hooks which are good to dig into it. But
* in many cases when Ive used it Ive had to subclass to get at its guts. For
* example Ive needed to know the amount of undo's in the stack at one time.
* There is absolutely no method that will return this value to us. Another
* time I needed to inspect the guts of the UndoableEdits so I could present
* a good undo dialog to the user. Again I had to subclass. So this indicates
* to me:
* 1. The API for the UndoManager is not sufficient for any use cases that go
* beyond just store and undo/redo.
* It may be better to create a new UndoManager class that offers variations on
* the UndoManager theme... maybe an UndoManager that takes only a certain type
* of UndoableEdit. At this juncture I consider all these ideas out of scope
* for this RFE, but are illustrative of holes in the API. If there truly
* are holes then it may make it impossible in the general case to compose a
* solution with the UndoManager as a component. Prefering Composition over
* inheritence cannot be realised.
*
* JDK VERSION:
* jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
*
* FILE AFFECTED: javax.swing.undo.UndoManager
* test ran succesfully on a SUSE 7.3 Linux distribution
*
* Brian Harry
* ###@###.###
* Thu Jan 11, 2006
*
*/
UNIFIED DIFF:
--- /home/nstuff/java6/jdk1.6.0/javax/swing/undo/UndoManager.java Thu Dec 15 02:17:58 2005
+++ /home/javarefs/javax/swing/undo/UndoManager.java Wed Jan 11 14:19:43 2006
@@ -116,8 +116,10 @@
* @version 1.38, 11/17/05
*/
public class UndoManager extends CompoundEdit implements UndoableEditListener {
+ static final long serialVersionUID = -2077529998244066750L;
int indexOfNextAdd;
int limit;
+ boolean ignoreLimit;
/**
* Creates a new <code>UndoManager</code>.
@@ -127,6 +129,7 @@
indexOfNextAdd = 0;
limit = 100;
edits.ensureCapacity(limit);
+ ignoreLimit = false;
}
/**
@@ -147,12 +150,12 @@
* @see AbstractUndoableEdit#die
*/
public synchronized void discardAllEdits() {
- Enumeration cursor = edits.elements();
+ Enumeration<UndoableEdit> cursor = edits.elements();
while (cursor.hasMoreElements()) {
- UndoableEdit e = (UndoableEdit)cursor.nextElement();
+ UndoableEdit e = cursor.nextElement();
e.die();
}
- edits = new Vector();
+ edits = new Vector<UndoableEdit>();
indexOfNextAdd = 0;
// PENDING(rjrjr) when vector grows a removeRange() method
// (expected in JDK 1.2), trimEdits() will be nice and
@@ -164,6 +167,7 @@
* centered on the index of the next edit.
*/
protected void trimForLimit() {
+ if(ignoreLimit) return;
if (limit >= 0) {
int size = edits.size();
// System.out.print("limit: " + limit +
@@ -221,7 +225,7 @@
// System.out.println("Trimming " + from + " " + to + " with index " +
// indexOfNextAdd);
for (int i = to; from <= i; i--) {
- UndoableEdit e = (UndoableEdit)edits.elementAt(i);
+ UndoableEdit e = edits.elementAt(i);
// System.out.println("JUM: Discarding " +
// e.getUndoPresentationName());
e.die();
@@ -249,15 +253,53 @@
* order they were added. The default is 100.
*
* @param l the new limit
+ * @throws IllegalArgumentException if l is < 0.
* @see #addEdit
* @see #getLimit
*/
public synchronized void setLimit(int l) {
if (!inProgress) throw new RuntimeException("Attempt to call UndoManager.setLimit() after UndoManager.end() has been called");
+ else if(l < 0)
+ throw new IllegalArgumentException("l must be >= 0 was " + l);
limit = l;
trimForLimit();
}
-
+
+ /**
+ * Sets whether or not this <code>UndoManager</code> instance
+ * will ignore the limit property. If set to true, this
+ * <code>UndoManager</code> will not place any bounds upon how
+ * many <code>UndoableEdits</code> it will accumulate. If set to
+ * false the <code>UndoManager</code> instance will ensure that the
+ * limit is maintained. Setting this value to false when the
+ * limit has been exceeded will result in the size of the
+ * <code>UndoableEdits</code> held to be reduced to the limit.
+ * Default value is false.
+ *
+ * @param ignore whether to ignore the limit or not.
+ * @see #getIgnoreLimit
+ */
+ public synchronized void setIgnoreLimit(boolean ignore){
+ if(!inProgress) throw new RuntimeException("Attempt to call UndoManager.setIgnoreLimit(boolean ignore) after UndoManager.end() has been called");
+ ignoreLimit = ignore;
+ trimForLimit();
+ }
+
+ /**
+ * Returns whether or not the limit is being ignored. If
+ * the limit is ignored then the <code>UndoManager</code> instance
+ * will place no bounds upon the amount of <code>UndoableEdits</code>
+ * that can accumalate. If the limit is not ignored, this will
+ * be the maximum amount of <code>UndoableEdits</code> this
+ * <code>UndoManager</code> can accumalate.
+ * Default value is false.
+ *
+ * @return boolean whether the limit is ignored or not.
+ * @see #setIgnoreLimit
+ */
+ public synchronized boolean getIgnoreLimit(){
+ return ignoreLimit;
+ }
/**
* Returns the the next significant edit to be undone if <code>undo</code>
@@ -269,7 +311,7 @@
protected UndoableEdit editToBeUndone() {
int i = indexOfNextAdd;
while (i > 0) {
- UndoableEdit edit = (UndoableEdit)edits.elementAt(--i);
+ UndoableEdit edit = edits.elementAt(--i);
if (edit.isSignificant()) {
return edit;
}
@@ -290,7 +332,7 @@
int i = indexOfNextAdd;
while (i < count) {
- UndoableEdit edit = (UndoableEdit)edits.elementAt(i++);
+ UndoableEdit edit = edits.elementAt(i++);
if (edit.isSignificant()) {
return edit;
}
@@ -309,7 +351,7 @@
protected void undoTo(UndoableEdit edit) throws CannotUndoException {
boolean done = false;
while (!done) {
- UndoableEdit next = (UndoableEdit)edits.elementAt(--indexOfNextAdd);
+ UndoableEdit next = edits.elementAt(--indexOfNextAdd);
next.undo();
done = next == edit;
}
@@ -325,7 +367,7 @@
protected void redoTo(UndoableEdit edit) throws CannotRedoException {
boolean done = false;
while (!done) {
- UndoableEdit next = (UndoableEdit)edits.elementAt(indexOfNextAdd++);
+ UndoableEdit next = edits.elementAt(indexOfNextAdd++);
next.redo();
done = next == edit;
}
JUnit TESTCASE :
import junit.framework.TestCase;
import junit.textui.TestRunner;
import static java.lang.System.out;
import javax.swing.undo.*;
/**
* BUG-ID: 6215849 javax.swing.undo.UndoManager.setLimit should state that -1 means "no limit"
* This is a bad description of the bug, the problem is in essence: there does
* not appear to be a way to take off the bounds of the UndoManager. Using -1
* as an indicator is bad, -1 means nothing on its own. Therefore I have chosen
* to supplement the UndoManager with 2 new methods: setIgnoreLimit and getIgnoreLimit
* When set to true, the UndoManager will not trim. You can call trimToLimit but
* it will not affect the quantity of UndoableEdits that have accumalated. Also
* to ensure clients do not confuse values less than 0 with some kind of special
* flag I have ensured that setLimit throws an IllegalArgumentException if it is
* passed a value < 0.
*
* ANTI-RATIONALE:
* 1. You can acheive the same effect by subclassing the UndoManager and add these * methods as well as instrumenting the trimToLimit method to ignore calls to it.
* 2. UndoManager is not final, subclasses may have added mechanisms to deal with
* unbounded adding or methods that have names that clash with it. Or the new
* methods may not work in an already existing subclass given that it may in turn
* override the trimToLimit method.
*
* TESTING STRATEGY: Exercise each new method and described functionality.
*
* A NOTE ON WARNINGS:
* I have removed the cause of I believe 8 warnings. The Vector inside of the
* UndoManager was not properly generified. Its superclass appears to have
* been generified but it was not being used as so in the UndoManager.
*
* OTHER IDEAS and API Analysis:
* The UndoManager in my experience has hooks which are good to dig into it. But
* in many cases when Ive used it Ive had to subclass to get at its guts. For
* example Ive needed to know the amount of undo's in the stack at one time.
* There is absolutely no method that will return this value to us. Another
* time I needed to inspect the guts of the UndoableEdits so I could present
* a good undo dialog to the user. Again I had to subclass. So this indicates
* to me:
* 1. The API for the UndoManager is not sufficient for any use cases that go
* beyond just store and undo/redo.
* It may be better to create a new UndoManager class that offers variations on
* the UndoManager theme... maybe an UndoManager that takes only a certain type
* of UndoableEdit. At this juncture I consider all these ideas out of scope
* for this RFE, but are illustrative of holes in the API. If there truly
* are holes then it may make it impossible in the general case to compose a
* solution with the UndoManager as a component. Prefering Composition over
* inheritence cannot be realised.
*
* JDK VERSION:
* jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
*
* FILE AFFECTED: javax.swing.undo.UndoManager
* test ran succesfully on a SUSE 7.3 Linux distribution
*
* Brian Harry
* ###@###.###
* Thu Jan 11, 2006
*
*/
public class TestUM extends TestCase{
public TestUM(String method){
super(method);
}
public static class UE implements UndoableEdit{
boolean cr;
boolean cu;
public UE(){
cu = true;
cr = false;
}
public boolean addEdit(UndoableEdit ue){
return false;
}
public boolean canRedo(){
return cr;
}
public boolean canUndo(){
return cu;
}
public void die(){
cu = cr = false;
}
public String getPresentationName(){
return "I do nothing";
}
public String getRedoPresentationName(){
return "I do nothing";
}
public String getUndoPresentationName(){
return "I do nothing";
}
public boolean isSignificant(){ return true; }
public void redo(){
cr = false;
cu = true;
}
public void undo(){
cr = true;
cu = false;
}
public boolean replaceEdit(UndoableEdit ue){
return false;
}
}
public void testUMIgnore(){
out.println("");
out.println("Testing to see if limit is ignored...");
UndoManager um = new UndoManager();
um.setLimit(100);
um.setIgnoreLimit(true);
out.println( "Limit is " + um.getLimit() );
out.println( "Adding 1000 UndoableEdit instances" );
for(int i = 0; i < 1000;i++)
um.addEdit(new UE());
out.println("Let us see if the limit is ignored...");
int x = 0;
while(um.canUndo()){
um.undo();
x++;
}
assertEquals(1000,x);
out.println("Limit was ignored! success!");
}
public void testUMNotIgnore(){
out.println("");
out.println("Testing to see if limit is not ignored...");
UndoManager um = new UndoManager();
um.setLimit(100);
um.setIgnoreLimit(false);
out.println( "Limit is " + um.getLimit() );
out.println( "Adding 1000 UndoableEdit instances" );
for(int i = 0; i < 1000;i++)
um.addEdit(new UE());
out.println("Let us see if the limit is not ignored...");
int x = 0;
while(um.canUndo()){
um.undo();
x++;
}
assertEquals(100,x);
out.println("Limit was not ignored! success!");
}
public void testUMTrim(){
out.println("");
out.println("Testing to see if setIgnoreLimit will trim if set to false after adding 1000 UEs ");
UndoManager um = new UndoManager();
um.setLimit(100);
um.setIgnoreLimit(true);
out.println( "Limit is " + um.getLimit() );
out.println( "Adding 1000 UndoableEdit instances" );
for(int i = 0; i < 1000;i++)
um.addEdit(new UE());
um.setIgnoreLimit(false);
out.println("Let us see if the setIgnoreLimit trims...");
int x = 0;
while(um.canUndo()){
um.undo();
x++;
}
assertEquals(100,x);
out.println("trim was executed!");
}
public void testUMLTZ(){
out.println("");
out.println("Testing to see if setLimit with values less than 0 will throw an IllegalArgumentException");
try{
UndoManager um = new UndoManager();
um.setLimit(-1);
}
catch(IllegalArgumentException iae){
out.println( "IllegalArgumentException is tossed as expected");
}
}
public static void main(String ... args){
TestCase tc = new TestUM("testUMIgnore");
TestRunner.run(tc);
TestCase tc2 = new TestUM("testUMNotIgnore");
TestRunner.run(tc2);
TestCase tc3 = new TestUM("testUMTrim");
TestRunner.run(tc3);
TestCase tc4 = new TestUM("testUMLTZ");
TestRunner.run(tc4);
}
}
FIX FOR BUG NUMBER:
6215849
- relates to
-
JDK-4992178 REGRESSION: Allow unlimited number of edits in an UndoManager
-
- Resolved
-