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