1 /* 2 * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 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 package java.awt; 26 27 import java.awt.peer.ScrollbarPeer; 28 import java.awt.event.*; 29 import java.util.EventListener; 30 import java.io.ObjectOutputStream; 31 import java.io.ObjectInputStream; 32 import java.io.IOException; 33 import javax.accessibility.*; 34 35 36 /** 37 * The <code>Scrollbar</code> class embodies a scroll bar, a 38 * familiar user-interface object. A scroll bar provides a 39 * convenient means for allowing a user to select from a 40 * range of values. The following three vertical 41 * scroll bars could be used as slider controls to pick 42 * the red, green, and blue components of a color: 43 * <p> 44 * <img src="doc-files/Scrollbar-1.gif" alt="Image shows 3 vertical sliders, side-by-side." 45 * style="float:center; margin: 7px 10px;"> 46 * <p> 47 * Each scroll bar in this example could be created with 48 * code similar to the following: 49 * 50 * <hr><blockquote><pre> 51 * redSlider=new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0, 255); 52 * add(redSlider); 53 * </pre></blockquote><hr> 54 * <p> 55 * Alternatively, a scroll bar can represent a range of values. For 56 * example, if a scroll bar is used for scrolling through text, the 57 * width of the "bubble" (also called the "thumb" or "scroll box") 58 * can be used to represent the amount of text that is visible. 59 * Here is an example of a scroll bar that represents a range: 60 * <p> 61 * <img src="doc-files/Scrollbar-2.gif" 62 * alt="Image shows horizontal slider with starting range of 0 and ending range of 300. The slider thumb is labeled 60." 63 * style="float:center; margin: 7px 10px;"> 64 * <p> 65 * The value range represented by the bubble in this example 66 * is the <em>visible amount</em>. The horizontal scroll bar 67 * in this example could be created with code like the following: 68 * 69 * <hr><blockquote><pre> 70 * ranger = new Scrollbar(Scrollbar.HORIZONTAL, 0, 60, 0, 300); 71 * add(ranger); 72 * </pre></blockquote><hr> 73 * <p> 74 * Note that the actual maximum value of the scroll bar is the 75 * <code>maximum</code> minus the <code>visible amount</code>. 76 * In the previous example, because the <code>maximum</code> is 77 * 300 and the <code>visible amount</code> is 60, the actual maximum 78 * value is 240. The range of the scrollbar track is 0 - 300. 79 * The left side of the bubble indicates the value of the 80 * scroll bar. 81 * <p> 82 * Normally, the user changes the value of the scroll bar by 83 * making a gesture with the mouse. For example, the user can 84 * drag the scroll bar's bubble up and down, or click in the 85 * scroll bar's unit increment or block increment areas. Keyboard 86 * gestures can also be mapped to the scroll bar. By convention, 87 * the <b>Page Up</b> and <b>Page Down</b> 88 * keys are equivalent to clicking in the scroll bar's block 89 * increment and block decrement areas. 90 * <p> 91 * When the user changes the value of the scroll bar, the scroll bar 92 * receives an instance of <code>AdjustmentEvent</code>. 93 * The scroll bar processes this event, passing it along to 94 * any registered listeners. 95 * <p> 96 * Any object that wishes to be notified of changes to the 97 * scroll bar's value should implement 98 * <code>AdjustmentListener</code>, an interface defined in 99 * the package <code>java.awt.event</code>. 100 * Listeners can be added and removed dynamically by calling 101 * the methods <code>addAdjustmentListener</code> and 102 * <code>removeAdjustmentListener</code>. 103 * <p> 104 * The <code>AdjustmentEvent</code> class defines five types 105 * of adjustment event, listed here: 106 * 107 * <ul> 108 * <li><code>AdjustmentEvent.TRACK</code> is sent out when the 109 * user drags the scroll bar's bubble. 110 * <li><code>AdjustmentEvent.UNIT_INCREMENT</code> is sent out 111 * when the user clicks in the left arrow of a horizontal scroll 112 * bar, or the top arrow of a vertical scroll bar, or makes the 113 * equivalent gesture from the keyboard. 114 * <li><code>AdjustmentEvent.UNIT_DECREMENT</code> is sent out 115 * when the user clicks in the right arrow of a horizontal scroll 116 * bar, or the bottom arrow of a vertical scroll bar, or makes the 117 * equivalent gesture from the keyboard. 118 * <li><code>AdjustmentEvent.BLOCK_INCREMENT</code> is sent out 119 * when the user clicks in the track, to the left of the bubble 120 * on a horizontal scroll bar, or above the bubble on a vertical 121 * scroll bar. By convention, the <b>Page Up</b> 122 * key is equivalent, if the user is using a keyboard that 123 * defines a <b>Page Up</b> key. 124 * <li><code>AdjustmentEvent.BLOCK_DECREMENT</code> is sent out 125 * when the user clicks in the track, to the right of the bubble 126 * on a horizontal scroll bar, or below the bubble on a vertical 127 * scroll bar. By convention, the <b>Page Down</b> 128 * key is equivalent, if the user is using a keyboard that 129 * defines a <b>Page Down</b> key. 130 * </ul> 131 * <p> 132 * The JDK 1.0 event system is supported for backwards 133 * compatibility, but its use with newer versions of the platform is 134 * discouraged. The five types of adjustment events introduced 135 * with JDK 1.1 correspond to the five event types 136 * that are associated with scroll bars in previous platform versions. 137 * The following list gives the adjustment event type, 138 * and the corresponding JDK 1.0 event type it replaces. 139 * 140 * <ul> 141 * <li><code>AdjustmentEvent.TRACK</code> replaces 142 * <code>Event.SCROLL_ABSOLUTE</code> 143 * <li><code>AdjustmentEvent.UNIT_INCREMENT</code> replaces 144 * <code>Event.SCROLL_LINE_UP</code> 145 * <li><code>AdjustmentEvent.UNIT_DECREMENT</code> replaces 146 * <code>Event.SCROLL_LINE_DOWN</code> 147 * <li><code>AdjustmentEvent.BLOCK_INCREMENT</code> replaces 148 * <code>Event.SCROLL_PAGE_UP</code> 149 * <li><code>AdjustmentEvent.BLOCK_DECREMENT</code> replaces 150 * <code>Event.SCROLL_PAGE_DOWN</code> 151 * </ul> 152 * <p> 153 * <b>Note</b>: We recommend using a <code>Scrollbar</code> 154 * for value selection only. If you want to implement 155 * a scrollable component inside a container, we recommend you use 156 * a {@link ScrollPane ScrollPane}. If you use a 157 * <code>Scrollbar</code> for this purpose, you are likely to 158 * encounter issues with painting, key handling, sizing and 159 * positioning. 160 * 161 * @author Sami Shaio 162 * @see java.awt.event.AdjustmentEvent 163 * @see java.awt.event.AdjustmentListener 164 * @since 1.0 165 */ 166 public class Scrollbar extends Component implements Adjustable, Accessible { 167 168 /** 169 * A constant that indicates a horizontal scroll bar. 170 */ 171 public static final int HORIZONTAL = 0; 172 173 /** 174 * A constant that indicates a vertical scroll bar. 175 */ 176 public static final int VERTICAL = 1; 177 178 /** 179 * The value of the <code>Scrollbar</code>. 180 * This property must be greater than or equal to <code>minimum</code> 181 * and less than or equal to 182 * <code>maximum - visibleAmount</code> 183 * 184 * @serial 185 * @see #getValue 186 * @see #setValue 187 */ 188 int value; 189 190 /** 191 * The maximum value of the <code>Scrollbar</code>. 192 * This value must be greater than the <code>minimum</code> 193 * value.<br> 194 * 195 * @serial 196 * @see #getMaximum 197 * @see #setMaximum 198 */ 199 int maximum; 200 201 /** 202 * The minimum value of the <code>Scrollbar</code>. 203 * This value must be less than the <code>maximum</code> 204 * value.<br> 205 * 206 * @serial 207 * @see #getMinimum 208 * @see #setMinimum 209 */ 210 int minimum; 211 212 /** 213 * The size of the <code>Scrollbar</code>'s bubble. 214 * When a scroll bar is used to select a range of values, 215 * the visibleAmount represents the size of this range. 216 * Depending on platform, this may be visually indicated 217 * by the size of the bubble. 218 * 219 * @serial 220 * @see #getVisibleAmount 221 * @see #setVisibleAmount 222 */ 223 int visibleAmount; 224 225 /** 226 * The <code>Scrollbar</code>'s orientation--being either horizontal 227 * or vertical. 228 * This value should be specified when the scrollbar is created.<BR> 229 * orientation can be either : <code>VERTICAL</code> or 230 * <code>HORIZONTAL</code> only. 231 * 232 * @serial 233 * @see #getOrientation 234 * @see #setOrientation 235 */ 236 int orientation; 237 238 /** 239 * The amount by which the scrollbar value will change when going 240 * up or down by a line. 241 * This value must be greater than zero. 242 * 243 * @serial 244 * @see #getLineIncrement 245 * @see #setLineIncrement 246 */ 247 int lineIncrement = 1; 248 249 /** 250 * The amount by which the scrollbar value will change when going 251 * up or down by a page. 252 * This value must be greater than zero. 253 * 254 * @serial 255 * @see #getPageIncrement 256 * @see #setPageIncrement 257 */ 258 int pageIncrement = 10; 259 260 /** 261 * The adjusting status of the <code>Scrollbar</code>. 262 * True if the value is in the process of changing as a result of 263 * actions being taken by the user. 264 * 265 * @see #getValueIsAdjusting 266 * @see #setValueIsAdjusting 267 * @since 1.4 268 */ 269 transient boolean isAdjusting; 270 271 transient AdjustmentListener adjustmentListener; 272 273 private static final String base = "scrollbar"; 274 private static int nameCounter = 0; 275 276 /* 277 * JDK 1.1 serialVersionUID 278 */ 279 private static final long serialVersionUID = 8451667562882310543L; 280 281 /** 282 * Initialize JNI field and method IDs. 283 */ 284 private static native void initIDs(); 285 286 static { 287 /* ensure that the necessary native libraries are loaded */ 288 Toolkit.loadLibraries(); 289 if (!GraphicsEnvironment.isHeadless()) { 290 initIDs(); 291 } 292 } 293 294 /** 295 * Constructs a new vertical scroll bar. 296 * The default properties of the scroll bar are listed in 297 * the following table: 298 * 299 * <table border=1 summary="Scrollbar default properties"> 300 * <tr> 301 * <th>Property</th> 302 * <th>Description</th> 303 * <th>Default Value</th> 304 * </tr> 305 * <tr> 306 * <td>orientation</td> 307 * <td>indicates whether the scroll bar is vertical 308 * <br>or horizontal</td> 309 * <td><code>Scrollbar.VERTICAL</code></td> 310 * </tr> 311 * <tr> 312 * <td>value</td> 313 * <td>value which controls the location 314 * <br>of the scroll bar's bubble</td> 315 * <td>0</td> 316 * </tr> 317 * <tr> 318 * <td>visible amount</td> 319 * <td>visible amount of the scroll bar's range, 320 * <br>typically represented by the size of the 321 * <br>scroll bar's bubble</td> 322 * <td>10</td> 323 * </tr> 324 * <tr> 325 * <td>minimum</td> 326 * <td>minimum value of the scroll bar</td> 327 * <td>0</td> 328 * </tr> 329 * <tr> 330 * <td>maximum</td> 331 * <td>maximum value of the scroll bar</td> 332 * <td>100</td> 333 * </tr> 334 * <tr> 335 * <td>unit increment</td> 336 * <td>amount the value changes when the 337 * <br>Line Up or Line Down key is pressed, 338 * <br>or when the end arrows of the scrollbar 339 * <br>are clicked </td> 340 * <td>1</td> 341 * </tr> 342 * <tr> 343 * <td>block increment</td> 344 * <td>amount the value changes when the 345 * <br>Page Up or Page Down key is pressed, 346 * <br>or when the scrollbar track is clicked 347 * <br>on either side of the bubble </td> 348 * <td>10</td> 349 * </tr> 350 * </table> 351 * 352 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 353 * returns true. 354 * @see java.awt.GraphicsEnvironment#isHeadless 355 */ 356 public Scrollbar() throws HeadlessException { 357 this(VERTICAL, 0, 10, 0, 100); 358 } 359 360 /** 361 * Constructs a new scroll bar with the specified orientation. 362 * <p> 363 * The <code>orientation</code> argument must take one of the two 364 * values <code>Scrollbar.HORIZONTAL</code>, 365 * or <code>Scrollbar.VERTICAL</code>, 366 * indicating a horizontal or vertical scroll bar, respectively. 367 * 368 * @param orientation indicates the orientation of the scroll bar 369 * @exception IllegalArgumentException when an illegal value for 370 * the <code>orientation</code> argument is supplied 371 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 372 * returns true. 373 * @see java.awt.GraphicsEnvironment#isHeadless 374 */ 375 public Scrollbar(int orientation) throws HeadlessException { 376 this(orientation, 0, 10, 0, 100); 377 } 378 379 /** 380 * Constructs a new scroll bar with the specified orientation, 381 * initial value, visible amount, and minimum and maximum values. 382 * <p> 383 * The <code>orientation</code> argument must take one of the two 384 * values <code>Scrollbar.HORIZONTAL</code>, 385 * or <code>Scrollbar.VERTICAL</code>, 386 * indicating a horizontal or vertical scroll bar, respectively. 387 * <p> 388 * The parameters supplied to this constructor are subject to the 389 * constraints described in {@link #setValues(int, int, int, int)}. 390 * 391 * @param orientation indicates the orientation of the scroll bar. 392 * @param value the initial value of the scroll bar 393 * @param visible the visible amount of the scroll bar, typically 394 * represented by the size of the bubble 395 * @param minimum the minimum value of the scroll bar 396 * @param maximum the maximum value of the scroll bar 397 * @exception IllegalArgumentException when an illegal value for 398 * the <code>orientation</code> argument is supplied 399 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 400 * returns true. 401 * @see #setValues 402 * @see java.awt.GraphicsEnvironment#isHeadless 403 */ 404 public Scrollbar(int orientation, int value, int visible, int minimum, 405 int maximum) throws HeadlessException { 406 GraphicsEnvironment.checkHeadless(); 407 switch (orientation) { 408 case HORIZONTAL: 409 case VERTICAL: 410 this.orientation = orientation; 411 break; 412 default: 413 throw new IllegalArgumentException("illegal scrollbar orientation"); 414 } 415 setValues(value, visible, minimum, maximum); 416 } 417 418 /** 419 * Constructs a name for this component. Called by <code>getName</code> 420 * when the name is <code>null</code>. 421 */ 422 String constructComponentName() { 423 synchronized (Scrollbar.class) { 424 return base + nameCounter++; 425 } 426 } 427 428 /** 429 * Creates the <code>Scrollbar</code>'s peer. The peer allows you to modify 430 * the appearance of the <code>Scrollbar</code> without changing any of its 431 * functionality. 432 */ 433 public void addNotify() { 434 synchronized (getTreeLock()) { 435 if (peer == null) 436 peer = getComponentFactory().createScrollbar(this); 437 super.addNotify(); 438 } 439 } 440 441 /** 442 * Returns the orientation of this scroll bar. 443 * 444 * @return the orientation of this scroll bar, either 445 * <code>Scrollbar.HORIZONTAL</code> or 446 * <code>Scrollbar.VERTICAL</code> 447 * @see java.awt.Scrollbar#setOrientation 448 */ 449 public int getOrientation() { 450 return orientation; 451 } 452 453 /** 454 * Sets the orientation for this scroll bar. 455 * 456 * @param orientation the orientation of this scroll bar, either 457 * <code>Scrollbar.HORIZONTAL</code> or 458 * <code>Scrollbar.VERTICAL</code> 459 * @see java.awt.Scrollbar#getOrientation 460 * @exception IllegalArgumentException if the value supplied 461 * for <code>orientation</code> is not a 462 * legal value 463 * @since 1.1 464 */ 465 public void setOrientation(int orientation) { 466 synchronized (getTreeLock()) { 467 if (orientation == this.orientation) { 468 return; 469 } 470 switch (orientation) { 471 case HORIZONTAL: 472 case VERTICAL: 473 this.orientation = orientation; 474 break; 475 default: 476 throw new IllegalArgumentException("illegal scrollbar orientation"); 477 } 478 /* Create a new peer with the specified orientation. */ 479 if (peer != null) { 480 removeNotify(); 481 addNotify(); 482 invalidate(); 483 } 484 } 485 if (accessibleContext != null) { 486 accessibleContext.firePropertyChange( 487 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 488 ((orientation == VERTICAL) 489 ? AccessibleState.HORIZONTAL : AccessibleState.VERTICAL), 490 ((orientation == VERTICAL) 491 ? AccessibleState.VERTICAL : AccessibleState.HORIZONTAL)); 492 } 493 } 494 495 /** 496 * Gets the current value of this scroll bar. 497 * 498 * @return the current value of this scroll bar 499 * @see java.awt.Scrollbar#getMinimum 500 * @see java.awt.Scrollbar#getMaximum 501 */ 502 public int getValue() { 503 return value; 504 } 505 506 /** 507 * Sets the value of this scroll bar to the specified value. 508 * <p> 509 * If the value supplied is less than the current <code>minimum</code> 510 * or greater than the current <code>maximum - visibleAmount</code>, 511 * then either <code>minimum</code> or <code>maximum - visibleAmount</code> 512 * is substituted, as appropriate. 513 * <p> 514 * Normally, a program should change a scroll bar's 515 * value only by calling <code>setValues</code>. 516 * The <code>setValues</code> method simultaneously 517 * and synchronously sets the minimum, maximum, visible amount, 518 * and value properties of a scroll bar, so that they are 519 * mutually consistent. 520 * <p> 521 * Calling this method does not fire an 522 * <code>AdjustmentEvent</code>. 523 * 524 * @param newValue the new value of the scroll bar 525 * @see java.awt.Scrollbar#setValues 526 * @see java.awt.Scrollbar#getValue 527 * @see java.awt.Scrollbar#getMinimum 528 * @see java.awt.Scrollbar#getMaximum 529 */ 530 public void setValue(int newValue) { 531 // Use setValues so that a consistent policy relating 532 // minimum, maximum, visible amount, and value is enforced. 533 setValues(newValue, visibleAmount, minimum, maximum); 534 } 535 536 /** 537 * Gets the minimum value of this scroll bar. 538 * 539 * @return the minimum value of this scroll bar 540 * @see java.awt.Scrollbar#getValue 541 * @see java.awt.Scrollbar#getMaximum 542 */ 543 public int getMinimum() { 544 return minimum; 545 } 546 547 /** 548 * Sets the minimum value of this scroll bar. 549 * <p> 550 * When <code>setMinimum</code> is called, the minimum value 551 * is changed, and other values (including the maximum, the 552 * visible amount, and the current scroll bar value) 553 * are changed to be consistent with the new minimum. 554 * <p> 555 * Normally, a program should change a scroll bar's minimum 556 * value only by calling <code>setValues</code>. 557 * The <code>setValues</code> method simultaneously 558 * and synchronously sets the minimum, maximum, visible amount, 559 * and value properties of a scroll bar, so that they are 560 * mutually consistent. 561 * <p> 562 * Note that setting the minimum value to <code>Integer.MAX_VALUE</code> 563 * will result in the new minimum value being set to 564 * <code>Integer.MAX_VALUE - 1</code>. 565 * 566 * @param newMinimum the new minimum value for this scroll bar 567 * @see java.awt.Scrollbar#setValues 568 * @see java.awt.Scrollbar#setMaximum 569 * @since 1.1 570 */ 571 public void setMinimum(int newMinimum) { 572 // No checks are necessary in this method since minimum is 573 // the first variable checked in the setValues function. 574 575 // Use setValues so that a consistent policy relating 576 // minimum, maximum, visible amount, and value is enforced. 577 setValues(value, visibleAmount, newMinimum, maximum); 578 } 579 580 /** 581 * Gets the maximum value of this scroll bar. 582 * 583 * @return the maximum value of this scroll bar 584 * @see java.awt.Scrollbar#getValue 585 * @see java.awt.Scrollbar#getMinimum 586 */ 587 public int getMaximum() { 588 return maximum; 589 } 590 591 /** 592 * Sets the maximum value of this scroll bar. 593 * <p> 594 * When <code>setMaximum</code> is called, the maximum value 595 * is changed, and other values (including the minimum, the 596 * visible amount, and the current scroll bar value) 597 * are changed to be consistent with the new maximum. 598 * <p> 599 * Normally, a program should change a scroll bar's maximum 600 * value only by calling <code>setValues</code>. 601 * The <code>setValues</code> method simultaneously 602 * and synchronously sets the minimum, maximum, visible amount, 603 * and value properties of a scroll bar, so that they are 604 * mutually consistent. 605 * <p> 606 * Note that setting the maximum value to <code>Integer.MIN_VALUE</code> 607 * will result in the new maximum value being set to 608 * <code>Integer.MIN_VALUE + 1</code>. 609 * 610 * @param newMaximum the new maximum value 611 * for this scroll bar 612 * @see java.awt.Scrollbar#setValues 613 * @see java.awt.Scrollbar#setMinimum 614 * @since 1.1 615 */ 616 public void setMaximum(int newMaximum) { 617 // minimum is checked first in setValues, so we need to 618 // enforce minimum and maximum checks here. 619 if (newMaximum == Integer.MIN_VALUE) { 620 newMaximum = Integer.MIN_VALUE + 1; 621 } 622 623 if (minimum >= newMaximum) { 624 minimum = newMaximum - 1; 625 } 626 627 // Use setValues so that a consistent policy relating 628 // minimum, maximum, visible amount, and value is enforced. 629 setValues(value, visibleAmount, minimum, newMaximum); 630 } 631 632 /** 633 * Gets the visible amount of this scroll bar. 634 * <p> 635 * When a scroll bar is used to select a range of values, 636 * the visible amount is used to represent the range of values 637 * that are currently visible. The size of the scroll bar's 638 * bubble (also called a thumb or scroll box), usually gives a 639 * visual representation of the relationship of the visible 640 * amount to the range of the scroll bar. 641 * Note that depending on platform, the value of the visible amount property 642 * may not be visually indicated by the size of the bubble. 643 * <p> 644 * The scroll bar's bubble may not be displayed when it is not 645 * moveable (e.g. when it takes up the entire length of the 646 * scroll bar's track, or when the scroll bar is disabled). 647 * Whether the bubble is displayed or not will not affect 648 * the value returned by <code>getVisibleAmount</code>. 649 * 650 * @return the visible amount of this scroll bar 651 * @see java.awt.Scrollbar#setVisibleAmount 652 * @since 1.1 653 */ 654 public int getVisibleAmount() { 655 return getVisible(); 656 } 657 658 /** 659 * Returns the visible amount of this scroll bar. 660 * 661 * @return the visible amount of this scroll bar 662 * @deprecated As of JDK version 1.1, 663 * replaced by <code>getVisibleAmount()</code>. 664 */ 665 @Deprecated 666 public int getVisible() { 667 return visibleAmount; 668 } 669 670 /** 671 * Sets the visible amount of this scroll bar. 672 * <p> 673 * When a scroll bar is used to select a range of values, 674 * the visible amount is used to represent the range of values 675 * that are currently visible. The size of the scroll bar's 676 * bubble (also called a thumb or scroll box), usually gives a 677 * visual representation of the relationship of the visible 678 * amount to the range of the scroll bar. 679 * Note that depending on platform, the value of the visible amount property 680 * may not be visually indicated by the size of the bubble. 681 * <p> 682 * The scroll bar's bubble may not be displayed when it is not 683 * moveable (e.g. when it takes up the entire length of the 684 * scroll bar's track, or when the scroll bar is disabled). 685 * Whether the bubble is displayed or not will not affect 686 * the value returned by <code>getVisibleAmount</code>. 687 * <p> 688 * If the visible amount supplied is less than <code>one</code> 689 * or greater than the current <code>maximum - minimum</code>, 690 * then either <code>one</code> or <code>maximum - minimum</code> 691 * is substituted, as appropriate. 692 * <p> 693 * Normally, a program should change a scroll bar's 694 * value only by calling <code>setValues</code>. 695 * The <code>setValues</code> method simultaneously 696 * and synchronously sets the minimum, maximum, visible amount, 697 * and value properties of a scroll bar, so that they are 698 * mutually consistent. 699 * 700 * @param newAmount the new visible amount 701 * @see java.awt.Scrollbar#getVisibleAmount 702 * @see java.awt.Scrollbar#setValues 703 * @since 1.1 704 */ 705 public void setVisibleAmount(int newAmount) { 706 // Use setValues so that a consistent policy relating 707 // minimum, maximum, visible amount, and value is enforced. 708 setValues(value, newAmount, minimum, maximum); 709 } 710 711 /** 712 * Sets the unit increment for this scroll bar. 713 * <p> 714 * The unit increment is the value that is added or subtracted 715 * when the user activates the unit increment area of the 716 * scroll bar, generally through a mouse or keyboard gesture 717 * that the scroll bar receives as an adjustment event. 718 * The unit increment must be greater than zero. 719 * Attempts to set the unit increment to a value lower than 1 720 * will result in a value of 1 being set. 721 * <p> 722 * In some operating systems, this property 723 * can be ignored by the underlying controls. 724 * 725 * @param v the amount by which to increment or decrement 726 * the scroll bar's value 727 * @see java.awt.Scrollbar#getUnitIncrement 728 * @since 1.1 729 */ 730 public void setUnitIncrement(int v) { 731 setLineIncrement(v); 732 } 733 734 /** 735 * Sets the unit increment for this scroll bar. 736 * 737 * @param v the increment value 738 * 739 * @deprecated As of JDK version 1.1, 740 * replaced by <code>setUnitIncrement(int)</code>. 741 */ 742 @Deprecated 743 public synchronized void setLineIncrement(int v) { 744 int tmp = (v < 1) ? 1 : v; 745 746 if (lineIncrement == tmp) { 747 return; 748 } 749 lineIncrement = tmp; 750 751 ScrollbarPeer peer = (ScrollbarPeer)this.peer; 752 if (peer != null) { 753 peer.setLineIncrement(lineIncrement); 754 } 755 } 756 757 /** 758 * Gets the unit increment for this scrollbar. 759 * <p> 760 * The unit increment is the value that is added or subtracted 761 * when the user activates the unit increment area of the 762 * scroll bar, generally through a mouse or keyboard gesture 763 * that the scroll bar receives as an adjustment event. 764 * The unit increment must be greater than zero. 765 * <p> 766 * In some operating systems, this property 767 * can be ignored by the underlying controls. 768 * 769 * @return the unit increment of this scroll bar 770 * @see java.awt.Scrollbar#setUnitIncrement 771 * @since 1.1 772 */ 773 public int getUnitIncrement() { 774 return getLineIncrement(); 775 } 776 777 /** 778 * Returns the unit increment for this scrollbar. 779 * 780 * @return the unit increment for this scrollbar 781 * @deprecated As of JDK version 1.1, 782 * replaced by <code>getUnitIncrement()</code>. 783 */ 784 @Deprecated 785 public int getLineIncrement() { 786 return lineIncrement; 787 } 788 789 /** 790 * Sets the block increment for this scroll bar. 791 * <p> 792 * The block increment is the value that is added or subtracted 793 * when the user activates the block increment area of the 794 * scroll bar, generally through a mouse or keyboard gesture 795 * that the scroll bar receives as an adjustment event. 796 * The block increment must be greater than zero. 797 * Attempts to set the block increment to a value lower than 1 798 * will result in a value of 1 being set. 799 * 800 * @param v the amount by which to increment or decrement 801 * the scroll bar's value 802 * @see java.awt.Scrollbar#getBlockIncrement 803 * @since 1.1 804 */ 805 public void setBlockIncrement(int v) { 806 setPageIncrement(v); 807 } 808 809 /** 810 * Sets the block increment for this scroll bar. 811 * 812 * @param v the block increment 813 * @deprecated As of JDK version 1.1, 814 * replaced by <code>setBlockIncrement()</code>. 815 */ 816 @Deprecated 817 public synchronized void setPageIncrement(int v) { 818 int tmp = (v < 1) ? 1 : v; 819 820 if (pageIncrement == tmp) { 821 return; 822 } 823 pageIncrement = tmp; 824 825 ScrollbarPeer peer = (ScrollbarPeer)this.peer; 826 if (peer != null) { 827 peer.setPageIncrement(pageIncrement); 828 } 829 } 830 831 /** 832 * Gets the block increment of this scroll bar. 833 * <p> 834 * The block increment is the value that is added or subtracted 835 * when the user activates the block increment area of the 836 * scroll bar, generally through a mouse or keyboard gesture 837 * that the scroll bar receives as an adjustment event. 838 * The block increment must be greater than zero. 839 * 840 * @return the block increment of this scroll bar 841 * @see java.awt.Scrollbar#setBlockIncrement 842 * @since 1.1 843 */ 844 public int getBlockIncrement() { 845 return getPageIncrement(); 846 } 847 848 /** 849 * Returns the block increment of this scroll bar. 850 * 851 * @return the block increment of this scroll bar 852 * 853 * @deprecated As of JDK version 1.1, 854 * replaced by <code>getBlockIncrement()</code>. 855 */ 856 @Deprecated 857 public int getPageIncrement() { 858 return pageIncrement; 859 } 860 861 /** 862 * Sets the values of four properties for this scroll bar: 863 * <code>value</code>, <code>visibleAmount</code>, 864 * <code>minimum</code>, and <code>maximum</code>. 865 * If the values supplied for these properties are inconsistent 866 * or incorrect, they will be changed to ensure consistency. 867 * <p> 868 * This method simultaneously and synchronously sets the values 869 * of four scroll bar properties, assuring that the values of 870 * these properties are mutually consistent. It enforces the 871 * following constraints: 872 * <code>maximum</code> must be greater than <code>minimum</code>, 873 * <code>maximum - minimum</code> must not be greater 874 * than <code>Integer.MAX_VALUE</code>, 875 * <code>visibleAmount</code> must be greater than zero. 876 * <code>visibleAmount</code> must not be greater than 877 * <code>maximum - minimum</code>, 878 * <code>value</code> must not be less than <code>minimum</code>, 879 * and <code>value</code> must not be greater than 880 * <code>maximum - visibleAmount</code> 881 * <p> 882 * Calling this method does not fire an 883 * <code>AdjustmentEvent</code>. 884 * 885 * @param value is the position in the current window 886 * @param visible is the visible amount of the scroll bar 887 * @param minimum is the minimum value of the scroll bar 888 * @param maximum is the maximum value of the scroll bar 889 * @see #setMinimum 890 * @see #setMaximum 891 * @see #setVisibleAmount 892 * @see #setValue 893 */ 894 public void setValues(int value, int visible, int minimum, int maximum) { 895 int oldValue; 896 synchronized (this) { 897 if (minimum == Integer.MAX_VALUE) { 898 minimum = Integer.MAX_VALUE - 1; 899 } 900 if (maximum <= minimum) { 901 maximum = minimum + 1; 902 } 903 904 long maxMinusMin = (long) maximum - (long) minimum; 905 if (maxMinusMin > Integer.MAX_VALUE) { 906 maxMinusMin = Integer.MAX_VALUE; 907 maximum = minimum + (int) maxMinusMin; 908 } 909 if (visible > (int) maxMinusMin) { 910 visible = (int) maxMinusMin; 911 } 912 if (visible < 1) { 913 visible = 1; 914 } 915 916 if (value < minimum) { 917 value = minimum; 918 } 919 if (value > maximum - visible) { 920 value = maximum - visible; 921 } 922 923 oldValue = this.value; 924 this.value = value; 925 this.visibleAmount = visible; 926 this.minimum = minimum; 927 this.maximum = maximum; 928 ScrollbarPeer peer = (ScrollbarPeer)this.peer; 929 if (peer != null) { 930 peer.setValues(value, visibleAmount, minimum, maximum); 931 } 932 } 933 934 if ((oldValue != value) && (accessibleContext != null)) { 935 accessibleContext.firePropertyChange( 936 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, 937 Integer.valueOf(oldValue), 938 Integer.valueOf(value)); 939 } 940 } 941 942 /** 943 * Returns true if the value is in the process of changing as a 944 * result of actions being taken by the user. 945 * 946 * @return the value of the <code>valueIsAdjusting</code> property 947 * @see #setValueIsAdjusting 948 * @since 1.4 949 */ 950 public boolean getValueIsAdjusting() { 951 return isAdjusting; 952 } 953 954 /** 955 * Sets the <code>valueIsAdjusting</code> property. 956 * 957 * @param b new adjustment-in-progress status 958 * @see #getValueIsAdjusting 959 * @since 1.4 960 */ 961 public void setValueIsAdjusting(boolean b) { 962 boolean oldValue; 963 964 synchronized (this) { 965 oldValue = isAdjusting; 966 isAdjusting = b; 967 } 968 969 if ((oldValue != b) && (accessibleContext != null)) { 970 accessibleContext.firePropertyChange( 971 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 972 ((oldValue) ? AccessibleState.BUSY : null), 973 ((b) ? AccessibleState.BUSY : null)); 974 } 975 } 976 977 978 979 /** 980 * Adds the specified adjustment listener to receive instances of 981 * <code>AdjustmentEvent</code> from this scroll bar. 982 * If l is <code>null</code>, no exception is thrown and no 983 * action is performed. 984 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 985 * >AWT Threading Issues</a> for details on AWT's threading model. 986 * 987 * @param l the adjustment listener 988 * @see #removeAdjustmentListener 989 * @see #getAdjustmentListeners 990 * @see java.awt.event.AdjustmentEvent 991 * @see java.awt.event.AdjustmentListener 992 * @since 1.1 993 */ 994 public synchronized void addAdjustmentListener(AdjustmentListener l) { 995 if (l == null) { 996 return; 997 } 998 adjustmentListener = AWTEventMulticaster.add(adjustmentListener, l); 999 newEventsOnly = true; 1000 } 1001 1002 /** 1003 * Removes the specified adjustment listener so that it no longer 1004 * receives instances of <code>AdjustmentEvent</code> from this scroll bar. 1005 * If l is <code>null</code>, no exception is thrown and no action 1006 * is performed. 1007 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 1008 * >AWT Threading Issues</a> for details on AWT's threading model. 1009 * 1010 * @param l the adjustment listener 1011 * @see #addAdjustmentListener 1012 * @see #getAdjustmentListeners 1013 * @see java.awt.event.AdjustmentEvent 1014 * @see java.awt.event.AdjustmentListener 1015 * @since 1.1 1016 */ 1017 public synchronized void removeAdjustmentListener(AdjustmentListener l) { 1018 if (l == null) { 1019 return; 1020 } 1021 adjustmentListener = AWTEventMulticaster.remove(adjustmentListener, l); 1022 } 1023 1024 /** 1025 * Returns an array of all the adjustment listeners 1026 * registered on this scrollbar. 1027 * 1028 * @return all of this scrollbar's <code>AdjustmentListener</code>s 1029 * or an empty array if no adjustment 1030 * listeners are currently registered 1031 * @see #addAdjustmentListener 1032 * @see #removeAdjustmentListener 1033 * @see java.awt.event.AdjustmentEvent 1034 * @see java.awt.event.AdjustmentListener 1035 * @since 1.4 1036 */ 1037 public synchronized AdjustmentListener[] getAdjustmentListeners() { 1038 return getListeners(AdjustmentListener.class); 1039 } 1040 1041 /** 1042 * Returns an array of all the objects currently registered 1043 * as <code><em>Foo</em>Listener</code>s 1044 * upon this <code>Scrollbar</code>. 1045 * <code><em>Foo</em>Listener</code>s are registered using the 1046 * <code>add<em>Foo</em>Listener</code> method. 1047 * <p> 1048 * You can specify the <code>listenerType</code> argument 1049 * with a class literal, such as 1050 * <code><em>Foo</em>Listener.class</code>. 1051 * For example, you can query a 1052 * <code>Scrollbar</code> <code>c</code> 1053 * for its mouse listeners with the following code: 1054 * 1055 * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre> 1056 * 1057 * If no such listeners exist, this method returns an empty array. 1058 * 1059 * @param listenerType the type of listeners requested; this parameter 1060 * should specify an interface that descends from 1061 * <code>java.util.EventListener</code> 1062 * @return an array of all objects registered as 1063 * <code><em>Foo</em>Listener</code>s on this component, 1064 * or an empty array if no such listeners have been added 1065 * @exception ClassCastException if <code>listenerType</code> 1066 * doesn't specify a class or interface that implements 1067 * <code>java.util.EventListener</code> 1068 * 1069 * @since 1.3 1070 */ 1071 public <T extends EventListener> T[] getListeners(Class<T> listenerType) { 1072 EventListener l = null; 1073 if (listenerType == AdjustmentListener.class) { 1074 l = adjustmentListener; 1075 } else { 1076 return super.getListeners(listenerType); 1077 } 1078 return AWTEventMulticaster.getListeners(l, listenerType); 1079 } 1080 1081 // REMIND: remove when filtering is done at lower level 1082 boolean eventEnabled(AWTEvent e) { 1083 if (e.id == AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED) { 1084 if ((eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0 || 1085 adjustmentListener != null) { 1086 return true; 1087 } 1088 return false; 1089 } 1090 return super.eventEnabled(e); 1091 } 1092 1093 /** 1094 * Processes events on this scroll bar. If the event is an 1095 * instance of <code>AdjustmentEvent</code>, it invokes the 1096 * <code>processAdjustmentEvent</code> method. 1097 * Otherwise, it invokes its superclass's 1098 * <code>processEvent</code> method. 1099 * <p>Note that if the event parameter is <code>null</code> 1100 * the behavior is unspecified and may result in an 1101 * exception. 1102 * 1103 * @param e the event 1104 * @see java.awt.event.AdjustmentEvent 1105 * @see java.awt.Scrollbar#processAdjustmentEvent 1106 * @since 1.1 1107 */ 1108 protected void processEvent(AWTEvent e) { 1109 if (e instanceof AdjustmentEvent) { 1110 processAdjustmentEvent((AdjustmentEvent)e); 1111 return; 1112 } 1113 super.processEvent(e); 1114 } 1115 1116 /** 1117 * Processes adjustment events occurring on this 1118 * scrollbar by dispatching them to any registered 1119 * <code>AdjustmentListener</code> objects. 1120 * <p> 1121 * This method is not called unless adjustment events are 1122 * enabled for this component. Adjustment events are enabled 1123 * when one of the following occurs: 1124 * <ul> 1125 * <li>An <code>AdjustmentListener</code> object is registered 1126 * via <code>addAdjustmentListener</code>. 1127 * <li>Adjustment events are enabled via <code>enableEvents</code>. 1128 * </ul> 1129 * <p>Note that if the event parameter is <code>null</code> 1130 * the behavior is unspecified and may result in an 1131 * exception. 1132 * 1133 * @param e the adjustment event 1134 * @see java.awt.event.AdjustmentEvent 1135 * @see java.awt.event.AdjustmentListener 1136 * @see java.awt.Scrollbar#addAdjustmentListener 1137 * @see java.awt.Component#enableEvents 1138 * @since 1.1 1139 */ 1140 protected void processAdjustmentEvent(AdjustmentEvent e) { 1141 AdjustmentListener listener = adjustmentListener; 1142 if (listener != null) { 1143 listener.adjustmentValueChanged(e); 1144 } 1145 } 1146 1147 /** 1148 * Returns a string representing the state of this <code>Scrollbar</code>. 1149 * This method is intended to be used only for debugging purposes, and the 1150 * content and format of the returned string may vary between 1151 * implementations. The returned string may be empty but may not be 1152 * <code>null</code>. 1153 * 1154 * @return the parameter string of this scroll bar 1155 */ 1156 protected String paramString() { 1157 return super.paramString() + 1158 ",val=" + value + 1159 ",vis=" + visibleAmount + 1160 ",min=" + minimum + 1161 ",max=" + maximum + 1162 ((orientation == VERTICAL) ? ",vert" : ",horz") + 1163 ",isAdjusting=" + isAdjusting; 1164 } 1165 1166 1167 /* Serialization support. 1168 */ 1169 1170 /** 1171 * The scroll bar's serialized Data Version. 1172 * 1173 * @serial 1174 */ 1175 private int scrollbarSerializedDataVersion = 1; 1176 1177 /** 1178 * Writes default serializable fields to stream. Writes 1179 * a list of serializable <code>AdjustmentListeners</code> 1180 * as optional data. The non-serializable listeners are 1181 * detected and no attempt is made to serialize them. 1182 * 1183 * @param s the <code>ObjectOutputStream</code> to write 1184 * @serialData <code>null</code> terminated sequence of 0 1185 * or more pairs; the pair consists of a <code>String</code> 1186 * and an <code>Object</code>; the <code>String</code> indicates 1187 * the type of object and is one of the following: 1188 * <code>adjustmentListenerK</code> indicating an 1189 * <code>AdjustmentListener</code> object 1190 * 1191 * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener) 1192 * @see java.awt.Component#adjustmentListenerK 1193 * @see #readObject(ObjectInputStream) 1194 */ 1195 private void writeObject(ObjectOutputStream s) 1196 throws IOException 1197 { 1198 s.defaultWriteObject(); 1199 1200 AWTEventMulticaster.save(s, adjustmentListenerK, adjustmentListener); 1201 s.writeObject(null); 1202 } 1203 1204 /** 1205 * Reads the <code>ObjectInputStream</code> and if 1206 * it isn't <code>null</code> adds a listener to 1207 * receive adjustment events fired by the 1208 * <code>Scrollbar</code>. 1209 * Unrecognized keys or values will be ignored. 1210 * 1211 * @param s the <code>ObjectInputStream</code> to read 1212 * @exception HeadlessException if 1213 * <code>GraphicsEnvironment.isHeadless</code> returns 1214 * <code>true</code> 1215 * @see java.awt.GraphicsEnvironment#isHeadless 1216 * @see #writeObject(ObjectOutputStream) 1217 */ 1218 private void readObject(ObjectInputStream s) 1219 throws ClassNotFoundException, IOException, HeadlessException 1220 { 1221 GraphicsEnvironment.checkHeadless(); 1222 s.defaultReadObject(); 1223 1224 Object keyOrNull; 1225 while(null != (keyOrNull = s.readObject())) { 1226 String key = ((String)keyOrNull).intern(); 1227 1228 if (adjustmentListenerK == key) 1229 addAdjustmentListener((AdjustmentListener)(s.readObject())); 1230 1231 else // skip value for unrecognized key 1232 s.readObject(); 1233 } 1234 } 1235 1236 1237 ///////////////// 1238 // Accessibility support 1239 //////////////// 1240 1241 /** 1242 * Gets the <code>AccessibleContext</code> associated with this 1243 * <code>Scrollbar</code>. For scrollbars, the 1244 * <code>AccessibleContext</code> takes the form of an 1245 * <code>AccessibleAWTScrollBar</code>. A new 1246 * <code>AccessibleAWTScrollBar</code> instance is created if necessary. 1247 * 1248 * @return an <code>AccessibleAWTScrollBar</code> that serves as the 1249 * <code>AccessibleContext</code> of this <code>ScrollBar</code> 1250 * @since 1.3 1251 */ 1252 public AccessibleContext getAccessibleContext() { 1253 if (accessibleContext == null) { 1254 accessibleContext = new AccessibleAWTScrollBar(); 1255 } 1256 return accessibleContext; 1257 } 1258 1259 /** 1260 * This class implements accessibility support for the 1261 * <code>Scrollbar</code> class. It provides an implementation of 1262 * the Java Accessibility API appropriate to scrollbar 1263 * user-interface elements. 1264 * @since 1.3 1265 */ 1266 protected class AccessibleAWTScrollBar extends AccessibleAWTComponent 1267 implements AccessibleValue 1268 { 1269 /* 1270 * JDK 1.3 serialVersionUID 1271 */ 1272 private static final long serialVersionUID = -344337268523697807L; 1273 1274 /** 1275 * Get the state set of this object. 1276 * 1277 * @return an instance of <code>AccessibleState</code> 1278 * containing the current state of the object 1279 * @see AccessibleState 1280 */ 1281 public AccessibleStateSet getAccessibleStateSet() { 1282 AccessibleStateSet states = super.getAccessibleStateSet(); 1283 if (getValueIsAdjusting()) { 1284 states.add(AccessibleState.BUSY); 1285 } 1286 if (getOrientation() == VERTICAL) { 1287 states.add(AccessibleState.VERTICAL); 1288 } else { 1289 states.add(AccessibleState.HORIZONTAL); 1290 } 1291 return states; 1292 } 1293 1294 /** 1295 * Get the role of this object. 1296 * 1297 * @return an instance of <code>AccessibleRole</code> 1298 * describing the role of the object 1299 */ 1300 public AccessibleRole getAccessibleRole() { 1301 return AccessibleRole.SCROLL_BAR; 1302 } 1303 1304 /** 1305 * Get the <code>AccessibleValue</code> associated with this 1306 * object. In the implementation of the Java Accessibility 1307 * API for this class, return this object, which is 1308 * responsible for implementing the 1309 * <code>AccessibleValue</code> interface on behalf of itself. 1310 * 1311 * @return this object 1312 */ 1313 public AccessibleValue getAccessibleValue() { 1314 return this; 1315 } 1316 1317 /** 1318 * Get the accessible value of this object. 1319 * 1320 * @return The current value of this object. 1321 */ 1322 public Number getCurrentAccessibleValue() { 1323 return Integer.valueOf(getValue()); 1324 } 1325 1326 /** 1327 * Set the value of this object as a Number. 1328 * 1329 * @return True if the value was set. 1330 */ 1331 public boolean setCurrentAccessibleValue(Number n) { 1332 if (n instanceof Integer) { 1333 setValue(n.intValue()); 1334 return true; 1335 } else { 1336 return false; 1337 } 1338 } 1339 1340 /** 1341 * Get the minimum accessible value of this object. 1342 * 1343 * @return The minimum value of this object. 1344 */ 1345 public Number getMinimumAccessibleValue() { 1346 return Integer.valueOf(getMinimum()); 1347 } 1348 1349 /** 1350 * Get the maximum accessible value of this object. 1351 * 1352 * @return The maximum value of this object. 1353 */ 1354 public Number getMaximumAccessibleValue() { 1355 return Integer.valueOf(getMaximum()); 1356 } 1357 1358 } // AccessibleAWTScrollBar 1359 1360 }