GNU Classpath (0.20) | |
Frames | No Frames |
1: /* Scrollbar.java -- AWT Scrollbar widget 2: Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 3: 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 java.awt; 41: 42: import java.awt.event.AdjustmentEvent; 43: import java.awt.event.AdjustmentListener; 44: import java.awt.peer.ScrollbarPeer; 45: import java.util.EventListener; 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: 54: /** 55: * This class implements a scrollbar widget. 56: * 57: * @author Aaron M. Renn (arenn@urbanophile.com) 58: * @author Tom Tromey (tromey@cygnus.com) 59: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 60: */ 61: public class Scrollbar extends Component implements Accessible, Adjustable 62: { 63: // FIXME: Serialization readObject/writeObject 64: 65: /** 66: * Constant indicating that a scrollbar is horizontal. 67: */ 68: public static final int HORIZONTAL = 0; 69: 70: /** 71: * Constant indicating that a scrollbar is vertical. 72: */ 73: public static final int VERTICAL = 1; 74: 75: /** 76: * Serialization Constant. 77: */ 78: private static final long serialVersionUID = 8451667562882310543L; 79: 80: /** 81: * @serial The amount by which the value of the scrollbar is changed 82: * when incrementing in line mode. 83: */ 84: private int lineIncrement; 85: 86: /** 87: * @serial The amount by which the value of the scrollbar is changed 88: * when incrementing in page mode. 89: */ 90: private int pageIncrement; 91: 92: /** 93: * @serial The maximum value for this scrollbar 94: */ 95: private int maximum; 96: 97: /** 98: * @serial The minimum value for this scrollbar 99: */ 100: private int minimum; 101: 102: /** 103: * @serial The orientation of this scrollbar, which will be either 104: * the <code>HORIZONTAL</code> or <code>VERTICAL</code> constant 105: * from this class. 106: */ 107: private int orientation; 108: 109: /** 110: * @serial The current value of this scrollbar. 111: */ 112: private int value; 113: 114: /** 115: * @serial The width of the scrollbar's thumb, which is relative 116: * to the minimum and maximum value of the scrollbar. 117: */ 118: private int visibleAmount; 119: 120: /** 121: * List of AdjustmentListener's. 122: */ 123: private AdjustmentListener adjustment_listeners; 124: 125: /** 126: * true if the scrollbar is adjusting, false otherwise. 127: */ 128: private transient boolean valueIsAdjusting = false; 129: 130: /** 131: * The number used to generate the name returned by getName. 132: */ 133: private static transient long next_scrollbar_number; 134: 135: /** 136: * Initializes a new instance of <code>Scrollbar</code> with a 137: * vertical orientation and default values for all other parameters. 138: * 139: * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true, 140: */ 141: public Scrollbar() 142: { 143: this(VERTICAL); 144: } 145: 146: /** 147: * Initializes a new instance of <code>Scrollbar</code> with the 148: * specified orientation and default values for all other parameters. 149: * The orientation must be either the constant <code>HORIZONTAL</code> or 150: * <code>VERTICAL</code> from this class. An incorrect value will throw 151: * an exception. 152: * 153: * @param orientation The orientation of this scrollbar. 154: * 155: * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true, 156: * @exception IllegalArgumentException If the orientation value is not valid. 157: */ 158: public Scrollbar(int orientation) throws IllegalArgumentException 159: { 160: this(orientation, 0, 10, 0, 100); 161: } 162: 163: /** 164: * Initializes a new instance of <code>Scrollbar</code> with the 165: * specified parameters. The orientation must be either the constant 166: * <code>HORIZONTAL</code> or <code>VERTICAL</code>. An incorrect value 167: * will throw an exception. Inconsistent values for other parameters 168: * are silently corrected to valid values. 169: * 170: * @param orientation The orientation of this scrollbar. 171: * @param value The initial value of the scrollbar. 172: * @param visibleAmount The width of the scrollbar thumb. 173: * @param minimum The minimum value of the scrollbar. 174: * @param maximum The maximum value of the scrollbar. 175: * 176: * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true, 177: * @exception IllegalArgumentException If the orientation value is not valid. 178: */ 179: public Scrollbar(int orientation, int value, int visibleAmount, int minimum, 180: int maximum) throws IllegalArgumentException 181: { 182: if (GraphicsEnvironment.isHeadless()) 183: throw new HeadlessException(); 184: 185: if ((orientation != HORIZONTAL) && (orientation != VERTICAL)) 186: throw new IllegalArgumentException("Bad orientation value: " 187: + orientation); 188: 189: this.orientation = orientation; 190: 191: setValues(value, visibleAmount, minimum, maximum); 192: 193: // Default is 1 according to online docs. 194: lineIncrement = 1; 195: 196: // Default is 10 according to javadocs. 197: pageIncrement = 10; 198: } 199: 200: /** 201: * Returns the orientation constant for this object. 202: * 203: * @return The orientation constant for this object. 204: */ 205: public int getOrientation() 206: { 207: return orientation; 208: } 209: 210: /** 211: * Sets the orientation of this scrollbar to the specified value. This 212: * value must be either the constant <code>HORIZONTAL</code> or 213: * <code>VERTICAL</code> from this class or an exception will be thrown. 214: * 215: * @param orientation The new orientation value. 216: * 217: * @exception IllegalArgumentException If the orientation value is not valid. 218: */ 219: public void setOrientation(int orientation) 220: { 221: if ((orientation != HORIZONTAL) && (orientation != VERTICAL)) 222: throw new IllegalArgumentException("Bad orientation value: " 223: + orientation); 224: 225: // FIXME: Communicate to peer? Or must this be called before peer creation? 226: this.orientation = orientation; 227: } 228: 229: /** 230: * Returns the current value for this scrollbar. 231: * 232: * @return The current value for this scrollbar. 233: */ 234: public int getValue() 235: { 236: return value; 237: } 238: 239: /** 240: * Sets the current value for this scrollbar to the specified value. 241: * If this is inconsistent with the minimum and maximum values for this 242: * scrollbar, the value is silently adjusted. 243: * 244: * @param value The new value for this scrollbar. 245: */ 246: public void setValue(int value) 247: { 248: setValues(value, visibleAmount, minimum, maximum); 249: } 250: 251: /** 252: * Returns the maximum value for this scrollbar. 253: * 254: * @return The maximum value for this scrollbar. 255: */ 256: public int getMaximum() 257: { 258: return maximum; 259: } 260: 261: /** 262: * Sets the maximum value for this scrollbar to the specified value. 263: * If the value is less than the current minimum value, it is silent 264: * set to equal the minimum value. 265: * 266: * @param maximum The new maximum value for this scrollbar. 267: */ 268: public void setMaximum(int maximum) 269: { 270: setValues(value, visibleAmount, minimum, maximum); 271: } 272: 273: /** 274: * Returns the minimum value for this scrollbar. 275: * 276: * @return The minimum value for this scrollbar. 277: */ 278: public int getMinimum() 279: { 280: return minimum; 281: } 282: 283: /** 284: * Sets the minimum value for this scrollbar to the specified value. If 285: * this is not consistent with the current value and maximum, it is 286: * silently adjusted to be consistent. 287: * 288: * @param minimum The new minimum value for this scrollbar. 289: */ 290: public void setMinimum(int minimum) 291: { 292: setValues(value, visibleAmount, minimum, maximum); 293: } 294: 295: /** 296: * Returns the width of the scrollbar's thumb, in units relative to the 297: * maximum and minimum value of the scrollbar. 298: * 299: * @return The width of the scrollbar's thumb. 300: */ 301: public int getVisibleAmount() 302: { 303: return getVisible(); 304: } 305: 306: /** 307: * Returns the width of the scrollbar's thumb, in units relative to the 308: * maximum and minimum value of the scrollbar. 309: * 310: * @return The width of the scrollbar's thumb. 311: * 312: * @deprecated This method is deprecated in favor of 313: * <code>getVisibleAmount()</code>. 314: */ 315: public int getVisible() 316: { 317: return visibleAmount; 318: } 319: 320: /** 321: * Sets the width of the scrollbar's thumb, in units relative to the 322: * maximum and minimum value of the scrollbar. 323: * 324: * @param visibleAmount The new visible amount value of the scrollbar. 325: */ 326: public void setVisibleAmount(int visibleAmount) 327: { 328: setValues(value, visibleAmount, minimum, maximum); 329: } 330: 331: /** 332: * Sets the current value, visible amount, minimum, and maximum for this 333: * scrollbar. These values are adjusted to be internally consistent 334: * if necessary. 335: * 336: * @param value The new value for this scrollbar. 337: * @param visibleAmount The new visible amount for this scrollbar. 338: * @param minimum The new minimum value for this scrollbar. 339: * @param maximum The new maximum value for this scrollbar. 340: */ 341: public synchronized void setValues(int value, int visibleAmount, 342: int minimum, int maximum) 343: { 344: if (maximum < minimum) 345: maximum = minimum; 346: 347: if (value < minimum) 348: value = minimum; 349: 350: if (value > maximum) 351: value = maximum; 352: 353: if (visibleAmount > maximum - minimum) 354: visibleAmount = maximum - minimum; 355: 356: ScrollbarPeer peer = (ScrollbarPeer) getPeer(); 357: if (peer != null 358: && (this.value != value || this.visibleAmount != visibleAmount 359: || this.minimum != minimum || this.maximum != maximum)) 360: peer.setValues(value, visibleAmount, minimum, maximum); 361: 362: this.value = value; 363: this.visibleAmount = visibleAmount; 364: this.minimum = minimum; 365: this.maximum = maximum; 366: 367: int range = maximum - minimum; 368: if (lineIncrement > range) 369: { 370: if (range == 0) 371: lineIncrement = 1; 372: else 373: lineIncrement = range; 374: 375: if (peer != null) 376: peer.setLineIncrement(lineIncrement); 377: } 378: 379: if (pageIncrement > range) 380: { 381: if (range == 0) 382: pageIncrement = 1; 383: else 384: pageIncrement = range; 385: 386: if (peer != null) 387: peer.setPageIncrement(pageIncrement); 388: } 389: } 390: 391: /** 392: * Returns the value added or subtracted when the user activates the scrollbar 393: * scroll by a "unit" amount. 394: * 395: * @return The unit increment value. 396: */ 397: public int getUnitIncrement() 398: { 399: return getLineIncrement(); 400: } 401: 402: /** 403: * Returns the value added or subtracted when the user selects the scrollbar 404: * scroll by a "unit" amount control. 405: * 406: * @return The unit increment value. 407: * 408: * @deprecated This method is deprecated in favor of 409: * <code>getUnitIncrement()</code>. 410: */ 411: public int getLineIncrement() 412: { 413: return lineIncrement; 414: } 415: 416: /** 417: * Sets the value added or subtracted to the scrollbar value when the 418: * user selects the scroll by a "unit" amount control. 419: * 420: * @param unitIncrement The new unit increment amount. 421: */ 422: public synchronized void setUnitIncrement(int unitIncrement) 423: { 424: setLineIncrement(unitIncrement); 425: } 426: 427: /** 428: * Sets the value added or subtracted to the scrollbar value when the 429: * user selects the scroll by a "unit" amount control. 430: * 431: * @param lineIncrement The new unit increment amount. 432: * 433: * @deprecated This method is deprecated in favor of 434: * <code>setUnitIncrement()</code>. 435: */ 436: public void setLineIncrement(int lineIncrement) 437: { 438: if (lineIncrement < 0) 439: throw new IllegalArgumentException("Unit increment less than zero."); 440: 441: int range = maximum - minimum; 442: if (lineIncrement > range) 443: { 444: if (range == 0) 445: lineIncrement = 1; 446: else 447: lineIncrement = range; 448: } 449: 450: if (lineIncrement == this.lineIncrement) 451: return; 452: 453: this.lineIncrement = lineIncrement; 454: 455: ScrollbarPeer peer = (ScrollbarPeer) getPeer(); 456: if (peer != null) 457: peer.setLineIncrement(this.lineIncrement); 458: } 459: 460: /** 461: * Returns the value added or subtracted when the user activates the scrollbar 462: * scroll by a "block" amount. 463: * 464: * @return The block increment value. 465: */ 466: public int getBlockIncrement() 467: { 468: return getPageIncrement(); 469: } 470: 471: /** 472: * Returns the value added or subtracted when the user selects the scrollbar 473: * scroll by a "block" amount control. 474: * 475: * @return The block increment value. 476: * 477: * @deprecated This method is deprecated in favor of 478: * <code>getBlockIncrement()</code>. 479: */ 480: public int getPageIncrement() 481: { 482: return pageIncrement; 483: } 484: 485: /** 486: * Sets the value added or subtracted to the scrollbar value when the 487: * user selects the scroll by a "block" amount control. 488: * 489: * @param blockIncrement The new block increment amount. 490: */ 491: public synchronized void setBlockIncrement(int blockIncrement) 492: { 493: setPageIncrement(blockIncrement); 494: } 495: 496: /** 497: * Sets the value added or subtracted to the scrollbar value when the 498: * user selects the scroll by a "block" amount control. 499: * 500: * @param pageIncrement The new block increment amount. 501: * 502: * @deprecated This method is deprecated in favor of 503: * <code>setBlockIncrement()</code>. 504: */ 505: public void setPageIncrement(int pageIncrement) 506: { 507: if (pageIncrement < 0) 508: throw new IllegalArgumentException("Block increment less than zero."); 509: 510: int range = maximum - minimum; 511: if (pageIncrement > range) 512: { 513: if (range == 0) 514: pageIncrement = 1; 515: else 516: pageIncrement = range; 517: } 518: 519: if (pageIncrement == this.pageIncrement) 520: return; 521: 522: this.pageIncrement = pageIncrement; 523: 524: ScrollbarPeer peer = (ScrollbarPeer) getPeer(); 525: if (peer != null) 526: peer.setPageIncrement(this.pageIncrement); 527: } 528: 529: /** 530: * Notifies this object to create its native peer. 531: */ 532: public synchronized void addNotify() 533: { 534: if (peer == null) 535: peer = getToolkit().createScrollbar(this); 536: super.addNotify(); 537: } 538: 539: /** 540: * Adds a new adjustment listener to the list of registered listeners 541: * for this object. 542: * 543: * @param listener The listener to add. 544: */ 545: public synchronized void addAdjustmentListener(AdjustmentListener listener) 546: { 547: adjustment_listeners = AWTEventMulticaster.add(adjustment_listeners, 548: listener); 549: enableEvents(AWTEvent.ADJUSTMENT_EVENT_MASK); 550: } 551: 552: /** 553: * Removes the specified listener from the list of registered listeners 554: * for this object. 555: * 556: * @param listener The listener to remove. 557: */ 558: public synchronized void removeAdjustmentListener(AdjustmentListener listener) 559: { 560: adjustment_listeners = AWTEventMulticaster.remove(adjustment_listeners, 561: listener); 562: } 563: 564: /** 565: * Processes events for this scrollbar. It does this by calling 566: * <code>processAdjustmentEvent()</code> if the event is an instance of 567: * <code>AdjustmentEvent</code>, otherwise it calls the superclass to 568: * process the event. 569: * 570: * @param event The event to process. 571: */ 572: protected void processEvent(AWTEvent event) 573: { 574: if (event instanceof AdjustmentEvent) 575: processAdjustmentEvent((AdjustmentEvent) event); 576: else 577: super.processEvent(event); 578: } 579: 580: /** 581: * Processes adjustment events for this object by dispatching them to 582: * any registered listeners. Note that this method will only be called 583: * if adjustment events are enabled. This will happen automatically if 584: * any listeners are registered. Otherwise, it can be enabled by a 585: * call to <code>enableEvents()</code>. 586: * 587: * @param event The event to process. 588: */ 589: protected void processAdjustmentEvent(AdjustmentEvent event) 590: { 591: value = event.getValue(); 592: if (adjustment_listeners != null) 593: adjustment_listeners.adjustmentValueChanged(event); 594: } 595: 596: void dispatchEventImpl(AWTEvent e) 597: { 598: if (e.id <= AdjustmentEvent.ADJUSTMENT_LAST 599: && e.id >= AdjustmentEvent.ADJUSTMENT_FIRST 600: && (adjustment_listeners != null 601: || (eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0)) 602: processEvent(e); 603: else 604: super.dispatchEventImpl(e); 605: } 606: 607: /** 608: * Returns a debugging string for this object. 609: * 610: * @return A debugging string for this object. 611: */ 612: protected String paramString() 613: { 614: return ("value=" + getValue() + ",visibleAmount=" + getVisibleAmount() 615: + ",minimum=" + getMinimum() + ",maximum=" + getMaximum() 616: + ",pageIncrement=" + pageIncrement + ",lineIncrement=" 617: + lineIncrement + ",orientation=" 618: + (orientation == HORIZONTAL ? "HORIZONTAL" : "VERTICAL") 619: + super.paramString()); 620: } 621: 622: /** 623: * Returns an array of all the objects currently registered as FooListeners 624: * upon this <code>Scrollbar</code>. FooListeners are registered using the 625: * addFooListener method. 626: * 627: * @exception ClassCastException If listenerType doesn't specify a class or 628: * interface that implements java.util.EventListener. 629: */ 630: public EventListener[] getListeners(Class listenerType) 631: { 632: if (listenerType == AdjustmentListener.class) 633: return AWTEventMulticaster.getListeners(adjustment_listeners, 634: listenerType); 635: 636: return super.getListeners(listenerType); 637: } 638: 639: /** 640: * Returns an array of all registered adjustment listeners. 641: */ 642: public AdjustmentListener[] getAdjustmentListeners() 643: { 644: return (AdjustmentListener[]) getListeners(AdjustmentListener.class); 645: } 646: 647: /** 648: * Returns true if the value is in the process of changing. 649: * 650: * @since 1.4 651: */ 652: public boolean getValueIsAdjusting() 653: { 654: return valueIsAdjusting; 655: } 656: 657: /** 658: * Sets the value of valueIsAdjusting. 659: * 660: * @since 1.4 661: */ 662: public void setValueIsAdjusting(boolean valueIsAdjusting) 663: { 664: this.valueIsAdjusting = valueIsAdjusting; 665: } 666: 667: /** 668: * Generate a unique name for this scroll bar. 669: * 670: * @return A unique name for this scroll bar. 671: */ 672: String generateName() 673: { 674: return "scrollbar" + getUniqueLong(); 675: } 676: 677: private static synchronized long getUniqueLong() 678: { 679: return next_scrollbar_number++; 680: } 681: 682: /** 683: * This class provides accessibility support for the 684: * scrollbar. 685: * 686: * @author Jerry Quinn (jlquinn@optonline.net) 687: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 688: */ 689: protected class AccessibleAWTScrollBar extends AccessibleAWTComponent 690: implements AccessibleValue 691: { 692: /** 693: * Serialization constant to match JDK 1.5 694: */ 695: private static final long serialVersionUID = -344337268523697807L; 696: 697: /** 698: * Returns the role of this accessible object. 699: * 700: * @return the instance of <code>AccessibleRole</code>, 701: * which describes this object. 702: * 703: * @see javax.accessibility.AccessibleRole 704: */ 705: public AccessibleRole getAccessibleRole() 706: { 707: return AccessibleRole.SCROLL_BAR; 708: } 709: 710: /** 711: * Returns the state set of this accessible object. 712: * 713: * @return a set of <code>AccessibleState</code>s which 714: * represent the current state of the accessible object. 715: * 716: * @see javax.accessibility.AccessibleState 717: * @see javax.accessibility.AccessibleStateSet 718: */ 719: public AccessibleStateSet getAccessibleStateSet() 720: { 721: AccessibleStateSet states = super.getAccessibleStateSet(); 722: if (getOrientation() == HORIZONTAL) 723: states.add(AccessibleState.HORIZONTAL); 724: else 725: states.add(AccessibleState.VERTICAL); 726: if (getValueIsAdjusting()) 727: states.add(AccessibleState.BUSY); 728: return states; 729: } 730: 731: /** 732: * Returns an implementation of the <code>AccessibleValue</code> 733: * interface for this accessible object. In this case, the 734: * current instance is simply returned (with a more appropriate 735: * type), as it also implements the accessible value as well as 736: * the context. 737: * 738: * @return the accessible value associated with this context. 739: * 740: * @see javax.accessibility.AccessibleValue 741: */ 742: public AccessibleValue getAccessibleValue() 743: { 744: return this; 745: } 746: 747: /** 748: * Returns the current value of this accessible object. 749: * In this case, this is the same as the value for 750: * the scrollbar, wrapped in an <code>Integer</code> 751: * object. 752: * 753: * @return the numeric value of this scrollbar. 754: * 755: * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue() 756: */ 757: public Number getCurrentAccessibleValue() 758: { 759: return new Integer(getValue()); 760: } 761: 762: /** 763: * Sets the current value of this accessible object 764: * to that supplied. In this case, the value of the 765: * scrollbar is set, and this method always returns 766: * true. 767: * 768: * @param number the new accessible value. 769: * 770: * @return true if the value was set. 771: * 772: * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number) 773: */ 774: public boolean setCurrentAccessibleValue(Number number) 775: { 776: setValue(number.intValue()); 777: return true; 778: } 779: 780: /** 781: * Returns the minimum acceptable accessible value used 782: * by this object. In this case, this is the same as 783: * the minimum value of the scrollbar, wrapped in an 784: * object. 785: * 786: * @return the minimum value of this scrollbar. 787: * 788: * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue() 789: */ 790: public Number getMinimumAccessibleValue() 791: { 792: return new Integer(getMinimum()); 793: } 794: 795: /** 796: * Returns the maximum acceptable accessible value used 797: * by this object. In this case, this is the same as 798: * the maximum value of the scrollbar, wrapped in an 799: * object. 800: * 801: * @return the maximum value of this scrollbar. 802: * 803: * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue() 804: */ 805: public Number getMaximumAccessibleValue() 806: { 807: return new Integer(getMaximum()); 808: } 809: } 810: 811: /** 812: * Gets the AccessibleContext associated with this <code>Scrollbar</code>. 813: * The context is created, if necessary. 814: * 815: * @return the associated context 816: */ 817: public AccessibleContext getAccessibleContext() 818: { 819: /* Create the context if this is the first request */ 820: if (accessibleContext == null) 821: accessibleContext = new AccessibleAWTScrollBar(); 822: 823: return accessibleContext; 824: } 825: }
GNU Classpath (0.20) |