KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > DefaultBoundedRangeModel


1 /*
2  * @(#)DefaultBoundedRangeModel.java 1.46 04/05/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing;
9
10 import javax.swing.event.*;
11 import java.io.Serializable JavaDoc;
12 import java.util.EventListener JavaDoc;
13
14 /**
15  * A generic implementation of BoundedRangeModel.
16  * <p>
17  * <strong>Warning:</strong>
18  * Serialized objects of this class will not be compatible with
19  * future Swing releases. The current serialization support is
20  * appropriate for short term storage or RMI between applications running
21  * the same version of Swing. As of 1.4, support for long term storage
22  * of all JavaBeans<sup><font size="-2">TM</font></sup>
23  * has been added to the <code>java.beans</code> package.
24  * Please see {@link java.beans.XMLEncoder}.
25  *
26  * @version 1.46 05/05/04
27  * @author David Kloba
28  * @author Hans Muller
29  * @see BoundedRangeModel
30  */

31 public class DefaultBoundedRangeModel implements BoundedRangeModel JavaDoc, Serializable JavaDoc
32 {
33     /**
34      * Only one <code>ChangeEvent</code> is needed per model instance since the
35      * event's only (read-only) state is the source property. The source
36      * of events generated here is always "this".
37      */

38     protected transient ChangeEvent changeEvent = null;
39
40     /** The listeners waiting for model changes. */
41     protected EventListenerList listenerList = new EventListenerList();
42
43     private int value = 0;
44     private int extent = 0;
45     private int min = 0;
46     private int max = 100;
47     private boolean isAdjusting = false;
48
49
50     /**
51      * Initializes all of the properties with default values.
52      * Those values are:
53      * <ul>
54      * <li><code>value</code> = 0
55      * <li><code>extent</code> = 0
56      * <li><code>minimum</code> = 0
57      * <li><code>maximum</code> = 100
58      * <li><code>adjusting</code> = false
59      * </ul>
60      */

61     public DefaultBoundedRangeModel() {
62     }
63
64
65     /**
66      * Initializes value, extent, minimum and maximum. Adjusting is false.
67      * Throws an <code>IllegalArgumentException</code> if the following
68      * constraints aren't satisfied:
69      * <pre>
70      * min <= value <= value+extent <= max
71      * </pre>
72      */

73     public DefaultBoundedRangeModel(int value, int extent, int min, int max)
74     {
75         if ((max >= min) &&
76         (value >= min) &&
77         ((value + extent) >= value) &&
78         ((value + extent) <= max)) {
79             this.value = value;
80             this.extent = extent;
81             this.min = min;
82             this.max = max;
83         }
84         else {
85             throw new IllegalArgumentException JavaDoc("invalid range properties");
86         }
87     }
88
89
90     /**
91      * Returns the model's current value.
92      * @return the model's current value
93      * @see #setValue
94      * @see BoundedRangeModel#getValue
95      */

96     public int getValue() {
97       return value;
98     }
99
100
101     /**
102      * Returns the model's extent.
103      * @return the model's extent
104      * @see #setExtent
105      * @see BoundedRangeModel#getExtent
106      */

107     public int getExtent() {
108       return extent;
109     }
110
111
112     /**
113      * Returns the model's minimum.
114      * @return the model's minimum
115      * @see #setMinimum
116      * @see BoundedRangeModel#getMinimum
117      */

118     public int getMinimum() {
119       return min;
120     }
121
122
123     /**
124      * Returns the model's maximum.
125      * @return the model's maximum
126      * @see #setMaximum
127      * @see BoundedRangeModel#getMaximum
128      */

129     public int getMaximum() {
130         return max;
131     }
132
133
134     /**
135      * Sets the current value of the model. For a slider, that
136      * determines where the knob appears. Ensures that the new
137      * value, <I>n</I> falls within the model's constraints:
138      * <pre>
139      * minimum <= value <= value+extent <= maximum
140      * </pre>
141      *
142      * @see BoundedRangeModel#setValue
143      */

144     public void setValue(int n) {
145         n = Math.min(n, Integer.MAX_VALUE - extent);
146
147         int newValue = Math.max(n, min);
148         if (newValue + extent > max) {
149             newValue = max - extent;
150         }
151         setRangeProperties(newValue, extent, min, max, isAdjusting);
152     }
153
154
155     /**
156      * Sets the extent to <I>n</I> after ensuring that <I>n</I>
157      * is greater than or equal to zero and falls within the model's
158      * constraints:
159      * <pre>
160      * minimum <= value <= value+extent <= maximum
161      * </pre>
162      * @see BoundedRangeModel#setExtent
163      */

164     public void setExtent(int n) {
165         int newExtent = Math.max(0, n);
166         if(value + newExtent > max) {
167             newExtent = max - value;
168         }
169         setRangeProperties(value, newExtent, min, max, isAdjusting);
170     }
171
172
173     /**
174      * Sets the minimum to <I>n</I> after ensuring that <I>n</I>
175      * that the other three properties obey the model's constraints:
176      * <pre>
177      * minimum <= value <= value+extent <= maximum
178      * </pre>
179      * @see #getMinimum
180      * @see BoundedRangeModel#setMinimum
181      */

182     public void setMinimum(int n) {
183         int newMax = Math.max(n, max);
184         int newValue = Math.max(n, value);
185         int newExtent = Math.min(newMax - newValue, extent);
186         setRangeProperties(newValue, newExtent, n, newMax, isAdjusting);
187     }
188
189
190     /**
191      * Sets the maximum 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 <= value <= value+extent <= maximum
195      * </pre>
196      * @see BoundedRangeModel#setMaximum
197      */

198     public void setMaximum(int n) {
199         int newMin = Math.min(n, min);
200         int newExtent = Math.min(n - newMin, extent);
201         int newValue = Math.min(n - newExtent, value);
202         setRangeProperties(newValue, newExtent, newMin, n, isAdjusting);
203     }
204
205
206     /**
207      * Sets the <code>valueIsAdjusting</code> property.
208      *
209      * @see #getValueIsAdjusting
210      * @see #setValue
211      * @see BoundedRangeModel#setValueIsAdjusting
212      */

213     public void setValueIsAdjusting(boolean b) {
214         setRangeProperties(value, extent, min, max, b);
215     }
216
217
218     /**
219      * Returns true if the value is in the process of changing
220      * as a result of actions being taken by the user.
221      *
222      * @return the value of the <code>valueIsAdjusting</code> property
223      * @see #setValue
224      * @see BoundedRangeModel#getValueIsAdjusting
225      */

226     public boolean getValueIsAdjusting() {
227         return isAdjusting;
228     }
229
230
231     /**
232      * Sets all of the <code>BoundedRangeModel</code> properties after forcing
233      * the arguments to obey the usual constraints:
234      * <pre>
235      * minimum <= value <= value+extent <= maximum
236      * </pre>
237      * <p>
238      * At most, one <code>ChangeEvent</code> is generated.
239      *
240      * @see BoundedRangeModel#setRangeProperties
241      * @see #setValue
242      * @see #setExtent
243      * @see #setMinimum
244      * @see #setMaximum
245      * @see #setValueIsAdjusting
246      */

247     public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting)
248     {
249         if (newMin > newMax) {
250             newMin = newMax;
251     }
252         if (newValue > newMax) {
253             newMax = newValue;
254     }
255         if (newValue < newMin) {
256             newMin = newValue;
257     }
258
259     /* Convert the addends to long so that extent can be
260      * Integer.MAX_VALUE without rolling over the sum.
261      * A JCK test covers this, see bug 4097718.
262      */

263         if (((long)newExtent + (long)newValue) > newMax) {
264             newExtent = newMax - newValue;
265     }
266     
267         if (newExtent < 0) {
268             newExtent = 0;
269     }
270
271         boolean isChange =
272             (newValue != value) ||
273             (newExtent != extent) ||
274             (newMin != min) ||
275             (newMax != max) ||
276             (adjusting != isAdjusting);
277
278         if (isChange) {
279             value = newValue;
280             extent = newExtent;
281             min = newMin;
282             max = newMax;
283             isAdjusting = adjusting;
284
285             fireStateChanged();
286         }
287     }
288
289
290     /**
291      * Adds a <code>ChangeListener</code>. The change listeners are run each
292      * time any one of the Bounded Range model properties changes.
293      *
294      * @param l the ChangeListener to add
295      * @see #removeChangeListener
296      * @see BoundedRangeModel#addChangeListener
297      */

298     public void addChangeListener(ChangeListener l) {
299         listenerList.add(ChangeListener.class, l);
300     }
301     
302
303     /**
304      * Removes a <code>ChangeListener</code>.
305      *
306      * @param l the <code>ChangeListener</code> to remove
307      * @see #addChangeListener
308      * @see BoundedRangeModel#removeChangeListener
309      */

310     public void removeChangeListener(ChangeListener l) {
311         listenerList.remove(ChangeListener.class, l);
312     }
313
314
315     /**
316      * Returns an array of all the change listeners
317      * registered on this <code>DefaultBoundedRangeModel</code>.
318      *
319      * @return all of this model's <code>ChangeListener</code>s
320      * or an empty
321      * array if no change listeners are currently registered
322      *
323      * @see #addChangeListener
324      * @see #removeChangeListener
325      *
326      * @since 1.4
327      */

328     public ChangeListener[] getChangeListeners() {
329         return (ChangeListener[])listenerList.getListeners(
330                 ChangeListener.class);
331     }
332
333
334     /**
335      * Runs each <code>ChangeListener</code>'s <code>stateChanged</code> method.
336      *
337      * @see #setRangeProperties
338      * @see EventListenerList
339      */

340     protected void fireStateChanged()
341     {
342         Object JavaDoc[] listeners = listenerList.getListenerList();
343         for (int i = listeners.length - 2; i >= 0; i -=2 ) {
344             if (listeners[i] == ChangeListener.class) {
345                 if (changeEvent == null) {
346                     changeEvent = new ChangeEvent(this);
347                 }
348                 ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
349             }
350         }
351     }
352
353     
354     /**
355      * Returns a string that displays all of the
356      * <code>BoundedRangeModel</code> properties.
357      */

358     public String JavaDoc toString() {
359         String JavaDoc modelString =
360             "value=" + getValue() + ", " +
361             "extent=" + getExtent() + ", " +
362             "min=" + getMinimum() + ", " +
363             "max=" + getMaximum() + ", " +
364             "adj=" + getValueIsAdjusting();
365
366         return getClass().getName() + "[" + modelString + "]";
367     }
368
369     /**
370      * Returns an array of all the objects currently registered as
371      * <code><em>Foo</em>Listener</code>s
372      * upon this model.
373      * <code><em>Foo</em>Listener</code>s
374      * are registered using the <code>add<em>Foo</em>Listener</code> method.
375      * <p>
376      * You can specify the <code>listenerType</code> argument
377      * with a class literal, such as <code><em>Foo</em>Listener.class</code>.
378      * For example, you can query a <code>DefaultBoundedRangeModel</code>
379      * instance <code>m</code>
380      * for its change listeners
381      * with the following code:
382      *
383      * <pre>ChangeListener[] cls = (ChangeListener[])(m.getListeners(ChangeListener.class));</pre>
384      *
385      * If no such listeners exist,
386      * this method returns an empty array.
387      *
388      * @param listenerType the type of listeners requested;
389      * this parameter should specify an interface
390      * that descends from <code>java.util.EventListener</code>
391      * @return an array of all objects registered as
392      * <code><em>Foo</em>Listener</code>s
393      * on this model,
394      * or an empty array if no such
395      * listeners have been added
396      * @exception ClassCastException if <code>listenerType</code> doesn't
397      * specify a class or interface that implements
398      * <code>java.util.EventListener</code>
399      *
400      * @see #getChangeListeners
401      *
402      * @since 1.3
403      */

404     public <T extends EventListener JavaDoc> T[] getListeners(Class JavaDoc<T> listenerType) {
405     return listenerList.getListeners(listenerType);
406     }
407 }
408
409
Popular Tags