Commit b3db7ef1 by Sascha Brawer Committed by Michael Koch

DefaultBoundedRangeModel.java: Documented API.

2004-01-07  Sascha Brawer  <brawer@dandelis.ch>

	* javax/swing/DefaultBoundedRangeModel.java: Documented API.
	(changeEvent): Create event object on demand.
	(DefaultBoundedRangeModel, toString, setValue, setExtent,
	setMinimum, setMaximum, setValueIsAdjusting, setRangeProperties,
	fireStateChanged): Re-written.
	* javax/swing/event/EventListenerList.java: Reformatted, document
	typical usage.
	(toString): Implemented.
	(getListeners): Re-written.
	(remove): Re-written.
	(add): Re-written.
	(NO_LISTENERS): New singleton field.
	(listenerList): Declare as transient; document.
	(serialVersionUID): Document.
	(getListenerCount(Class)): More efficient implementation,
	also accepts null argument.  Improve Javadoc.
	(getListenerCount()): Remove unnecessary cast; docfix.
	* javax/swing/undo/UndoableEditSupport.java:
	Re-format, document.
	(UndoableEditSupport): Set realSource field. Improve documentation.
	(_postEdit): Iterate over cloned listener vector.
	(toString): Don't emit realSource.
	(beginUpdate, endUpdate): Support nested updates.
	(postEdit): Use compound edit if present.

From-SVN: r75505
parent b48a0c18
2004-01-07 Sascha Brawer <brawer@dandelis.ch>
* javax/swing/DefaultBoundedRangeModel.java: Documented API.
(changeEvent): Create event object on demand.
(DefaultBoundedRangeModel, toString, setValue, setExtent,
setMinimum, setMaximum, setValueIsAdjusting, setRangeProperties,
fireStateChanged): Re-written.
* javax/swing/event/EventListenerList.java: Reformatted, document
typical usage.
(toString): Implemented.
(getListeners): Re-written.
(remove): Re-written.
(add): Re-written.
(NO_LISTENERS): New singleton field.
(listenerList): Declare as transient; document.
(serialVersionUID): Document.
(getListenerCount(Class)): More efficient implementation,
also accepts null argument. Improve Javadoc.
(getListenerCount()): Remove unnecessary cast; docfix.
* javax/swing/undo/UndoableEditSupport.java:
Re-format, document.
(UndoableEditSupport): Set realSource field. Improve documentation.
(_postEdit): Iterate over cloned listener vector.
(toString): Don't emit realSource.
(beginUpdate, endUpdate): Support nested updates.
(postEdit): Use compound edit if present.
2004-01-06 Graydon Hoare <graydon@redhat.com> 2004-01-06 Graydon Hoare <graydon@redhat.com>
* java/awt/Container.java (swapComponents): Add forgotten * java/awt/Container.java (swapComponents): Add forgotten
......
/* UndoableEditSupport.java -- /* UndoableEditSupport.java --
Copyright (C) 2002, 2003 Free Software Foundation, Inc. Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath. This file is part of GNU Classpath.
...@@ -38,98 +38,112 @@ exception statement from your version. */ ...@@ -38,98 +38,112 @@ exception statement from your version. */
package javax.swing.undo; package javax.swing.undo;
import java.util.Iterator;
import java.util.Vector; import java.util.Vector;
import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener; import javax.swing.event.UndoableEditListener;
/** /**
* UndoableEditSupport * A helper class for supporting {@link
* @author Andrew Selkirk * javax.swing.event.UndoableEditListener}.
*
* @author <a href="mailto:aselkirk@sympatico.ca">Andrew Selkirk</a>
* @author <a href="mailto:brawer@dandelis.ch">Sascha Brawer</a>
*/ */
public class UndoableEditSupport public class UndoableEditSupport
{ {
//-------------------------------------------------------------
// Variables --------------------------------------------------
//-------------------------------------------------------------
/** /**
* updateLevel * The number of times that {@link #beginUpdate()} has been called
* without a matching call to {@link #endUpdate()}.
*/ */
protected int updateLevel; protected int updateLevel;
/** /**
* compoundEdit * compoundEdit
*/ */
protected CompoundEdit compoundEdit; protected CompoundEdit compoundEdit;
/** /**
* listeners * The currently registered listeners.
*/ */
protected Vector listeners = new Vector(); protected Vector listeners = new Vector();
/** /**
* realSource * The source of the broadcast UndoableEditEvents.
*/ */
protected Object realSource; protected Object realSource;
//-------------------------------------------------------------
// Initialization ---------------------------------------------
//-------------------------------------------------------------
/** /**
* Constructor UndoableEditSupport * Constructs a new helper for broadcasting UndoableEditEvents. The
* events will indicate the newly constructed
* <code>UndoableEditSupport</code> instance as their source.
*
* @see #UndoableEditSupport(java.lang.Object)
*/ */
public UndoableEditSupport() public UndoableEditSupport()
{ {
realSource = this;
} }
/** /**
* Constructor UndoableEditSupport * Constructs a new helper for broadcasting UndoableEditEvents.
* @param object TODO *
* @param realSource the source of the UndoableEditEvents that will
* be broadcast by this helper. If <code>realSource</code> is
* <code>null</code>, the events will indicate the newly constructed
* <code>UndoableEditSupport</code> instance as their source.
*/ */
public UndoableEditSupport(Object object) public UndoableEditSupport(Object realSource)
{ {
realSource = object; if (realSource == null)
realSource = this;
this.realSource = realSource;
} }
//-------------------------------------------------------------
// Methods ----------------------------------------------------
//-------------------------------------------------------------
/** /**
* toString * Returns a string representation of this object that may be useful
* @returns String * for debugging.
*/ */
public String toString() public String toString()
{ {
return (super.toString() + " realSource: " + realSource // Note that often, this.realSource == this. Therefore, dumping
+ " updateLevel: " + updateLevel); // realSource without additional checks may lead to infinite
// recursion. See Classpath bug #7119.
return super.toString() + " updateLevel: " + updateLevel
+ " listeners: " + listeners + " compoundEdit: " + compoundEdit;
} }
/** /**
* Add a listener. * Registers a listener.
* @param val the listener *
* @param val the listener to be added.
*/ */
public synchronized void addUndoableEditListener(UndoableEditListener val) public synchronized void addUndoableEditListener(UndoableEditListener val)
{ {
listeners.add(val); listeners.add(val);
} }
/** /**
* Remove a listener. * Unregisters a listener.
* @param val the listener * @param val the listener to be removed.
*/ */
public synchronized void removeUndoableEditListener(UndoableEditListener val) public synchronized void removeUndoableEditListener(UndoableEditListener val)
{ {
listeners.removeElement(val); listeners.removeElement(val);
} }
/** /**
* Return an array of all listeners. * Returns an array containing the currently registered listeners.
* @returns all the listeners
*/ */
public synchronized UndoableEditListener[] getUndoableEditListeners() public synchronized UndoableEditListener[] getUndoableEditListeners()
{ {
...@@ -137,78 +151,121 @@ public class UndoableEditSupport ...@@ -137,78 +151,121 @@ public class UndoableEditSupport
return (UndoableEditListener[]) listeners.toArray(result); return (UndoableEditListener[]) listeners.toArray(result);
} }
/** /**
* _postEdit * Notifies all registered listeners that an {@link
* @param value0 TODO * UndoableEditEvent} has occured.
*
* <p><b>Lack of Thread Safety:</b> It is <em>not</em> safe to call
* this method from concurrent threads, unless the call is protected
* by a synchronization on this <code>UndoableEditSupport</code>
* instance.
*
* @param edit the edit action to be posted.
*/ */
protected void _postEdit(UndoableEdit edit) protected void _postEdit(UndoableEdit edit)
{ {
UndoableEditEvent event = new UndoableEditEvent(realSource, edit); UndoableEditEvent event;
int max = listeners.size(); Iterator iter;
for (int i = 0; i < max; ++i)
{ // Do nothing if we have no listeners.
UndoableEditListener l if (listeners.isEmpty())
= (UndoableEditListener) (listeners.elementAt(i)); return;
l.undoableEditHappened(event);
} 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);
} }
/** /**
* postEdit * If {@link #beginEdit} has been called (so that the current
* @param value0 TODO * update level is greater than zero), adds the specified edit
* to {@link #compoundEdit}. Otherwise, notify listeners of the
* edit by calling {@link #_postEdit(UndoableEdit)}.
*
* <p><b>Thread Safety:</b> It is safe to call this method from any
* thread without external synchronization.
*
* @param edit the edit action to be posted.
*/ */
public synchronized void postEdit(UndoableEdit edit) public synchronized void postEdit(UndoableEdit edit)
{ {
if (compoundEdit == null) if (compoundEdit != null)
compoundEdit.addEdit(edit); compoundEdit.addEdit(edit);
else else
_postEdit(edit); _postEdit(edit);
} }
/** /**
* getUpdateLevel * Returns the current update level.
* @returns int
*/ */
public int getUpdateLevel() public int getUpdateLevel()
{ {
return updateLevel; return updateLevel;
} }
/** /**
* beginUpdate * Starts a (possibly nested) update session. If the current update
* level is zero, {@link #compoundEdit} is set to the result of the
* {@link #createCompoundEdit} method. In any case, the update level
* is increased by one.
*
* <p><b>Thread Safety:</b> It is safe to call this method from any
* thread without external synchronization.
*/ */
public synchronized void beginUpdate() public synchronized void beginUpdate()
{ {
if (compoundEdit != null) if (compoundEdit == null)
{ compoundEdit = createCompoundEdit();
// FIXME: what? We can't push a new one. This isn't even
// documented anyway.
endUpdate();
}
compoundEdit = createCompoundEdit();
++updateLevel; ++updateLevel;
} }
/** /**
* createCompoundEdit * Creates a new instance of {@link #CompoundEdit}. Called by {@link
* @returns CompoundEdit * #beginUpdate}. If a subclass wants {@link #beginUpdate} to work
* on a specific {@link #compoundEdit}, it should override this
* method.
*
* @returns a newly created instance of {@link #CompoundEdit}.
*/ */
protected CompoundEdit createCompoundEdit() protected CompoundEdit createCompoundEdit()
{ {
return new CompoundEdit(); return new CompoundEdit();
} }
/** /**
* endUpdate * Ends an update session. If the terminated session was the
* outermost session, {@link #compoundEdit} will receive an
* <code>end</code> message, and {@link #_postEdit} gets called in
* order to notify any listeners. Finally, the
* <code>compoundEdit</code> is discarded.
*
* <p><b>Thread Safety:</b> It is safe to call this method from any
* thread without external synchronization.
*/ */
public synchronized void endUpdate() public synchronized void endUpdate()
{ {
// FIXME: assert updateLevel == 1; if (updateLevel == 0)
throw new IllegalStateException();
if (--updateLevel > 0)
return;
compoundEdit.end(); compoundEdit.end();
CompoundEdit c = compoundEdit; _postEdit(compoundEdit);
compoundEdit = null; compoundEdit = null;
--updateLevel;
_postEdit(c);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment