⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vetoablechangemulticaster.java

📁 采用JAVA开发
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
   * @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 + -