Home » openjdk-7 » javax » swing » [javadoc | source]

    1   /*
    2    * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package javax.swing;
   27   
   28   import javax.swing.event;
   29   import java.io.Serializable;
   30   import java.util.EventListener;
   31   
   32   /**
   33    * A generic implementation of BoundedRangeModel.
   34    * <p>
   35    * <strong>Warning:</strong>
   36    * Serialized objects of this class will not be compatible with
   37    * future Swing releases. The current serialization support is
   38    * appropriate for short term storage or RMI between applications running
   39    * the same version of Swing.  As of 1.4, support for long term storage
   40    * of all JavaBeans<sup><font size="-2">TM</font></sup>
   41    * has been added to the <code>java.beans</code> package.
   42    * Please see {@link java.beans.XMLEncoder}.
   43    *
   44    * @author David Kloba
   45    * @author Hans Muller
   46    * @see BoundedRangeModel
   47    */
   48   public class DefaultBoundedRangeModel implements BoundedRangeModel, Serializable
   49   {
   50       /**
   51        * Only one <code>ChangeEvent</code> is needed per model instance since the
   52        * event's only (read-only) state is the source property.  The source
   53        * of events generated here is always "this".
   54        */
   55       protected transient ChangeEvent changeEvent = null;
   56   
   57       /** The listeners waiting for model changes. */
   58       protected EventListenerList listenerList = new EventListenerList();
   59   
   60       private int value = 0;
   61       private int extent = 0;
   62       private int min = 0;
   63       private int max = 100;
   64       private boolean isAdjusting = false;
   65   
   66   
   67       /**
   68        * Initializes all of the properties with default values.
   69        * Those values are:
   70        * <ul>
   71        * <li><code>value</code> = 0
   72        * <li><code>extent</code> = 0
   73        * <li><code>minimum</code> = 0
   74        * <li><code>maximum</code> = 100
   75        * <li><code>adjusting</code> = false
   76        * </ul>
   77        */
   78       public DefaultBoundedRangeModel() {
   79       }
   80   
   81   
   82       /**
   83        * Initializes value, extent, minimum and maximum. Adjusting is false.
   84        * Throws an <code>IllegalArgumentException</code> if the following
   85        * constraints aren't satisfied:
   86        * <pre>
   87        * min &lt;= value &lt;= value+extent &lt;= max
   88        * </pre>
   89        */
   90       public DefaultBoundedRangeModel(int value, int extent, int min, int max)
   91       {
   92           if ((max >= min) &&
   93               (value >= min) &&
   94               ((value + extent) >= value) &&
   95               ((value + extent) <= max)) {
   96               this.value = value;
   97               this.extent = extent;
   98               this.min = min;
   99               this.max = max;
  100           }
  101           else {
  102               throw new IllegalArgumentException("invalid range properties");
  103           }
  104       }
  105   
  106   
  107       /**
  108        * Returns the model's current value.
  109        * @return the model's current value
  110        * @see #setValue
  111        * @see BoundedRangeModel#getValue
  112        */
  113       public int getValue() {
  114         return value;
  115       }
  116   
  117   
  118       /**
  119        * Returns the model's extent.
  120        * @return the model's extent
  121        * @see #setExtent
  122        * @see BoundedRangeModel#getExtent
  123        */
  124       public int getExtent() {
  125         return extent;
  126       }
  127   
  128   
  129       /**
  130        * Returns the model's minimum.
  131        * @return the model's minimum
  132        * @see #setMinimum
  133        * @see BoundedRangeModel#getMinimum
  134        */
  135       public int getMinimum() {
  136         return min;
  137       }
  138   
  139   
  140       /**
  141        * Returns the model's maximum.
  142        * @return  the model's maximum
  143        * @see #setMaximum
  144        * @see BoundedRangeModel#getMaximum
  145        */
  146       public int getMaximum() {
  147           return max;
  148       }
  149   
  150   
  151       /**
  152        * Sets the current value of the model. For a slider, that
  153        * determines where the knob appears. Ensures that the new
  154        * value, <I>n</I> falls within the model's constraints:
  155        * <pre>
  156        *     minimum &lt;= value &lt;= value+extent &lt;= maximum
  157        * </pre>
  158        *
  159        * @see BoundedRangeModel#setValue
  160        */
  161       public void setValue(int n) {
  162           n = Math.min(n, Integer.MAX_VALUE - extent);
  163   
  164           int newValue = Math.max(n, min);
  165           if (newValue + extent > max) {
  166               newValue = max - extent;
  167           }
  168           setRangeProperties(newValue, extent, min, max, isAdjusting);
  169       }
  170   
  171   
  172       /**
  173        * Sets the extent to <I>n</I> after ensuring that <I>n</I>
  174        * is greater than or equal to zero and falls within the model's
  175        * constraints:
  176        * <pre>
  177        *     minimum &lt;= value &lt;= value+extent &lt;= maximum
  178        * </pre>
  179        * @see BoundedRangeModel#setExtent
  180        */
  181       public void setExtent(int n) {
  182           int newExtent = Math.max(0, n);
  183           if(value + newExtent > max) {
  184               newExtent = max - value;
  185           }
  186           setRangeProperties(value, newExtent, min, max, isAdjusting);
  187       }
  188   
  189   
  190       /**
  191        * Sets the minimum to <I>n</I> after ensuring that <I>n</I>
  192        * that the other three properties obey the model's constraints:
  193        * <pre>
  194        *     minimum &lt;= value &lt;= value+extent &lt;= maximum
  195        * </pre>
  196        * @see #getMinimum
  197        * @see BoundedRangeModel#setMinimum
  198        */
  199       public void setMinimum(int n) {
  200           int newMax = Math.max(n, max);
  201           int newValue = Math.max(n, value);
  202           int newExtent = Math.min(newMax - newValue, extent);
  203           setRangeProperties(newValue, newExtent, n, newMax, isAdjusting);
  204       }
  205   
  206   
  207       /**
  208        * Sets the maximum to <I>n</I> after ensuring that <I>n</I>
  209        * that the other three properties obey the model's constraints:
  210        * <pre>
  211        *     minimum &lt;= value &lt;= value+extent &lt;= maximum
  212        * </pre>
  213        * @see BoundedRangeModel#setMaximum
  214        */
  215       public void setMaximum(int n) {
  216           int newMin = Math.min(n, min);
  217           int newExtent = Math.min(n - newMin, extent);
  218           int newValue = Math.min(n - newExtent, value);
  219           setRangeProperties(newValue, newExtent, newMin, n, isAdjusting);
  220       }
  221   
  222   
  223       /**
  224        * Sets the <code>valueIsAdjusting</code> property.
  225        *
  226        * @see #getValueIsAdjusting
  227        * @see #setValue
  228        * @see BoundedRangeModel#setValueIsAdjusting
  229        */
  230       public void setValueIsAdjusting(boolean b) {
  231           setRangeProperties(value, extent, min, max, b);
  232       }
  233   
  234   
  235       /**
  236        * Returns true if the value is in the process of changing
  237        * as a result of actions being taken by the user.
  238        *
  239        * @return the value of the <code>valueIsAdjusting</code> property
  240        * @see #setValue
  241        * @see BoundedRangeModel#getValueIsAdjusting
  242        */
  243       public boolean getValueIsAdjusting() {
  244           return isAdjusting;
  245       }
  246   
  247   
  248       /**
  249        * Sets all of the <code>BoundedRangeModel</code> properties after forcing
  250        * the arguments to obey the usual constraints:
  251        * <pre>
  252        *     minimum &lt;= value &lt;= value+extent &lt;= maximum
  253        * </pre>
  254        * <p>
  255        * At most, one <code>ChangeEvent</code> is generated.
  256        *
  257        * @see BoundedRangeModel#setRangeProperties
  258        * @see #setValue
  259        * @see #setExtent
  260        * @see #setMinimum
  261        * @see #setMaximum
  262        * @see #setValueIsAdjusting
  263        */
  264       public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting)
  265       {
  266           if (newMin > newMax) {
  267               newMin = newMax;
  268           }
  269           if (newValue > newMax) {
  270               newMax = newValue;
  271           }
  272           if (newValue < newMin) {
  273               newMin = newValue;
  274           }
  275   
  276           /* Convert the addends to long so that extent can be
  277            * Integer.MAX_VALUE without rolling over the sum.
  278            * A JCK test covers this, see bug 4097718.
  279            */
  280           if (((long)newExtent + (long)newValue) > newMax) {
  281               newExtent = newMax - newValue;
  282           }
  283   
  284           if (newExtent < 0) {
  285               newExtent = 0;
  286           }
  287   
  288           boolean isChange =
  289               (newValue != value) ||
  290               (newExtent != extent) ||
  291               (newMin != min) ||
  292               (newMax != max) ||
  293               (adjusting != isAdjusting);
  294   
  295           if (isChange) {
  296               value = newValue;
  297               extent = newExtent;
  298               min = newMin;
  299               max = newMax;
  300               isAdjusting = adjusting;
  301   
  302               fireStateChanged();
  303           }
  304       }
  305   
  306   
  307       /**
  308        * Adds a <code>ChangeListener</code>.  The change listeners are run each
  309        * time any one of the Bounded Range model properties changes.
  310        *
  311        * @param l the ChangeListener to add
  312        * @see #removeChangeListener
  313        * @see BoundedRangeModel#addChangeListener
  314        */
  315       public void addChangeListener(ChangeListener l) {
  316           listenerList.add(ChangeListener.class, l);
  317       }
  318   
  319   
  320       /**
  321        * Removes a <code>ChangeListener</code>.
  322        *
  323        * @param l the <code>ChangeListener</code> to remove
  324        * @see #addChangeListener
  325        * @see BoundedRangeModel#removeChangeListener
  326        */
  327       public void removeChangeListener(ChangeListener l) {
  328           listenerList.remove(ChangeListener.class, l);
  329       }
  330   
  331   
  332       /**
  333        * Returns an array of all the change listeners
  334        * registered on this <code>DefaultBoundedRangeModel</code>.
  335        *
  336        * @return all of this model's <code>ChangeListener</code>s
  337        *         or an empty
  338        *         array if no change listeners are currently registered
  339        *
  340        * @see #addChangeListener
  341        * @see #removeChangeListener
  342        *
  343        * @since 1.4
  344        */
  345       public ChangeListener[] getChangeListeners() {
  346           return listenerList.getListeners(ChangeListener.class);
  347       }
  348   
  349   
  350       /**
  351        * Runs each <code>ChangeListener</code>'s <code>stateChanged</code> method.
  352        *
  353        * @see #setRangeProperties
  354        * @see EventListenerList
  355        */
  356       protected void fireStateChanged()
  357       {
  358           Object[] listeners = listenerList.getListenerList();
  359           for (int i = listeners.length - 2; i >= 0; i -=2 ) {
  360               if (listeners[i] == ChangeListener.class) {
  361                   if (changeEvent == null) {
  362                       changeEvent = new ChangeEvent(this);
  363                   }
  364                   ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
  365               }
  366           }
  367       }
  368   
  369   
  370       /**
  371        * Returns a string that displays all of the
  372        * <code>BoundedRangeModel</code> properties.
  373        */
  374       public String toString()  {
  375           String modelString =
  376               "value=" + getValue() + ", " +
  377               "extent=" + getExtent() + ", " +
  378               "min=" + getMinimum() + ", " +
  379               "max=" + getMaximum() + ", " +
  380               "adj=" + getValueIsAdjusting();
  381   
  382           return getClass().getName() + "[" + modelString + "]";
  383       }
  384   
  385       /**
  386        * Returns an array of all the objects currently registered as
  387        * <code><em>Foo</em>Listener</code>s
  388        * upon this model.
  389        * <code><em>Foo</em>Listener</code>s
  390        * are registered using the <code>add<em>Foo</em>Listener</code> method.
  391        * <p>
  392        * You can specify the <code>listenerType</code> argument
  393        * with a class literal, such as <code><em>Foo</em>Listener.class</code>.
  394        * For example, you can query a <code>DefaultBoundedRangeModel</code>
  395        * instance <code>m</code>
  396        * for its change listeners
  397        * with the following code:
  398        *
  399        * <pre>ChangeListener[] cls = (ChangeListener[])(m.getListeners(ChangeListener.class));</pre>
  400        *
  401        * If no such listeners exist,
  402        * this method returns an empty array.
  403        *
  404        * @param listenerType  the type of listeners requested;
  405        *          this parameter should specify an interface
  406        *          that descends from <code>java.util.EventListener</code>
  407        * @return an array of all objects registered as
  408        *          <code><em>Foo</em>Listener</code>s
  409        *          on this model,
  410        *          or an empty array if no such
  411        *          listeners have been added
  412        * @exception ClassCastException if <code>listenerType</code> doesn't
  413        *          specify a class or interface that implements
  414        *          <code>java.util.EventListener</code>
  415        *
  416        * @see #getChangeListeners
  417        *
  418        * @since 1.3
  419        */
  420       public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
  421           return listenerList.getListeners(listenerType);
  422       }
  423   }

Home » openjdk-7 » javax » swing » [javadoc | source]