Index: ChangeLog =================================================================== RCS file: /cvsroot/classpath/classpath/ChangeLog,v retrieving revision 1.1763 diff -u -r1.1763 ChangeLog --- ChangeLog 7 Jan 2004 02:23:37 -0000 1.1763 +++ ChangeLog 7 Jan 2004 08:57:11 -0000 @@ -1,3 +1,13 @@ +2004-01-07 Sascha Brawer + + * javax/swing/undo/UndoableEditSupport.java (UndoableEditSupport): + Set realSource field. Improve documentation. + (_postEdit): Iterate over cloned listener vector. + + Fix for Classpath bug #7119. + * javax/swing/undo/UndoableEditSupport.java (toString): Don't emit + realSource. + 2004-01-06 Graydon Hoare * configure.in: Add --enable-gtk-cairo check. Index: javax/swing/undo/UndoableEditSupport.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/undo/UndoableEditSupport.java,v retrieving revision 1.5 diff -u -r1.5 UndoableEditSupport.java --- javax/swing/undo/UndoableEditSupport.java 6 Jan 2004 17:03:57 -0000 1.5 +++ javax/swing/undo/UndoableEditSupport.java 7 Jan 2004 08:57:11 -0000 @@ -38,6 +38,7 @@ package javax.swing.undo; +import java.util.Iterator; import java.util.Vector; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; @@ -78,6 +79,19 @@ /** + * Constructs a new helper for broadcasting UndoableEditEvents. The + * events will indicate the newly constructed + * UndoableEditSupport instance as their source. + * + * @see #UndoableEditSupport(java.lang.Object) + */ + public UndoableEditSupport() + { + realSource = this; + } + + + /** * Constructs a new helper for broadcasting UndoableEditEvents. * * @param realSource the source of the UndoableEditEvents that will @@ -85,7 +99,7 @@ * null, the events will indicate the newly constructed * UndoableEditSupport instance as their source. */ - public UndoableEditSupport() + public UndoableEditSupport(Object realSource) { if (realSource == null) realSource = this; @@ -94,23 +108,16 @@ /** - * Constructor UndoableEditSupport - * @param object TODO - */ - public UndoableEditSupport(Object object) - { - realSource = object; - } - - - /** * Returns a string representation of this object that may be useful * for debugging. */ public String toString() { - return (super.toString() + " realSource: " + realSource - + " updateLevel: " + updateLevel); + // Note that often, this.realSource == this. Therefore, dumping + // realSource without additional checks may lead to infinite + // recursion. See Classpath bug #7119. + return super.toString() + " updateLevel: " + updateLevel + + " listeners: " + listeners + " compoundEdit: " + compoundEdit; } @@ -146,19 +153,36 @@ /** - * _postEdit - * @param value0 TODO + * Notifies all registered listeners that an address@hidden + * UndoableEditEvent} has occured. + * + *

Lack of Thread Safety: It is not safe to call + * this method from concurrent threads, unless the call is protected + * by a synchronization on this UndoableEditSupport + * instance. + * + * @param edit the edit action to be posted. */ protected void _postEdit(UndoableEdit edit) { - UndoableEditEvent event = new UndoableEditEvent(realSource, edit); - int max = listeners.size(); - for (int i = 0; i < max; ++i) - { - UndoableEditListener l - = (UndoableEditListener) (listeners.elementAt(i)); - l.undoableEditHappened(event); - } + UndoableEditEvent event; + Iterator iter; + + // Do nothing if we have no listeners. + if (listeners.isEmpty()) + return; + + event = new UndoableEditEvent(realSource, edit); + + // We clone the vector because this allows listeners to register + // or unregister listeners in their undoableEditHappened method. + // Otherwise, this would throw exceptions (in the case of + // Iterator, a java.util.ConcurrentModificationException; in the + // case of a direct loop over the Vector elements, some + // index-out-of-bounds exception). + iter = ((Vector) listeners.clone()).iterator(); + while (iter.hasNext()) + ((UndoableEditListener) iter.next()).undoableEditHappened(event); }