GNU Classpath (0.20) | |
Frames | No Frames |
1: /* DefaultBoundedRangeModel.java -- Default implementation 2: of BoundedRangeModel. 3: Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: 40: package javax.swing; 41: 42: import java.io.Serializable; 43: import java.util.EventListener; 44: 45: import javax.swing.event.ChangeEvent; 46: import javax.swing.event.ChangeListener; 47: import javax.swing.event.EventListenerList; 48: 49: /** 50: * The default implementation of <code>BoundedRangeModel</code>. 51: * 52: * @author Andrew Selkirk (aselkirk@sympatico.ca) 53: * @author Sascha Brawer (brawer@dandelis.ch) 54: */ 55: public class DefaultBoundedRangeModel 56: implements BoundedRangeModel, Serializable 57: { 58: /** 59: * The identifier of this class in object serialization. Verified 60: * using the serialver tool of Sun J2SE 1.4.1_01. 61: */ 62: private static final long serialVersionUID = 5034068491295259790L; 63: 64: /** 65: * An event that is sent to all registered {@link ChangeListener}s 66: * when the state of this range model has changed. 67: * 68: * <p>The event object is created on demand, the first time it 69: * is actually needed.</p> 70: * 71: * @see #fireStateChanged() 72: */ 73: protected transient ChangeEvent changeEvent; 74: 75: /** 76: * The list of the currently registered EventListeners. 77: */ 78: protected EventListenerList listenerList = new EventListenerList(); 79: 80: /** 81: * The current value of the range model, which is always between 82: * {@link #minimum} and ({@link #maximum} - {@link #extent}). In a 83: * scroll bar visualization of a {@link BoundedRangeModel}, the 84: * <code>value</code> is displayed as the position of the thumb. 85: */ 86: private int value; 87: 88: /** 89: * The current extent of the range model, which is a number greater 90: * than or equal to zero. In a scroll bar visualization of a {@link 91: * BoundedRangeModel}, the <code>extent</code> is displayed as the 92: * size of the thumb. 93: */ 94: private int extent; 95: 96: /** 97: * The current minimum value of the range model, which is always 98: * less than or equal to {@link #maximum}. 99: */ 100: private int minimum; 101: 102: /** 103: * The current maximum value of the range model, which is always 104: * greater than or equal to {@link #minimum}. 105: */ 106: private int maximum; 107: 108: /** 109: * A property that indicates whether the value of this {@link 110: * BoundedRangeModel} is going to change in the immediate future. 111: */ 112: private boolean isAdjusting; 113: 114: /** 115: * Constructs a <code>DefaultBoundedRangeModel</code> with default 116: * values for the properties. The properties <code>value</code>, 117: * <code>extent</code> and <code>minimum</code> will be initialized 118: * to zero; <code>maximum</code> will be set to 100; the property 119: * <code>valueIsAdjusting</code> will be <code>false</code>. 120: */ 121: public DefaultBoundedRangeModel() 122: { 123: // The fields value, extent, minimum have the default value 0, and 124: // isAdjusting is already false. These fields no not need to be 125: // set explicitly. 126: maximum = 100; 127: } 128: 129: /** 130: * Constructs a <code>DefaultBoundedRangeModel</code> with the 131: * specified values for some properties. 132: * 133: * @param value the initial value of the range model, which must be 134: * a number between <code>minimum</code> and <code>(maximum - 135: * extent)</code>. In a scroll bar visualization of a {@link 136: * BoundedRangeModel}, the <code>value</code> is displayed as the 137: * position of the thumb. 138: * @param extent the initial extent of the range model, which is a 139: * number greater than or equal to zero. In a scroll bar 140: * visualization of a {@link BoundedRangeModel}, the 141: * <code>extent</code> is displayed as the size of the thumb. 142: * @param minimum the initial minimal value of the range model. 143: * @param maximum the initial maximal value of the range model. 144: * 145: * @throws IllegalArgumentException if the following condition is 146: * not satisfied: <code>minimum <= value <= value + extent <= 147: * maximum</code>. 148: */ 149: public DefaultBoundedRangeModel(int value, int extent, int minimum, 150: int maximum) 151: { 152: if (!(minimum <= value && extent >= 0 && (value + extent) <= maximum)) 153: throw new IllegalArgumentException(); 154: 155: this.value = value; 156: this.extent = extent; 157: this.minimum = minimum; 158: this.maximum = maximum; 159: 160: // The isAdjusting field already has a false value by default. 161: } 162: 163: /** 164: * Returns a string with all relevant properties of this range 165: * model. 166: * 167: * @return a string representing the object 168: */ 169: public String toString() 170: { 171: return getClass().getName() 172: + "[value=" + value 173: + ", extent=" + extent 174: + ", min=" + minimum 175: + ", max=" + maximum 176: + ", adj=" + isAdjusting 177: + ']'; 178: } 179: 180: /** 181: * Returns the current value of this bounded range model. In a 182: * scroll bar visualization of a {@link BoundedRangeModel}, the 183: * <code>value</code> is displayed as the position of the thumb. 184: * 185: * @return the value 186: */ 187: public int getValue() 188: { 189: return value; 190: } 191: 192: /** 193: * Changes the current value of this bounded range model. In a 194: * scroll bar visualization of a {@link BoundedRangeModel}, the 195: * <code>value</code> is displayed as the position of the thumb; 196: * changing the <code>value</code> of a scroll bar's model 197: * thus moves the thumb to a different position. 198: * 199: * @param value the value 200: */ 201: public void setValue(int value) 202: { 203: value = Math.max(minimum, value); 204: if (value + extent > maximum) 205: value = maximum - extent; 206: 207: if (value != this.value) 208: { 209: this.value = value; 210: fireStateChanged(); 211: } 212: } 213: 214: /** 215: * Returns the current extent of this bounded range model, which is 216: * a number greater than or equal to zero. In a scroll bar 217: * visualization of a {@link BoundedRangeModel}, the 218: * <code>extent</code> is displayed as the size of the thumb. 219: * 220: * @return the extent 221: */ 222: public int getExtent() 223: { 224: return extent; 225: } 226: 227: /** 228: * Changes the current extent of this bounded range model. In a 229: * scroll bar visualization of a {@link BoundedRangeModel}, the 230: * <code>extent</code> is displayed as the size of the thumb. 231: * 232: * @param extent the new extent of the range model, which is a 233: * number greater than or equal to zero. 234: */ 235: public void setExtent(int extent) 236: { 237: extent = Math.max(extent, 0); 238: if (value + extent > maximum) 239: extent = maximum - value; 240: 241: if (extent != this.extent) 242: { 243: this.extent = extent; 244: fireStateChanged(); 245: } 246: } 247: 248: /** 249: * Returns the current minimal value of this bounded range model. 250: */ 251: public int getMinimum() 252: { 253: return minimum; 254: } 255: 256: /** 257: * Changes the current minimal value of this bounded range model. 258: * 259: * @param minimum the new minimal value. 260: */ 261: public void setMinimum(int minimum) 262: { 263: int value, maximum; 264: 265: maximum = Math.max(minimum, this.maximum); 266: value = Math.max(minimum, this.value); 267: 268: setRangeProperties(value, extent, minimum, maximum, isAdjusting); 269: } 270: 271: /** 272: * Returns the current maximal value of this bounded range model. 273: * 274: * @return the maximum 275: */ 276: public int getMaximum() 277: { 278: return maximum; 279: } 280: 281: /** 282: * Changes the current maximal value of this bounded range model. 283: * 284: * @param maximum the new maximal value. 285: */ 286: public void setMaximum(int maximum) 287: { 288: int value, extent, minimum; 289: 290: minimum = Math.min(this.minimum, maximum); 291: extent = Math.min(this.extent, maximum - minimum); 292: value = Math.min(this.value, maximum - extent); 293: 294: setRangeProperties(value, extent, minimum, maximum, isAdjusting); 295: } 296: 297: /** 298: * Returns whether or not the value of this bounded range model is 299: * going to change in the immediate future. Scroll bars set this 300: * property to <code>true</code> while the thumb is being dragged 301: * around; when the mouse is relased, they set the property to 302: * <code>false</code> and post a final {@link ChangeEvent}. 303: * 304: * @return <code>true</code> if the value will change soon again; 305: * <code>false</code> if the value will probably not change soon. 306: */ 307: public boolean getValueIsAdjusting() 308: { 309: return isAdjusting; 310: } 311: 312: /** 313: * Specifies whether or not the value of this bounded range model is 314: * going to change in the immediate future. Scroll bars set this 315: * property to <code>true</code> while the thumb is being dragged 316: * around; when the mouse is relased, they set the property to 317: * <code>false</code>. 318: * 319: * @param isAdjusting <code>true</code> if the value will change 320: * soon again; <code>false</code> if the value will probably not 321: * change soon. 322: */ 323: public void setValueIsAdjusting(boolean isAdjusting) 324: { 325: if (isAdjusting == this.isAdjusting) 326: return; 327: 328: this.isAdjusting = isAdjusting; 329: fireStateChanged(); 330: } 331: 332: /** 333: * Sets all properties. 334: * 335: * @param value the new value of the range model. In a scroll bar 336: * visualization of a {@link BoundedRangeModel}, the 337: * <code>value</code> is displayed as the position of the thumb. 338: * @param extent the new extent of the range model, which is a 339: * number greater than or equal to zero. In a scroll bar 340: * visualization of a {@link BoundedRangeModel}, the 341: * <code>extent</code> is displayed as the size of the thumb. 342: * @param minimum the new minimal value of the range model. 343: * @param maximum the new maximal value of the range model. 344: * @param isAdjusting whether or not the value of this bounded range 345: * model is going to change in the immediate future. Scroll bars set 346: * this property to <code>true</code> while the thumb is being 347: * dragged around; when the mouse is relased, they set the property 348: * to <code>false</code>. 349: */ 350: public void setRangeProperties(int value, int extent, int minimum, 351: int maximum, boolean isAdjusting) 352: { 353: minimum = Math.min(Math.min(minimum, maximum), value); 354: maximum = Math.max(value, maximum); 355: if (extent + value > maximum) 356: extent = maximum - value; 357: extent = Math.max(0, extent); 358: 359: if ((value == this.value) 360: && (extent == this.extent) 361: && (minimum == this.minimum) 362: && (maximum == this.maximum) 363: && (isAdjusting == this.isAdjusting)) 364: return; 365: 366: this.value = value; 367: this.extent = extent; 368: this.minimum = minimum; 369: this.maximum = maximum; 370: this.isAdjusting = isAdjusting; 371: 372: fireStateChanged(); 373: } 374: 375: /** 376: * Subscribes a ChangeListener to state changes. 377: * 378: * @param listener the listener to be subscribed. 379: */ 380: public void addChangeListener(ChangeListener listener) 381: { 382: listenerList.add(ChangeListener.class, listener); 383: } 384: 385: /** 386: * Cancels the subscription of a ChangeListener. 387: * 388: * @param listener the listener to be unsubscribed. 389: */ 390: public void removeChangeListener(ChangeListener listener) 391: { 392: listenerList.remove(ChangeListener.class, listener); 393: } 394: 395: /** 396: * Sends a {@link ChangeEvent} to any registered {@link 397: * ChangeListener}s. 398: * 399: * @see #addChangeListener(ChangeListener) 400: * @see #removeChangeListener(ChangeListener) 401: */ 402: protected void fireStateChanged() 403: { 404: ChangeListener[] listeners = getChangeListeners(); 405: 406: if (changeEvent == null) 407: changeEvent = new ChangeEvent(this); 408: 409: for (int i = listeners.length - 1; i >= 0; --i) 410: listeners[i].stateChanged(changeEvent); 411: } 412: 413: /** 414: * Retrieves the current listeners of the specified class. 415: * 416: * @param listenerType the class of listeners; usually {@link 417: * ChangeListener}<code>.class</code>. 418: * 419: * @return an array with the currently subscribed listeners, or 420: * an empty array if there are currently no listeners. 421: * 422: * @since 1.3 423: */ 424: public EventListener[] getListeners(Class listenerType) 425: { 426: return listenerList.getListeners(listenerType); 427: } 428: 429: /** 430: * Returns all <code>ChangeListeners</code> that are currently 431: * subscribed for changes to this 432: * <code>DefaultBoundedRangeModel</code>. 433: * 434: * @return an array with the currently subscribed listeners, or 435: * an empty array if there are currently no listeners. 436: * 437: * @since 1.4 438: */ 439: public ChangeListener[] getChangeListeners() 440: { 441: return (ChangeListener[]) getListeners(ChangeListener.class); 442: } 443: }
GNU Classpath (0.20) |