package ch.werner_randelshofer.gui.model;/*Copyright (C) 1999 Werner Randelshoferwerner.randelshofer@mythen.chhttp://www.mythen.ch/w.randelshofer/    Permission to use this release of DefaultBoundedRangeModel is herebygranted without fee provided that the complete copyrightnotice and this permission notice appear in all copiesand in supporting documentation.*/import ch.werner_randelshofer.gui.event.ChangeListener;import ch.werner_randelshofer.gui.event.ChangeEvent;import ch.werner_randelshofer.gui.event.EventListenerList;/**Default bounded range model.@author	Werner Randelshofer, Staldenmattweg 2, CH-6405 Immensee, Switzerland.@version	1.0	20.02.1999	Derived from javax.swing.BoundedRangeModel.*/public class DefaultBoundedRangeModelimplements BoundedRangeModel	{    /**     * Only one ChangeEvent is needed per model instance since the     * event's only (read-only) state is the source property.  The source     * of events generated here is always "this".     */    protected transient ChangeEvent changeEvent_ = null;    /** The listeners waiting for model changes. */    protected EventListenerList listenerList_ = new EventListenerList();    private int value_ = 0;    private int extent_ = 0;    private int min_ = 0;    private int max_ = 100;    private boolean isAdjusting_ = false;    /**     * Initializes all of the properties with default values.     * Those values are:     * <ul>     * <li><code>value_</code> = 0     * <li><code>extent_</code> = 0     * <li><code>minimum</code> = 0     * <li><code>maximum</code> = 100     * <li><code>adjusting</code> = false     * </ul>     */    public DefaultBoundedRangeModel() {    }    /**     * Initializes value_, extent_, minimum and maximum. Adjusting is false.     * Throws an IllegalArgumentException if the following constraints     * aren't satisfied:     * <pre>     * min_ <= value_ <= value_+extent_ <= max_     * </pre>     */    public DefaultBoundedRangeModel(int value_, int extent_, int min_, int max_)    {        if ((max_ >= min_) && (value_ >= min_) && ((value_ + extent_) <= max_)) {            this.value_ = value_;            this.extent_ = extent_;            this.min_ = min_;            this.max_ = max_;        }        else {            throw new IllegalArgumentException("invalid range properties");        }    }    /**     * Return the model's current value_.     * @return the model's current value_     * @see #setValue     * @see BoundedRangeModel#getValue     */    public int getValue() {      return value_;     }    /**     * Return the model's extent_.     * @return the model's extent_     * @see #setExtent     * @see BoundedRangeModel#getExtent     */    public int getExtent() {      return extent_;     }    /**     * Return the model's minimum.     * @return the model's minimum     * @see #setMinimum     * @see BoundedRangeModel#getMinimum     */    public int getMinimum() {      return min_;     }    /**     * Return the model's maximum.     * @return  the model's maximum     * @see #setMaximum     * @see BoundedRangeModel#getMaximum     */    public int getMaximum() {        return max_;     }    /**      * Sets the current value_ of the model. For a slider, that     * determines where the knob appears. Ensures that the new      * value_, <I>n</I> falls within the model's constraints:     * <pre>     *     minimum <= value_ <= value_+extent_ <= maximum     * </pre>     *      * @see BoundedRangeModel#setValue     */    public void setValue(int n) {        int newValue = Math.max(n, min_);        if(newValue + extent_ > max_) {            newValue = max_ - extent_;         }        setRangeProperties(newValue, extent_, min_, max_, isAdjusting_);    }    /**      * Sets the extent_ to <I>n</I> after ensuring that <I>n</I>      * is greater than or equal to zero and falls within the model's      * constraints:     * <pre>     *     minimum <= value_ <= value_+extent_ <= maximum     * </pre>     * @see BoundedRangeModel#setExtent     */    public void setExtent(int n) {        int newExtent = Math.max(0, n);        if(value_ + newExtent > max_) {            newExtent = max_ - value_;        }        setRangeProperties(value_, newExtent, min_, max_, isAdjusting_);    }    /**      * Sets the minimum to <I>n</I> after ensuring that <I>n</I>      * that the other three properties obey the model's constraints:     * <pre>     *     minimum <= value_ <= value_+extent_ <= maximum     * </pre>     * @see #getMinimum     * @see BoundedRangeModel#setMinimum     */    public void setMinimum(int n) {        int newMax = Math.max(n, max_);        int newValue = Math.max(n, value_);        int newExtent = Math.min(newMax - newValue, extent_);        setRangeProperties(newValue, newExtent, n, newMax, isAdjusting_);    }    /**      * Sets the maximum to <I>n</I> after ensuring that <I>n</I>      * that the other three properties obey the model's constraints:     * <pre>     *     minimum <= value_ <= value_+extent_ <= maximum     * </pre>     * @see BoundedRangeModel#setMaximum     */    public void setMaximum(int n) {        int newMin = Math.min(n, min_);        int newValue = Math.min(n, value_);        int newExtent = Math.min(n - newValue, extent_);        setRangeProperties(newValue, newExtent, newMin, n, isAdjusting_);    }    /**     * Sets the valueIsAdjusting property.     *      * @see #getValueIsAdjusting     * @see #setValue     * @see BoundedRangeModel#setValueIsAdjusting     */    public void setValueIsAdjusting(boolean b) {        setRangeProperties(value_, extent_, min_, max_, b);    }    /**     * Returns true if the value_ is in the process of changing     * as a result of actions being taken by the user.     *     * @return the value_ of the valueIsAdjusting property     * @see #setValue     * @see BoundedRangeModel#getValueIsAdjusting     */    public boolean getValueIsAdjusting() {        return isAdjusting_;     }    /**     * Sets all of the BoundedRangeModel properties after forcing     * the arguments to obey the usual constraints:     * <pre>     *     minimum <= value_ <= value_+extent_ <= maximum     * </pre>     * <p>     * At most, one ChangeEvent is generated.     *      * @see BoundedRangeModel#setRangeProperties     * @see #setValue     * @see #setExtent     * @see #setMinimum     * @see #setMaximum     * @see #setValueIsAdjusting     */    public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting)    {        if(newMin > newMax)            newMin = newMax;        if(newValue > newMax)            newMax = newValue;        if(newValue < newMin)            newMin = newValue;        if((newExtent + newValue) > newMax)            newExtent = newMax - newValue;        if(newExtent < 0)            newExtent = 0;        boolean isChange =            (newValue != value_) ||            (newExtent != extent_) ||            (newMin != min_) ||            (newMax != max_) ||            (adjusting != isAdjusting_);        if (isChange) {            value_ = newValue;            extent_ = newExtent;            min_ = newMin;            max_ = newMax;            isAdjusting_ = adjusting;            fireStateChanged();        }    }    /**     * Adds a ChangeListener.  The change listeners are run each     * time any one of the Bounded Range model properties changes.     *     * @param l the ChangeListener to add     * @see #removeChangeListener     * @see BoundedRangeModel#addChangeListener     */    public void addChangeListener(ChangeListener l) {        listenerList_.add(ChangeListener.class, l);    }        /**     * Removes a ChangeListener.     *     * @param l the ChangeListener to remove     * @see #addChangeListener     * @see BoundedRangeModel#removeChangeListener     */    public void removeChangeListener(ChangeListener l) {        listenerList_.remove(ChangeListener.class, l);    }    /**      * Run each ChangeListeners stateChanged() method.     *      * @see #setRangeProperties     * @see EventListenerList     */    protected void fireStateChanged()     {        Object[] listeners = listenerList_.getListenerList();        for (int i = listeners.length - 2; i >= 0; i -=2 ) {            if (listeners[i] == ChangeListener.class) {                if (changeEvent_ == null) {                    changeEvent_ = new ChangeEvent(this);                }                ((ChangeListener)listeners[i+1]).stateChanged(changeEvent_);            }                  }    }           /**     * Returns a string that displays all of the BoundedRangeModel properties.     */    public String toString()  {        String modelString =            "value_=" + getValue() + ", " +            "extent_=" + getExtent() + ", " +            "min_=" + getMinimum() + ", " +            "max_=" + getMaximum() + ", " +            "adj=" + getValueIsAdjusting();        return getClass().getName() + "[" + modelString + "]";    }	}