package org.erikaredmark.util; import java.beans.PropertyChangeListener; /************************************************************************************************************************* * * Interface for corresponding class {@link ObservableModel}. Java does not allow multiple inheritence, even though in this * case it would be very useful because the underlying boilerplate functionality is the same for every class. Nevertheless, * in the event a class already has an inheritence relationship, or the underlying functionality needs to be changed, * a class can implement this interface to achieve the same effects. * <p/> * Implementors of this class are typically the 'Model' part of the Observer pattern. The interface takes advantage of * Property Change Events via {@link PropertyChangeListener}. * * @author TJS * ************************************************************************************************************************/ public interface IObservableModel { /********************************************************************************************************************* * * To be used by clients: Allows them to register a property change listener * * @param listener * the listener implements {@link PropertyChangeListener}. Listener will receive all events from this observable * ********************************************************************************************************************/ public void addPropertyChangeListener(PropertyChangeListener listener); /********************************************************************************************************************* * * To be used by clients: Allows them to remove a property change listener * * @param listener * the listener to remove. This comparison is done via == reference equality, so the actual reference must be * passed in * ********************************************************************************************************************/ public void removePropertyChangeListener(PropertyChangeListener listener); /********************************************************************************************************************* * * Adds a listener for a specific property * * @param propertyName * the property for the listener to listen for * * @param listener * the listener that will receive events only for this property on this observable * ********************************************************************************************************************/ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener); /********************************************************************************************************************* * * Removes a listener for a specific property. If the listener is added via * {@link #addPropertyChangeListener(PropertyChangeListener)}, then it is impossible to do the inverse and tell it * what not to listen to; it must have been added from {@link #addPropertyChangeListener(String, PropertyChangeListener)} * * @param propertyName * the property to remove the listener from listening from * * @param listener * the listener to remove. This comparison is done via == reference equality, so the actual reference must be * passed in * ********************************************************************************************************************/ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener); /********************************************************************************************************************* * * To be used by subclass only (or in case of Decorator, container object). Alerts all listeners that the state of * a variable has been changed. * <p/> * This method is <strong> not </strong> asynchronous. As such, when this called, code that runs directly after * can be guaranteed that all listeners have been notified. Whether or not the listener itself is asynchronous is not * under control of this method. * * @param propertyName * Name of the property, which roughly maps to the name of the variable. * * @param oldValue * Original value * * @param newValue * Newly set value * ********************************************************************************************************************/ public void firePropertyChange(String propertyName, Object oldVal, Object newVal); /********************************************************************************************************************* * * Tells the observable to suspend all property change events. This is typically used to reload or re-initialise an * object where it would be undesirable to fire a property change for every change. Suspending the property events * does not prevent objects from registering as listeners. They just will not receive any events until the observable * is resumed. * <p/> * This method <strong>must</strong> be paired with {@link #resumePropertyChangeEvents()} or the observable will * become useless. It may <strong>not </strong> be called twice in a row. * * @throws * IllegalStateException * if called again without first being closed by {@link #resumePropertyChangeEvents()} * ********************************************************************************************************************/ public void suspendPropertyChangeEvents(); /********************************************************************************************************************* * * Tells the obseverable to resume property change operations. This method may only be called once after the method * {@link #suspendPropertyChangeEvents()} is executed, and may not be called again unless closing out another * call to that method. Otherwise this will throw an exception. * * @throws * IllegalStateException * if called when the observable is not suspended * ********************************************************************************************************************/ public void resumePropertyChangeEvents(); }