📄 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 + -