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™ 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 * @since 1.2 48 */ 49 @SuppressWarnings("serial") // Same-version serialization only 50 public class DefaultBoundedRangeModel implements BoundedRangeModel, Serializable 51 { 52 /** 53 * Only one <code>ChangeEvent</code> is needed per model instance since the 54 * event's only (read-only) state is the source property. The source 55 * of events generated here is always "this". 56 */ 57 protected transient ChangeEvent changeEvent = null; 58 59 /** The listeners waiting for model changes. */ 60 protected EventListenerList listenerList = new EventListenerList(); 61 62 private int value = 0; 63 private int extent = 0; 64 private int min = 0; 65 private int max = 100; 66 private boolean isAdjusting = false; 67 68 69 /** 70 * Initializes all of the properties with default values. 71 * Those values are: 72 * <ul> 73 * <li><code>value</code> = 0 74 * <li><code>extent</code> = 0 75 * <li><code>minimum</code> = 0 76 * <li><code>maximum</code> = 100 77 * <li><code>adjusting</code> = false 78 * </ul> 79 */ 80 public DefaultBoundedRangeModel() { 81 } 82 83 84 /** 85 * Initializes value, extent, minimum and maximum. Adjusting is false. 86 * Throws an <code>IllegalArgumentException</code> if the following 87 * constraints aren't satisfied: 88 * <pre> 89 * min <= value <= value+extent <= max 90 * </pre> 91 * 92 * @param value an int giving the current value 93 * @param extent the length of the inner range that begins at the model's value 94 * @param min an int giving the minimum value 95 * @param max an int giving the maximum value 96 */ 97 public DefaultBoundedRangeModel(int value, int extent, int min, int max) 98 { 99 if ((max >= min) && 100 (value >= min) && 101 ((value + extent) >= value) && 102 ((value + extent) <= max)) { 103 this.value = value; 104 this.extent = extent; 105 this.min = min; 106 this.max = max; 211 } 212 213 214 /** 215 * Sets the maximum to <I>n</I> after ensuring that <I>n</I> 216 * that the other three properties obey the model's constraints: 217 * <pre> 218 * minimum <= value <= value+extent <= maximum 219 * </pre> 220 * @see BoundedRangeModel#setMaximum 221 */ 222 public void setMaximum(int n) { 223 int newMin = Math.min(n, min); 224 int newExtent = Math.min(n - newMin, extent); 225 int newValue = Math.min(n - newExtent, value); 226 setRangeProperties(newValue, newExtent, newMin, n, isAdjusting); 227 } 228 229 230 /** 231 * Sets the <code>valueIsAdjusting</code> property. 232 * 233 * @see #getValueIsAdjusting 234 * @see #setValue 235 * @see BoundedRangeModel#setValueIsAdjusting 236 */ 237 public void setValueIsAdjusting(boolean b) { 238 setRangeProperties(value, extent, min, max, b); 239 } 240 241 242 /** 243 * Returns true if the value is in the process of changing 244 * as a result of actions being taken by the user. 245 * 246 * @return the value of the <code>valueIsAdjusting</code> property 247 * @see #setValue 248 * @see BoundedRangeModel#getValueIsAdjusting 249 */ 250 public boolean getValueIsAdjusting() { 251 return isAdjusting; 252 } 253 254 255 /** 256 * Sets all of the <code>BoundedRangeModel</code> properties after forcing 257 * the arguments to obey the usual constraints: 258 * <pre> 259 * minimum <= value <= value+extent <= maximum 260 * </pre> 261 * <p> 262 * At most, one <code>ChangeEvent</code> is generated. 263 * 264 * @see BoundedRangeModel#setRangeProperties 265 * @see #setValue 266 * @see #setExtent 267 * @see #setMinimum 268 * @see #setMaximum 269 * @see #setValueIsAdjusting 270 */ 271 public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting) 272 { 273 if (newMin > newMax) { 274 newMin = newMax; 275 } 276 if (newValue > newMax) { 277 newMax = newValue; 278 } 279 if (newValue < newMin) { 280 newMin = newValue; 281 } 282 295 boolean isChange = 296 (newValue != value) || 297 (newExtent != extent) || 298 (newMin != min) || 299 (newMax != max) || 300 (adjusting != isAdjusting); 301 302 if (isChange) { 303 value = newValue; 304 extent = newExtent; 305 min = newMin; 306 max = newMax; 307 isAdjusting = adjusting; 308 309 fireStateChanged(); 310 } 311 } 312 313 314 /** 315 * Adds a <code>ChangeListener</code>. The change listeners are run each 316 * time any one of the Bounded Range model properties changes. 317 * 318 * @param l the ChangeListener to add 319 * @see #removeChangeListener 320 * @see BoundedRangeModel#addChangeListener 321 */ 322 public void addChangeListener(ChangeListener l) { 323 listenerList.add(ChangeListener.class, l); 324 } 325 326 327 /** 328 * Removes a <code>ChangeListener</code>. 329 * 330 * @param l the <code>ChangeListener</code> to remove 331 * @see #addChangeListener 332 * @see BoundedRangeModel#removeChangeListener 333 */ 334 public void removeChangeListener(ChangeListener l) { 335 listenerList.remove(ChangeListener.class, l); 336 } 337 338 339 /** 340 * Returns an array of all the change listeners 341 * registered on this <code>DefaultBoundedRangeModel</code>. 342 * 343 * @return all of this model's <code>ChangeListener</code>s 344 * or an empty 345 * array if no change listeners are currently registered 346 * 347 * @see #addChangeListener 348 * @see #removeChangeListener 349 * 350 * @since 1.4 351 */ 352 public ChangeListener[] getChangeListeners() { 353 return listenerList.getListeners(ChangeListener.class); 354 } 355 356 357 /** 358 * Runs each <code>ChangeListener</code>'s <code>stateChanged</code> method. 359 * 360 * @see #setRangeProperties 361 * @see EventListenerList 362 */ 363 protected void fireStateChanged() 364 { 365 Object[] listeners = listenerList.getListenerList(); 366 for (int i = listeners.length - 2; i >= 0; i -=2 ) { 367 if (listeners[i] == ChangeListener.class) { 368 if (changeEvent == null) { 369 changeEvent = new ChangeEvent(this); 370 } 371 ((ChangeListener)listeners[i+1]).stateChanged(changeEvent); 372 } 373 } 374 } 375 376 377 /** 378 * Returns a string that displays all of the 379 * <code>BoundedRangeModel</code> properties. 380 */ 381 public String toString() { 382 String modelString = 383 "value=" + getValue() + ", " + 384 "extent=" + getExtent() + ", " + 385 "min=" + getMinimum() + ", " + 386 "max=" + getMaximum() + ", " + 387 "adj=" + getValueIsAdjusting(); 388 389 return getClass().getName() + "[" + modelString + "]"; 390 } 391 392 /** 393 * Returns an array of all the objects currently registered as 394 * <code><em>Foo</em>Listener</code>s 395 * upon this model. 396 * <code><em>Foo</em>Listener</code>s 397 * are registered using the <code>add<em>Foo</em>Listener</code> method. 398 * <p> 399 * You can specify the <code>listenerType</code> argument 400 * with a class literal, such as <code><em>Foo</em>Listener.class</code>. 401 * For example, you can query a <code>DefaultBoundedRangeModel</code> 402 * instance <code>m</code> 403 * for its change listeners 404 * with the following code: 405 * 406 * <pre>ChangeListener[] cls = (ChangeListener[])(m.getListeners(ChangeListener.class));</pre> 407 * 408 * If no such listeners exist, 409 * this method returns an empty array. 410 * 411 * @param <T> the type of {@code EventListener} class being requested 412 * @param listenerType the type of listeners requested; 413 * this parameter should specify an interface 414 * that descends from <code>java.util.EventListener</code> 415 * @return an array of all objects registered as 416 * <code><em>Foo</em>Listener</code>s 417 * on this model, 418 * or an empty array if no such 419 * listeners have been added 420 * @exception ClassCastException if <code>listenerType</code> doesn't 421 * specify a class or interface that implements 422 * <code>java.util.EventListener</code> 423 * 424 * @see #getChangeListeners 425 * 426 * @since 1.3 427 */ 428 public <T extends EventListener> T[] getListeners(Class<T> listenerType) { 429 return listenerList.getListeners(listenerType); 430 } 431 } | 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™ 41 * has been added to the {@code java.beans} package. 42 * Please see {@link java.beans.XMLEncoder}. 43 * 44 * @author David Kloba 45 * @author Hans Muller 46 * @see BoundedRangeModel 47 * @since 1.2 48 */ 49 @SuppressWarnings("serial") // Same-version serialization only 50 public class DefaultBoundedRangeModel implements BoundedRangeModel, Serializable 51 { 52 /** 53 * Only one {@code ChangeEvent} is needed per model instance since the 54 * event's only (read-only) state is the source property. The source 55 * of events generated here is always "this". 56 */ 57 protected transient ChangeEvent changeEvent = null; 58 59 /** The listeners waiting for model changes. */ 60 protected EventListenerList listenerList = new EventListenerList(); 61 62 private int value = 0; 63 private int extent = 0; 64 private int min = 0; 65 private int max = 100; 66 private boolean isAdjusting = false; 67 68 69 /** 70 * Initializes all of the properties with default values. 71 * Those values are: 72 * <ul> 73 * <li>{@code value} = 0 74 * <li>{@code extent} = 0 75 * <li>{@code minimum} = 0 76 * <li>{@code maximum} = 100 77 * <li>{@code adjusting} = false 78 * </ul> 79 */ 80 public DefaultBoundedRangeModel() { 81 } 82 83 84 /** 85 * Initializes value, extent, minimum and maximum. Adjusting is false. 86 * Throws an {@code IllegalArgumentException} if the following 87 * constraints aren't satisfied: 88 * <pre> 89 * min <= value <= value+extent <= max 90 * </pre> 91 * 92 * @param value an int giving the current value 93 * @param extent the length of the inner range that begins at the model's value 94 * @param min an int giving the minimum value 95 * @param max an int giving the maximum value 96 */ 97 public DefaultBoundedRangeModel(int value, int extent, int min, int max) 98 { 99 if ((max >= min) && 100 (value >= min) && 101 ((value + extent) >= value) && 102 ((value + extent) <= max)) { 103 this.value = value; 104 this.extent = extent; 105 this.min = min; 106 this.max = max; 211 } 212 213 214 /** 215 * Sets the maximum to <I>n</I> after ensuring that <I>n</I> 216 * that the other three properties obey the model's constraints: 217 * <pre> 218 * minimum <= value <= value+extent <= maximum 219 * </pre> 220 * @see BoundedRangeModel#setMaximum 221 */ 222 public void setMaximum(int n) { 223 int newMin = Math.min(n, min); 224 int newExtent = Math.min(n - newMin, extent); 225 int newValue = Math.min(n - newExtent, value); 226 setRangeProperties(newValue, newExtent, newMin, n, isAdjusting); 227 } 228 229 230 /** 231 * Sets the {@code valueIsAdjusting} property. 232 * 233 * @see #getValueIsAdjusting 234 * @see #setValue 235 * @see BoundedRangeModel#setValueIsAdjusting 236 */ 237 public void setValueIsAdjusting(boolean b) { 238 setRangeProperties(value, extent, min, max, b); 239 } 240 241 242 /** 243 * Returns true if the value is in the process of changing 244 * as a result of actions being taken by the user. 245 * 246 * @return the value of the {@code valueIsAdjusting} property 247 * @see #setValue 248 * @see BoundedRangeModel#getValueIsAdjusting 249 */ 250 public boolean getValueIsAdjusting() { 251 return isAdjusting; 252 } 253 254 255 /** 256 * Sets all of the {@code BoundedRangeModel} properties after forcing 257 * the arguments to obey the usual constraints: 258 * <pre> 259 * minimum <= value <= value+extent <= maximum 260 * </pre> 261 * <p> 262 * At most, one {@code ChangeEvent} is generated. 263 * 264 * @see BoundedRangeModel#setRangeProperties 265 * @see #setValue 266 * @see #setExtent 267 * @see #setMinimum 268 * @see #setMaximum 269 * @see #setValueIsAdjusting 270 */ 271 public void setRangeProperties(int newValue, int newExtent, int newMin, int newMax, boolean adjusting) 272 { 273 if (newMin > newMax) { 274 newMin = newMax; 275 } 276 if (newValue > newMax) { 277 newMax = newValue; 278 } 279 if (newValue < newMin) { 280 newMin = newValue; 281 } 282 295 boolean isChange = 296 (newValue != value) || 297 (newExtent != extent) || 298 (newMin != min) || 299 (newMax != max) || 300 (adjusting != isAdjusting); 301 302 if (isChange) { 303 value = newValue; 304 extent = newExtent; 305 min = newMin; 306 max = newMax; 307 isAdjusting = adjusting; 308 309 fireStateChanged(); 310 } 311 } 312 313 314 /** 315 * Adds a {@code ChangeListener}. The change listeners are run each 316 * time any one of the Bounded Range model properties changes. 317 * 318 * @param l the ChangeListener to add 319 * @see #removeChangeListener 320 * @see BoundedRangeModel#addChangeListener 321 */ 322 public void addChangeListener(ChangeListener l) { 323 listenerList.add(ChangeListener.class, l); 324 } 325 326 327 /** 328 * Removes a {@code ChangeListener}. 329 * 330 * @param l the {@code ChangeListener} to remove 331 * @see #addChangeListener 332 * @see BoundedRangeModel#removeChangeListener 333 */ 334 public void removeChangeListener(ChangeListener l) { 335 listenerList.remove(ChangeListener.class, l); 336 } 337 338 339 /** 340 * Returns an array of all the change listeners 341 * registered on this {@code DefaultBoundedRangeModel}. 342 * 343 * @return all of this model's {@code ChangeListener}s 344 * or an empty 345 * array if no change listeners are currently registered 346 * 347 * @see #addChangeListener 348 * @see #removeChangeListener 349 * 350 * @since 1.4 351 */ 352 public ChangeListener[] getChangeListeners() { 353 return listenerList.getListeners(ChangeListener.class); 354 } 355 356 357 /** 358 * Runs each {@code ChangeListener}'s {@code stateChanged} method. 359 * 360 * @see #setRangeProperties 361 * @see EventListenerList 362 */ 363 protected void fireStateChanged() 364 { 365 Object[] listeners = listenerList.getListenerList(); 366 for (int i = listeners.length - 2; i >= 0; i -=2 ) { 367 if (listeners[i] == ChangeListener.class) { 368 if (changeEvent == null) { 369 changeEvent = new ChangeEvent(this); 370 } 371 ((ChangeListener)listeners[i+1]).stateChanged(changeEvent); 372 } 373 } 374 } 375 376 377 /** 378 * Returns a string that displays all of the 379 * {@code BoundedRangeModel} properties. 380 */ 381 public String toString() { 382 String modelString = 383 "value=" + getValue() + ", " + 384 "extent=" + getExtent() + ", " + 385 "min=" + getMinimum() + ", " + 386 "max=" + getMaximum() + ", " + 387 "adj=" + getValueIsAdjusting(); 388 389 return getClass().getName() + "[" + modelString + "]"; 390 } 391 392 /** 393 * Returns an array of all the objects currently registered as 394 * <code><em>Foo</em>Listener</code>s 395 * upon this model. 396 * <code><em>Foo</em>Listener</code>s 397 * are registered using the <code>add<em>Foo</em>Listener</code> method. 398 * <p> 399 * You can specify the {@code listenerType} argument 400 * with a class literal, such as <code><em>Foo</em>Listener.class</code>. 401 * For example, you can query a {@code DefaultBoundedRangeModel} 402 * instance {@code m} 403 * for its change listeners 404 * with the following code: 405 * 406 * <pre>ChangeListener[] cls = (ChangeListener[])(m.getListeners(ChangeListener.class));</pre> 407 * 408 * If no such listeners exist, 409 * this method returns an empty array. 410 * 411 * @param <T> the type of {@code EventListener} class being requested 412 * @param listenerType the type of listeners requested; 413 * this parameter should specify an interface 414 * that descends from {@code java.util.EventListener} 415 * @return an array of all objects registered as 416 * <code><em>Foo</em>Listener</code>s 417 * on this model, 418 * or an empty array if no such 419 * listeners have been added 420 * @exception ClassCastException if {@code listenerType} doesn't 421 * specify a class or interface that implements 422 * {@code java.util.EventListener} 423 * 424 * @see #getChangeListeners 425 * 426 * @since 1.3 427 */ 428 public <T extends EventListener> T[] getListeners(Class<T> listenerType) { 429 return listenerList.getListeners(listenerType); 430 } 431 } |