Frames | No Frames |
1: /* JScrollBar.java -- 2: Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing; 40: 41: import java.awt.Adjustable; 42: import java.awt.Dimension; 43: import java.awt.event.AdjustmentEvent; 44: import java.awt.event.AdjustmentListener; 45: import java.beans.PropertyChangeEvent; 46: 47: import javax.accessibility.Accessible; 48: import javax.accessibility.AccessibleContext; 49: import javax.accessibility.AccessibleRole; 50: import javax.accessibility.AccessibleState; 51: import javax.accessibility.AccessibleStateSet; 52: import javax.accessibility.AccessibleValue; 53: import javax.swing.plaf.ScrollBarUI; 54: 55: /** 56: * The JScrollBar. Two buttons control how the values that the 57: * scroll bar can take. You can also drag the thumb or click the track 58: * to move the scroll bar. Typically, the JScrollBar is used with 59: * other components to translate the value of the bar to the viewable 60: * contents of the other components. 61: */ 62: public class JScrollBar extends JComponent implements Adjustable, Accessible 63: { 64: /** 65: * Provides the accessibility features for the <code>JScrollBar</code> 66: * component. 67: */ 68: protected class AccessibleJScrollBar extends JComponent.AccessibleJComponent 69: implements AccessibleValue 70: { 71: private static final long serialVersionUID = -7758162392045586663L; 72: 73: /** 74: * Creates a new <code>AccessibleJScrollBar</code> instance. 75: */ 76: protected AccessibleJScrollBar() 77: { 78: super(); 79: } 80: 81: /** 82: * Returns a set containing the current state of the {@link JScrollBar} 83: * component. 84: * 85: * @return The accessible state set. 86: */ 87: public AccessibleStateSet getAccessibleStateSet() 88: { 89: AccessibleStateSet result = super.getAccessibleStateSet(); 90: if (orientation == JScrollBar.HORIZONTAL) 91: result.add(AccessibleState.HORIZONTAL); 92: else if (orientation == JScrollBar.VERTICAL) 93: result.add(AccessibleState.VERTICAL); 94: return result; 95: } 96: 97: /** 98: * Returns the accessible role for the <code>JScrollBar</code> component. 99: * 100: * @return {@link AccessibleRole#SCROLL_BAR}. 101: */ 102: public AccessibleRole getAccessibleRole() 103: { 104: return AccessibleRole.SCROLL_BAR; 105: } 106: 107: /** 108: * Returns an object that provides access to the current, minimum and 109: * maximum values. 110: * 111: * @return The accessible value. 112: */ 113: public AccessibleValue getAccessibleValue() 114: { 115: return this; 116: } 117: 118: /** 119: * Returns the current value of the {@link JScrollBar} component, as an 120: * {@link Integer}. 121: * 122: * @return The current value of the {@link JScrollBar} component. 123: */ 124: public Number getCurrentAccessibleValue() 125: { 126: return new Integer(getValue()); 127: } 128: 129: /** 130: * Sets the current value of the {@link JScrollBar} component and sends a 131: * {@link PropertyChangeEvent} (with the property name 132: * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered 133: * listeners. If the supplied value is <code>null</code>, this method 134: * does nothing and returns <code>false</code>. 135: * 136: * @param value the new slider value (<code>null</code> permitted). 137: * 138: * @return <code>true</code> if the slider value is updated, and 139: * <code>false</code> otherwise. 140: */ 141: public boolean setCurrentAccessibleValue(Number value) 142: { 143: if (value == null) 144: return false; 145: Number oldValue = getCurrentAccessibleValue(); 146: setValue(value.intValue()); 147: firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue, 148: new Integer(getValue())); 149: return true; 150: } 151: 152: /** 153: * Returns the minimum value of the {@link JScrollBar} component, as an 154: * {@link Integer}. 155: * 156: * @return The minimum value of the {@link JScrollBar} component. 157: */ 158: public Number getMinimumAccessibleValue() 159: { 160: return new Integer(getMinimum()); 161: } 162: 163: /** 164: * Returns the maximum value of the {@link JScrollBar} component, as an 165: * {@link Integer}. 166: * 167: * @return The maximum value of the {@link JScrollBar} component. 168: */ 169: public Number getMaximumAccessibleValue() 170: { 171: return new Integer(getMaximum() - model.getExtent()); 172: } 173: } 174: 175: private static final long serialVersionUID = -8195169869225066566L; 176: 177: /** How much the thumb moves when moving in a block. */ 178: protected int blockIncrement = 10; 179: 180: /** The model that holds the scroll bar's data. */ 181: protected BoundedRangeModel model; 182: 183: /** The orientation of the scroll bar. */ 184: protected int orientation = SwingConstants.VERTICAL; 185: 186: /** How much the thumb moves when moving in a unit. */ 187: protected int unitIncrement = 1; 188: 189: /** 190: * Creates a new horizontal JScrollBar object with a minimum 191: * of 0, a maxmium of 100, a value of 0 and an extent of 10. 192: */ 193: public JScrollBar() 194: { 195: this(SwingConstants.VERTICAL, 0, 10, 0, 100); 196: } 197: 198: /** 199: * Creates a new JScrollBar object with a minimum of 0, a 200: * maximum of 100, a value of 0, an extent of 10 and the given 201: * orientation. 202: * 203: * @param orientation The orientation of the JScrollBar. 204: */ 205: public JScrollBar(int orientation) 206: { 207: this(orientation, 0, 10, 0, 100); 208: } 209: 210: /** 211: * Creates a new JScrollBar object with the given orientation, 212: * value, min, max, and extent. 213: * 214: * @param orientation The orientation to use. 215: * @param value The value to use. 216: * @param extent The extent to use. 217: * @param min The minimum value of the scrollbar. 218: * @param max The maximum value of the scrollbar. 219: */ 220: public JScrollBar(int orientation, int value, int extent, int min, int max) 221: { 222: model = new DefaultBoundedRangeModel(value, extent, min, max); 223: if (orientation != SwingConstants.HORIZONTAL 224: && orientation != SwingConstants.VERTICAL) 225: throw new IllegalArgumentException(orientation 226: + " is not a legal orientation"); 227: this.orientation = orientation; 228: updateUI(); 229: } 230: 231: /** 232: * This method sets the UI of this scrollbar to 233: * the given UI. 234: * 235: * @param ui The UI to use with this scrollbar. 236: */ 237: public void setUI(ScrollBarUI ui) 238: { 239: super.setUI(ui); 240: } 241: 242: /** 243: * This method returns the UI that is being used 244: * with this scrollbar. 245: * 246: * @return The scrollbar's current UI. 247: */ 248: public ScrollBarUI getUI() 249: { 250: return (ScrollBarUI) ui; 251: } 252: 253: /** 254: * This method changes the UI to be the 255: * default for the current look and feel. 256: */ 257: public void updateUI() 258: { 259: setUI((ScrollBarUI) UIManager.getUI(this)); 260: } 261: 262: /** 263: * This method returns an identifier to 264: * choose the correct UI delegate for the 265: * scrollbar. 266: * 267: * @return The identifer to choose the UI delegate; "ScrollBarUI" 268: */ 269: public String getUIClassID() 270: { 271: return "ScrollBarUI"; 272: } 273: 274: /** 275: * This method returns the orientation of the scrollbar. 276: * 277: * @return The orientation of the scrollbar. 278: */ 279: public int getOrientation() 280: { 281: return orientation; 282: } 283: 284: /** 285: * This method sets the orientation of the scrollbar. 286: * 287: * @param orientation The orientation of the scrollbar. 288: */ 289: public void setOrientation(int orientation) 290: { 291: if (orientation != SwingConstants.HORIZONTAL 292: && orientation != SwingConstants.VERTICAL) 293: throw new IllegalArgumentException("orientation must be one of HORIZONTAL or VERTICAL"); 294: if (orientation != this.orientation) 295: { 296: int oldOrientation = this.orientation; 297: this.orientation = orientation; 298: firePropertyChange("orientation", oldOrientation, 299: this.orientation); 300: } 301: } 302: 303: /** 304: * This method returns the model being used with 305: * the scrollbar. 306: * 307: * @return The scrollbar's model. 308: */ 309: public BoundedRangeModel getModel() 310: { 311: return model; 312: } 313: 314: /** 315: * This method sets the model to use with 316: * the scrollbar. 317: * 318: * @param newModel The new model to use with the scrollbar. 319: */ 320: public void setModel(BoundedRangeModel newModel) 321: { 322: if (model != newModel) 323: { 324: BoundedRangeModel oldModel = model; 325: model = newModel; 326: firePropertyChange("model", oldModel, model); 327: } 328: } 329: 330: /** 331: * This method returns how much the scrollbar's value 332: * should change for a unit increment depending on the 333: * given direction. 334: * 335: * @param direction The direction to scroll in. 336: * 337: * @return The amount the scrollbar's value will change given the direction. 338: */ 339: public int getUnitIncrement(int direction) 340: { 341: return direction * unitIncrement; 342: } 343: 344: /** 345: * This method sets the unitIncrement property. 346: * 347: * @param unitIncrement The new unitIncrement. 348: */ 349: public void setUnitIncrement(int unitIncrement) 350: { 351: if (unitIncrement != this.unitIncrement) 352: { 353: int oldInc = this.unitIncrement; 354: this.unitIncrement = unitIncrement; 355: firePropertyChange("unitIncrement", oldInc, 356: this.unitIncrement); 357: } 358: } 359: 360: /** 361: * The method returns how much the scrollbar's value 362: * should change for a block increment depending on 363: * the given direction. 364: * 365: * @param direction The direction to scroll in. 366: * 367: * @return The amount the scrollbar's value will change given the direction. 368: */ 369: public int getBlockIncrement(int direction) 370: { 371: return direction * blockIncrement; 372: } 373: 374: /** 375: * This method sets the blockIncrement property. 376: * 377: * @param blockIncrement The new blockIncrement. 378: */ 379: public void setBlockIncrement(int blockIncrement) 380: { 381: if (blockIncrement != this.blockIncrement) 382: { 383: int oldInc = this.blockIncrement; 384: this.blockIncrement = blockIncrement; 385: firePropertyChange("blockIncrement", oldInc, 386: this.blockIncrement); 387: } 388: } 389: 390: /** 391: * This method returns the unitIncrement. 392: * 393: * @return The unitIncrement. 394: */ 395: public int getUnitIncrement() 396: { 397: return unitIncrement; 398: } 399: 400: /** 401: * This method returns the blockIncrement. 402: * 403: * @return The blockIncrement. 404: */ 405: public int getBlockIncrement() 406: { 407: return blockIncrement; 408: } 409: 410: /** 411: * This method returns the value of the scrollbar. 412: * 413: * @return The value of the scrollbar. 414: */ 415: public int getValue() 416: { 417: return model.getValue(); 418: } 419: 420: /** 421: * This method changes the value of the scrollbar. 422: * 423: * @param value The new value of the scrollbar. 424: */ 425: public void setValue(int value) 426: { 427: if (isEnabled() && value != getValue()) 428: { 429: model.setValue(value); 430: fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 431: AdjustmentEvent.TRACK, value); 432: } 433: } 434: 435: /** 436: * This method returns the visible amount (AKA extent). 437: * The visible amount can be used by UI delegates to 438: * determine the size of the thumb. 439: * 440: * @return The visible amount (AKA extent). 441: */ 442: public int getVisibleAmount() 443: { 444: return model.getExtent(); 445: } 446: 447: /** 448: * This method sets the visible amount (AKA extent). 449: * 450: * @param extent The visible amount (AKA extent). 451: */ 452: public void setVisibleAmount(int extent) 453: { 454: if (extent != getVisibleAmount()) 455: { 456: model.setExtent(extent); 457: fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 458: AdjustmentEvent.TRACK, extent); 459: } 460: } 461: 462: /** 463: * This method returns the minimum value of the scrollbar. 464: * 465: * @return The minimum value of the scrollbar. 466: */ 467: public int getMinimum() 468: { 469: return model.getMinimum(); 470: } 471: 472: /** 473: * This method sets the minimum value of the scrollbar. 474: * 475: * @param minimum The minimum value of the scrollbar. 476: */ 477: public void setMinimum(int minimum) 478: { 479: if (minimum != getMinimum()) 480: { 481: model.setMinimum(minimum); 482: fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 483: AdjustmentEvent.TRACK, minimum); 484: } 485: } 486: 487: /** 488: * This method returns the maximum value of the scrollbar. 489: * 490: * @return The maximum value of the scrollbar. 491: */ 492: public int getMaximum() 493: { 494: return model.getMaximum(); 495: } 496: 497: /** 498: * This method sets the maximum value of the scrollbar. 499: * 500: * @param maximum The maximum value of the scrollbar. 501: */ 502: public void setMaximum(int maximum) 503: { 504: if (maximum != getMaximum()) 505: { 506: model.setMaximum(maximum); 507: fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 508: AdjustmentEvent.TRACK, maximum); 509: } 510: } 511: 512: /** 513: * This method returns the model's isAjusting value. 514: * 515: * @return The model's isAdjusting value. 516: */ 517: public boolean getValueIsAdjusting() 518: { 519: return model.getValueIsAdjusting(); 520: } 521: 522: /** 523: * This method sets the model's isAdjusting value. 524: * 525: * @param b The new isAdjusting value. 526: */ 527: public void setValueIsAdjusting(boolean b) 528: { 529: model.setValueIsAdjusting(b); 530: } 531: 532: /** 533: * This method sets the value, extent, minimum and 534: * maximum. 535: * 536: * @param newValue The new value. 537: * @param newExtent The new extent. 538: * @param newMin The new minimum. 539: * @param newMax The new maximum. 540: */ 541: public void setValues(int newValue, int newExtent, int newMin, int newMax) 542: { 543: if (!isEnabled()) 544: newValue = model.getValue(); 545: // It seems to be that on any change the value is fired. 546: if (newValue != getValue() || newExtent != getVisibleAmount() || 547: newMin != getMinimum() || newMax != getMaximum()) 548: { 549: model.setRangeProperties(newValue, newExtent, newMin, newMax, 550: model.getValueIsAdjusting()); 551: fireAdjustmentValueChanged(AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 552: AdjustmentEvent.TRACK, newValue); 553: } 554: } 555: 556: /** 557: * This method adds an AdjustmentListener to the scroll bar. 558: * 559: * @param listener The listener to add. 560: */ 561: public void addAdjustmentListener(AdjustmentListener listener) 562: { 563: listenerList.add(AdjustmentListener.class, listener); 564: } 565: 566: /** 567: * This method removes an AdjustmentListener from the scroll bar. 568: * 569: * @param listener The listener to remove. 570: */ 571: public void removeAdjustmentListener(AdjustmentListener listener) 572: { 573: listenerList.remove(AdjustmentListener.class, listener); 574: } 575: 576: /** 577: * This method returns an arry of all AdjustmentListeners listening to 578: * this scroll bar. 579: * 580: * @return An array of AdjustmentListeners listening to this scroll bar. 581: */ 582: public AdjustmentListener[] getAdjustmentListeners() 583: { 584: return (AdjustmentListener[]) listenerList.getListeners(AdjustmentListener.class); 585: } 586: 587: /** 588: * This method is called to fired AdjustmentEvents to the listeners 589: * of this scroll bar. All AdjustmentEvents that are fired 590: * will have an ID of ADJUSTMENT_VALUE_CHANGED and a type of 591: * TRACK. 592: * 593: * @param id The ID of the adjustment event. 594: * @param type The Type of change. 595: * @param value The new value for the property that was changed.. 596: */ 597: protected void fireAdjustmentValueChanged(int id, int type, int value) 598: { 599: Object[] adjustmentListeners = listenerList.getListenerList(); 600: AdjustmentEvent adjustmentEvent = new AdjustmentEvent(this, 601: AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, 602: AdjustmentEvent.TRACK, 603: value); 604: for (int i = adjustmentListeners.length - 2; i >= 0; i -= 2) 605: { 606: if (adjustmentListeners[i] == AdjustmentListener.class) 607: ((AdjustmentListener) adjustmentListeners[i + 1]).adjustmentValueChanged(adjustmentEvent); 608: } 609: } 610: 611: /** 612: * This method returns the minimum size for this scroll bar. 613: * 614: * @return The minimum size. 615: */ 616: public Dimension getMinimumSize() 617: { 618: return ui.getMinimumSize(this); 619: } 620: 621: /** 622: * This method returns the maximum size for this scroll bar. 623: * 624: * @return The maximum size. 625: */ 626: public Dimension getMaximumSize() 627: { 628: return ui.getMaximumSize(this); 629: } 630: 631: /** 632: * This method overrides the setEnabled in JComponent. 633: * When the scroll bar is disabled, the knob cannot 634: * be moved. 635: * 636: * @param x Whether the scrollbar is enabled. 637: */ 638: public void setEnabled(boolean x) 639: { 640: // nothing special needs to be done here since we 641: // just check the enabled setting before changing the value. 642: super.setEnabled(x); 643: } 644: 645: /** 646: * Returns a string describing the attributes for the <code>JScrollBar</code> 647: * component, for use in debugging. The return value is guaranteed to be 648: * non-<code>null</code>, but the format of the string may vary between 649: * implementations. 650: * 651: * @return A string describing the attributes of the <code>JScrollBar</code>. 652: */ 653: protected String paramString() 654: { 655: StringBuffer sb = new StringBuffer(super.paramString()); 656: sb.append(",blockIncrement=").append(blockIncrement); 657: sb.append(",orientation="); 658: if (this.orientation == JScrollBar.HORIZONTAL) 659: sb.append("HORIZONTAL"); 660: else 661: sb.append("VERTICAL"); 662: sb.append(",unitIncrement=").append(unitIncrement); 663: return sb.toString(); 664: } 665: 666: /** 667: * Returns the object that provides accessibility features for this 668: * <code>JScrollBar</code> component. 669: * 670: * @return The accessible context (an instance of 671: * {@link AccessibleJScrollBar}). 672: */ 673: public AccessibleContext getAccessibleContext() 674: { 675: if (accessibleContext == null) 676: accessibleContext = new AccessibleJScrollBar(); 677: return accessibleContext; 678: } 679: }