📄 vetoablechangemulticaster.java
字号:
* @param listener The VetoableChangeListener to be added
* @exception NullPointerException If listener is null
*/
public void addVetoableChangeListenerIfAbsent(String propertyName,
VetoableChangeListener listener) {
if (listener == null) throw new NullPointerException();
VetoableChangeMulticaster child = null;
synchronized(this) {
if (children == null)
children = new HashMap();
else
child = (VetoableChangeMulticaster)children.get(propertyName);
if (child == null) {
child = new VetoableChangeMulticaster(source);
children.put(propertyName, child);
}
}
child.addVetoableChangeListenerIfAbsent(listener);
}
/**
* Remove a VetoableChangeListener for a specific property.
* Affects only the given property.
* If the listener is also registered for all properties,
* then it will continue to be registered for them.
*
* @param propertyName The name of the property that was listened on.
* @param listener The VetoableChangeListener to be removed
*/
public void removeVetoableChangeListener(String propertyName,
VetoableChangeListener listener) {
VetoableChangeMulticaster child = getChild(propertyName);
if (child != null)
child.removeVetoableChangeListener(listener);
}
/**
* Helper method to relay evt to all listeners.
* Called by all public fireVetoableChange methods.
**/
protected void multicast(PropertyChangeEvent evt) throws PropertyVetoException {
VetoableChangeListener[] array; // bind in synch block below
VetoableChangeMulticaster child = null;
synchronized (this) {
array = listeners;
if (children != null && evt.getPropertyName() != null)
child = (VetoableChangeMulticaster)children.get(evt.getPropertyName());
}
// Loop through array, and then cascade to child.
int i = 0; // make visible to catch clause
try {
for (i = 0; i < array.length; ++i)
array[i].vetoableChange(evt);
if (child != null)
child.multicast(evt);
}
catch (PropertyVetoException veto) {
// Revert all that have been notified
PropertyChangeEvent revert =
new PropertyChangeEvent(evt.getSource(),
evt.getPropertyName(),
evt.getNewValue(),
evt.getOldValue());
int lastNotified = (i < array.length)? i : (array.length-1);
for (int k = 0; k <= lastNotified; ++k) {
try {
array[k].vetoableChange(revert);
}
catch (PropertyVetoException ignore) {
// Cannot veto a reversion
}
}
// Rethrow the PropertyVetoException.
throw veto;
}
}
/**
* Report a vetoable property update to any registered listeners.
* Notifications are sent serially (although in no particular order)
* to the list of listeners,
* aborting if one throws PropertyVetoException. Upon this exception,
* fire a new event reverting this
* change to all listeners that have already been notified
* (ignoring any further vetos),
* suppress notifications to all other listeners, and
* then rethrow the PropertyVetoException.
* <p>
* No event is fired if old and new are equal non-null.
*
* @param propertyName The programmatic name of the property
* that was changed.
* @param oldValue The old value of the property.
* @param newValue The new value of the property.
* @exception PropertyVetoException if a recipient wishes the property
* change to be rolled back.
*/
public void fireVetoableChange(String propertyName,
Object oldValue, Object newValue) throws PropertyVetoException {
if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
multicast(new PropertyChangeEvent(source,
propertyName,
oldValue,
newValue));
}
}
/**
* Report a vetoable property update to any registered listeners.
* Notifications are sent serially (although in no particular order)
* to the list of listeners,
* aborting if one throws PropertyVetoException. Upon this exception,
* fire a new event reverting this
* change to all listeners that have already been notified
* (ignoring any further vetos),
* suppress notifications to all other listeners, and
* then rethrow the PropertyVetoException.
* <p>
* No event is fired if old and new are equal.
* <p>
* This is merely a convenience wrapper around the more general
* fireVetoableChange method that takes Object values.
*
* @param propertyName The programmatic name of the property
* that was changed.
* @param oldValue The old value of the property.
* @param newValue The new value of the property.
* @exception PropertyVetoException if the recipient wishes the property
* change to be rolled back.
*/
public void fireVetoableChange(String propertyName,
int oldValue, int newValue) throws PropertyVetoException {
if (oldValue != newValue) {
multicast(new PropertyChangeEvent(source,
propertyName,
new Integer(oldValue),
new Integer(newValue)));
}
}
/**
* Report a vetoable property update to any registered listeners.
* Notifications are sent serially (although in no particular order)
* to the list of listeners,
* aborting if one throws PropertyVetoException. Upon this exception,
* fire a new event reverting this
* change to all listeners that have already been notified
* (ignoring any further vetos),
* suppress notifications to all other listeners, and
* then rethrow the PropertyVetoException.
* <p>
* No event is fired if old and new are equal.
* <p>
* This is merely a convenience wrapper around the more general
* fireVetoableChange method that takes Object values.
*
* @param propertyName The programmatic name of the property
* that was changed.
* @param oldValue The old value of the property.
* @param newValue The new value of the property.
* @exception PropertyVetoException if the recipient wishes the property
* change to be rolled back.
*/
public void fireVetoableChange(String propertyName,
boolean oldValue, boolean newValue) throws PropertyVetoException {
if (oldValue != newValue) {
multicast(new PropertyChangeEvent(source,
propertyName,
new Boolean(oldValue),
new Boolean(newValue)));
}
}
/**
* Report a vetoable property update to any registered listeners.
* Notifications are sent serially (although in no particular order)
* to the list of listeners,
* aborting if one throws PropertyVetoException. Upon this exception,
* fire a new event reverting this
* change to all listeners that have already been notified
* (ignoring any further vetos),
* suppress notifications to all other listeners, and
* then rethrow the PropertyVetoException.
* <p>
* No event is fired if old and new are equal and non-null.
*
* equal and non-null.
* @param evt The PropertyChangeEvent object.
* @exception PropertyVetoException if the recipient wishes the property
* change to be rolled back.
*/
public void fireVetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
Object oldValue = evt.getOldValue();
Object newValue = evt.getNewValue();
if (oldValue == null || newValue == null || !oldValue.equals(newValue))
multicast(evt);
}
/**
* Check if there are any listeners for a specific property.
* If propertyName is null, return whether there are any listeners at all.
*
* @param propertyName the property name.
* @return true if there are one or more listeners for the given property
*
*/
public boolean hasListeners(String propertyName) {
VetoableChangeMulticaster child;
synchronized (this) {
if (listeners.length > 0)
return true;
else if (propertyName == null || children == null)
return false;
else {
child = (VetoableChangeMulticaster)children.get(propertyName);
if (child == null)
return false;
}
}
return child.hasListeners(null);
}
/**
* @serialData Null terminated list of <code>VetoableChangeListeners</code>.
* <p>
* At serialization time we skip non-serializable listeners and
* only serialize the serializable listeners.
*
*/
private synchronized void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
for (int i = 0; i < listeners.length; i++) {
VetoableChangeListener l = listeners[i];
if (listeners[i] instanceof Serializable) {
s.writeObject(listeners[i]);
}
}
s.writeObject(null);
}
private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
listeners = new VetoableChangeListener[0]; // paranoically reset
s.defaultReadObject();
Object listenerOrNull;
while (null != (listenerOrNull = s.readObject())) {
addVetoableChangeListener((VetoableChangeListener)listenerOrNull);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -