/*
 * @(#)SupportsPropertyChange.java    1.0  22 August 2003
 *
 * Copyright 2004
 * College of Computer and Information Science
 * Northeastern University
 * Boston, MA  02115
 *
 * The Java Power Tools software may be used for educational
 * purposes as long as this copyright notice is retained intact
 * at the top of all source files.
 *
 * To discuss possible commercial use of this software, 
 * contact Richard Rasala at Northeastern University, 
 * College of Computer and Information Science,
 * 617-373-2462 or rasala@ccs.neu.edu.
 *
 * The Java Power Tools software has been designed and built
 * in collaboration with Viera Proulx and Jeff Raab.
 *
 * Should this software be modified, the words "Modified from 
 * Original" must be included as a comment below this notice.
 *
 * All publication rights are retained.  This software or its 
 * documentation may not be published in any media either
 * in whole or in part without explicit permission.
 *
 * This software was created with support from Northeastern 
 * University and from NSF grant DUE-9950829.
 */

package edu.neu.ccs.gui;

import java.beans.*;

/**
 * <P><CODE>SupportsPropertyChange</CODE> is an interface for objects
 * that can add <CODE>PropertyChangeListener</CODE> objects, can fire
 * <CODE>PropertyChangeEvent</CODE> events directly to those listeners,
 * and can forward internal <CODE>PropertyChangeEvent</CODE> events to
 * those listeners as well.</P>
 *
 * <P>Many of the methods in this interface are identical to methods
 * found in one or more of the following Java classes:</P>
 * <CODE><UL>
 *   <LI>Component</LI>
 *   <LI>JComponent</LI>
 *   <LI>PropertyChangeSupport</LI>
 *   <LI>SwingPropertyChangeSupport</LI>
 * </UL></CODE>
 * 
 * <P>The documentation below will indicate which of these classes has
 * the particular method.</P>
 *
 * @author  Richard Rasala
 * @version 2.3
 * @since   2.3
 */
public interface SupportsPropertyChange {

    /**
     * <P>Add a <CODE>PropertyChangeListener</CODE> to the listener list.
     * The listener is registered for all properties.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>Component</LI>
     *   <LI>JComponent</LI>
     *   <LI>PropertyChangeSupport</LI>
     *   <LI>SwingPropertyChangeSupport</LI>
     * </UL></CODE>
     *
     * @param listener the PropertyChangeListener to be added
     */
    void addPropertyChangeListener(PropertyChangeListener listener);
    
    
    /**
     * <P>Add a <CODE>PropertyChangeListener</CODE> to the listener list for a
     * specific property.  The listener will be invoked only when a call on
     * <CODE>firePropertyChange</CODE> names that specific property.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>Component</LI>
     *   <LI>JComponent</LI>
     *   <LI>PropertyChangeSupport</LI>
     *   <LI>SwingPropertyChangeSupport</LI>
     * </UL></CODE>
     *
     * @param propertyName the name of the property to listen on 
     * @param listener the PropertyChangeListener to be added
     */
    void addPropertyChangeListener(
        String propertyName,
        PropertyChangeListener listener); 
    
    
    /**
     * <P>Add all items in the given <CODE>PropertyChangeListener</CODE> array
     * to the listener list.  These items are registered for all properties.</P>
     *
     * @param listeners the PropertyChangeListener array to be added
     */
    void addPropertyChangeListeners(PropertyChangeListener[] listeners);
    
    
    /**
     * <P>Add all items in the given <CODE>PropertyChangeListener</CODE> array
     * to the listener list for a specific property.  These items will be invoked
     * only when a call on <CODE>firePropertyChange</CODE> names that specific
     * property.</P>
     *
     * @param listeners the PropertyChangeListener array to be added
     */
    void addPropertyChangeListeners(
        String propertyName,
        PropertyChangeListener[] listeners);
    
    
    /**
     * <P>Remove a <CODE>PropertyChangeListener</CODE> from the listener list.
     * This removes a <CODE>PropertyChangeListener</CODE> that was registered
     * for all properties.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>Component</LI>
     *   <LI>JComponent</LI>
     *   <LI>PropertyChangeSupport</LI>
     *   <LI>SwingPropertyChangeSupport</LI>
     * </UL></CODE>
     *
     * @param listener the PropertyChangeListener to be removed
     */
    void removePropertyChangeListener(PropertyChangeListener listener);
    
    
    /**
     * <P>Remove a <CODE>PropertyChangeListener</CODE> for a specific property.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>Component</LI>
     *   <LI>JComponent</LI>
     *   <LI>PropertyChangeSupport</LI>
     *   <LI>SwingPropertyChangeSupport</LI>
     * </UL></CODE>
     *
     * @param propertyName the name of the property that was listened on 
     * @param listener the PropertyChangeListener to be removed
     */
    void removePropertyChangeListener(
        String propertyName,
        PropertyChangeListener listener);
    
    
    /**
     * <P>Returns an array of all listeners that were added to this object.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>Component</LI>
     *   <LI>JComponent</LI>
     *   <LI>PropertyChangeSupport</LI>
     *   <LI>SwingPropertyChangeSupport</LI>
     * </UL></CODE>
     *
     * @return an array with all listeners
     */
    PropertyChangeListener[] getPropertyChangeListeners();   
    
    
    /**
     * <P>Returns an array of all listeners that were added to this object
     * and associated with the named property.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>Component</LI>
     *   <LI>JComponent</LI>
     *   <LI>PropertyChangeSupport</LI>
     *   <LI>SwingPropertyChangeSupport</LI>
     * </UL></CODE>
     *
     * @param  propertyName the name of the property to seek 
     * @return an array with all listeners for the given named property
     */
    PropertyChangeListener[] getPropertyChangeListeners(String propertyName);
    
    
    /**
     * <P>Check if there are any listeners for a specific property.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>PropertyChangeSupport</LI>
     *   <LI>SwingPropertyChangeSupport</LI>
     * </UL></CODE>
     *
     * @param  propertyName the name of the property to check
     * @return whether or not there are any listeners for a specific property
     */
    boolean hasListeners(String propertyName);
    
    
    /**
     * <P>Report a bound property update to any registered listeners.
     * No event is fired if the old and new values are equal and non-null.</P>
     *
     * <P>This method is found in:</P>
     * <UL>
     *   <LI><CODE>Component</CODE> as a <CODE>protected</CODE> method</LI>
     *   <LI><CODE>JComponent</CODE> as a <CODE>protected</CODE> method</LI>
     *   <LI><CODE>PropertyChangeSupport</CODE></LI>
     *   <LI><CODE>SwingPropertyChangeSupport</CODE></LI>
     * </UL>
     *
     * @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
     */
    void firePropertyChange(
        String propertyName,
        Object oldValue,
        Object newValue);
    
    
    /**
     * <P>Report a bound property update to any registered listeners.
     * No event is fired if the old and new values are equal.</P>
     *
     * <P>This is merely a convenience wrapper around the more general
     * firePropertyChange method that takes Object values.</P>
     *
     * <P>This method is found in:</P>
     * <UL>
     *   <LI><CODE>Component</CODE> as a <CODE>protected</CODE> method</LI>
     *   <LI><CODE>JComponent</CODE></LI>
     *   <LI><CODE>PropertyChangeSupport</CODE></LI>
     *   <LI><CODE>SwingPropertyChangeSupport</CODE></LI>
     * </UL>
     *
     * @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
     */
    void firePropertyChange(
        String propertyName,
        boolean oldValue,
        boolean newValue);
    
    
    /**
     * <P>Report a bound property update to any registered listeners.
     * No event is fired if the old and new values are equal.</P>
     *
     * <P>This is merely a convenience wrapper around the more general
     * firePropertyChange method that takes Object values.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>JComponent
     * </UL></CODE>
     *
     * @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
     */
    void firePropertyChange(
        String propertyName,
        char oldValue,
        char newValue);
    
    
    /**
     * <P>Report a bound property update to any registered listeners.
     * No event is fired if the old and new values are equal.</P>
     *
     * <P>This is merely a convenience wrapper around the more general
     * firePropertyChange method that takes Object values.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>JComponent
     * </UL></CODE>
     *
     * @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
     */
    void firePropertyChange(
        String propertyName,
        byte oldValue,
        byte newValue);
    
    
    /**
     * <P>Report a bound property update to any registered listeners.
     * No event is fired if the old and new values are equal.</P>
     *
     * <P>This is merely a convenience wrapper around the more general
     * firePropertyChange method that takes Object values.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>JComponent
     * </UL></CODE>
     *
     * @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
     */
    void firePropertyChange(
        String propertyName,
        short oldValue,
        short newValue);
    
    
    /**
     * <P>Report a bound property update to any registered listeners.
     * No event is fired if the old and new values are equal.</P>
     *
     * <P>This is merely a convenience wrapper around the more general
     * firePropertyChange method that takes Object values.</P>
     *
     * <P>This method is found in:</P>
     * <UL>
     *   <LI><CODE>Component</CODE> as a <CODE>protected</CODE> method</LI>
     *   <LI><CODE>JComponent</CODE></LI>
     *   <LI><CODE>PropertyChangeSupport</CODE></LI>
     *   <LI><CODE>SwingPropertyChangeSupport</CODE></LI>
     * </UL>
     *
     * @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
     */
    void firePropertyChange(
        String propertyName,
        int oldValue,
        int newValue);
    
    
    /**
     * <P>Report a bound property update to any registered listeners.
     * No event is fired if the old and new values are equal.</P>
     *
     * <P>This is merely a convenience wrapper around the more general
     * firePropertyChange method that takes Object values.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>JComponent
     * </UL></CODE>
     *
     * @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
     */
    void firePropertyChange(
        String propertyName,
        long oldValue,
        long newValue);
    
    
    /**
     * <P>Report a bound property update to any registered listeners.
     * No event is fired if the old and new values are equal.</P>
     *
     * <P>This is merely a convenience wrapper around the more general
     * firePropertyChange method that takes Object values.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>JComponent
     * </UL></CODE>
     *
     * @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
     */
    void firePropertyChange(
        String propertyName,
        float oldValue,
        float newValue);
    
    
    /**
     * <P>Report a bound property update to any registered listeners.
     * No event is fired if the old and new values are equal.</P>
     *
     * <P>This is merely a convenience wrapper around the more general
     * firePropertyChange method that takes Object values.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>JComponent
     * </UL></CODE>
     *
     * @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
     */
    void firePropertyChange(
        String propertyName,
        double oldValue,
        double newValue);
    
    
    /**
     * <P>Fire an existing <CODE>PropertyChangeEvent</CODE> to any registered
     * listeners.  No event is fired if the given event's old and new values
     * are equal and non-null.</P>
     *
     * <P>This method is found in:</P>
     * <CODE><UL>
     *   <LI>PropertyChangeSupport</LI>
     *   <LI>SwingPropertyChangeSupport</LI>
     * </UL></CODE>
     *
     * @param evt the PropertyChangeEvent object
     */
    void firePropertyChange(PropertyChangeEvent evt);
    
    
    /**
     * <P>Returns the <CODE>PropertyChangeForwardingListener</CODE> that
     * will forward the property change events it receives to this object.</P>
     *
     * @return the forwarding listener
     */
    PropertyChangeForwardingListener getForwardingListener();
    
    
    /**
     * Add the forwarding listener as a property change listener
     * for the given object if the object supports property change.
     *
     * @param object the object that should add the forwarding listener
     */
    void addForwardingListener(Object object);    
    
    
    /**
     * Remove the forwarding listener as a property change listener
     * for the given object if the object supports property change.
     *
     * @param object the object that should remove the forwarding listener
     */
    void removeForwardingListener(Object object);    
    
    
    /**
     * Remove the forwarding listener as a property change listener
     * for the old object if the old object supports property change
     * and add the forwarding listener as a property change listener
     * for the new object if the new object supports property change.
     *
     * @param oldobject the old object that should remove the forwarding listener
     * @param newobject the new object that should add the forwarding listener
     */
    void removeAndAddForwardingListener(Object oldobject, Object newobject);    
    
}
