1 /* 2 * Copyright (c) 1995, 2017, 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} 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} minus the {@code visible amount}. 76 * In the previous example, because the {@code maximum} is 77 * 300 and the {@code visible amount} 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}. 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}, an interface defined in 99 * the package {@code java.awt.event}. 100 * Listeners can be added and removed dynamically by calling 101 * the methods {@code addAdjustmentListener} and 102 * {@code removeAdjustmentListener}. 103 * <p> 104 * The {@code AdjustmentEvent} class defines five types 105 * of adjustment event, listed here: 106 * 107 * <ul> 108 * <li>{@code AdjustmentEvent.TRACK} is sent out when the 109 * user drags the scroll bar's bubble. 110 * <li>{@code AdjustmentEvent.UNIT_INCREMENT} 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} 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} 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} 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} replaces 142 * {@code Event.SCROLL_ABSOLUTE} 143 * <li>{@code AdjustmentEvent.UNIT_INCREMENT} replaces 144 * {@code Event.SCROLL_LINE_UP} 145 * <li>{@code AdjustmentEvent.UNIT_DECREMENT} replaces 146 * {@code Event.SCROLL_LINE_DOWN} 147 * <li>{@code AdjustmentEvent.BLOCK_INCREMENT} replaces 148 * {@code Event.SCROLL_PAGE_UP} 149 * <li>{@code AdjustmentEvent.BLOCK_DECREMENT} replaces 150 * {@code Event.SCROLL_PAGE_DOWN} 151 * </ul> 152 * <p> 153 * <b>Note</b>: We recommend using a {@code Scrollbar} 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} 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}. 180 * This property must be greater than or equal to {@code minimum} 181 * and less than or equal to 182 * {@code maximum - visibleAmount} 183 * 184 * @serial 185 * @see #getValue 186 * @see #setValue 187 */ 188 int value; 189 190 /** 191 * The maximum value of the {@code Scrollbar}. 192 * This value must be greater than the {@code minimum} 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}. 203 * This value must be less than the {@code maximum} 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}'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}'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} or 230 * {@code HORIZONTAL} 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}. 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 class="striped"> 300 * <caption>Scrollbar default properties</caption> 301 * <thead> 302 * <tr> 303 * <th>Property</th> 304 * <th>Description</th> 305 * <th>Default Value</th> 306 * </tr> 307 * </thead> 308 * <tbody> 309 * <tr> 310 * <td>orientation</td> 311 * <td>indicates whether the scroll bar is vertical 312 * <br>or horizontal</td> 313 * <td>{@code Scrollbar.VERTICAL}</td> 314 * </tr> 315 * <tr> 316 * <td>value</td> 317 * <td>value which controls the location 318 * <br>of the scroll bar's bubble</td> 319 * <td>0</td> 320 * </tr> 321 * <tr> 322 * <td>visible amount</td> 323 * <td>visible amount of the scroll bar's range, 324 * <br>typically represented by the size of the 325 * <br>scroll bar's bubble</td> 326 * <td>10</td> 327 * </tr> 328 * <tr> 329 * <td>minimum</td> 330 * <td>minimum value of the scroll bar</td> 331 * <td>0</td> 332 * </tr> 333 * <tr> 334 * <td>maximum</td> 335 * <td>maximum value of the scroll bar</td> 336 * <td>100</td> 337 * </tr> 338 * <tr> 339 * <td>unit increment</td> 340 * <td>amount the value changes when the 341 * <br>Line Up or Line Down key is pressed, 342 * <br>or when the end arrows of the scrollbar 343 * <br>are clicked </td> 344 * <td>1</td> 345 * </tr> 346 * <tr> 347 * <td>block increment</td> 348 * <td>amount the value changes when the 349 * <br>Page Up or Page Down key is pressed, 350 * <br>or when the scrollbar track is clicked 351 * <br>on either side of the bubble </td> 352 * <td>10</td> 353 * </tr> 354 * </tbody> 355 * </table> 356 * 357 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 358 * returns true. 359 * @see java.awt.GraphicsEnvironment#isHeadless 360 */ 361 public Scrollbar() throws HeadlessException { 362 this(VERTICAL, 0, 10, 0, 100); 363 } 364 365 /** 366 * Constructs a new scroll bar with the specified orientation. 367 * <p> 368 * The {@code orientation} argument must take one of the two 369 * values {@code Scrollbar.HORIZONTAL}, 370 * or {@code Scrollbar.VERTICAL}, 371 * indicating a horizontal or vertical scroll bar, respectively. 372 * 373 * @param orientation indicates the orientation of the scroll bar 374 * @exception IllegalArgumentException when an illegal value for 375 * the {@code orientation} argument is supplied 376 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 377 * returns true. 378 * @see java.awt.GraphicsEnvironment#isHeadless 379 */ 380 public Scrollbar(int orientation) throws HeadlessException { 381 this(orientation, 0, 10, 0, 100); 382 } 383 384 /** 385 * Constructs a new scroll bar with the specified orientation, 386 * initial value, visible amount, and minimum and maximum values. 387 * <p> 388 * The {@code orientation} argument must take one of the two 389 * values {@code Scrollbar.HORIZONTAL}, 390 * or {@code Scrollbar.VERTICAL}, 391 * indicating a horizontal or vertical scroll bar, respectively. 392 * <p> 393 * The parameters supplied to this constructor are subject to the 394 * constraints described in {@link #setValues(int, int, int, int)}. 395 * 396 * @param orientation indicates the orientation of the scroll bar. 397 * @param value the initial value of the scroll bar 398 * @param visible the visible amount of the scroll bar, typically 399 * represented by the size of the bubble 400 * @param minimum the minimum value of the scroll bar 401 * @param maximum the maximum value of the scroll bar 402 * @exception IllegalArgumentException when an illegal value for 403 * the {@code orientation} argument is supplied 404 * @exception HeadlessException if GraphicsEnvironment.isHeadless() 405 * returns true. 406 * @see #setValues 407 * @see java.awt.GraphicsEnvironment#isHeadless 408 */ 409 public Scrollbar(int orientation, int value, int visible, int minimum, 410 int maximum) throws HeadlessException { 411 GraphicsEnvironment.checkHeadless(); 412 switch (orientation) { 413 case HORIZONTAL: 414 case VERTICAL: 415 this.orientation = orientation; 416 break; 417 default: 418 throw new IllegalArgumentException("illegal scrollbar orientation"); 419 } 420 setValues(value, visible, minimum, maximum); 421 } 422 423 /** 424 * Constructs a name for this component. Called by {@code getName} 425 * when the name is {@code null}. 426 */ 427 String constructComponentName() { 428 synchronized (Scrollbar.class) { 429 return base + nameCounter++; 430 } 431 } 432 433 /** 434 * Creates the {@code Scrollbar}'s peer. The peer allows you to modify 435 * the appearance of the {@code Scrollbar} without changing any of its 436 * functionality. 437 */ 438 public void addNotify() { 439 synchronized (getTreeLock()) { 440 if (peer == null) 441 peer = getComponentFactory().createScrollbar(this); 442 super.addNotify(); 443 } 444 } 445 446 /** 447 * Returns the orientation of this scroll bar. 448 * 449 * @return the orientation of this scroll bar, either 450 * {@code Scrollbar.HORIZONTAL} or 451 * {@code Scrollbar.VERTICAL} 452 * @see java.awt.Scrollbar#setOrientation 453 */ 454 public int getOrientation() { 455 return orientation; 456 } 457 458 /** 459 * Sets the orientation for this scroll bar. 460 * 461 * @param orientation the orientation of this scroll bar, either 462 * {@code Scrollbar.HORIZONTAL} or 463 * {@code Scrollbar.VERTICAL} 464 * @see java.awt.Scrollbar#getOrientation 465 * @exception IllegalArgumentException if the value supplied 466 * for {@code orientation} is not a 467 * legal value 468 * @since 1.1 469 */ 470 public void setOrientation(int orientation) { 471 synchronized (getTreeLock()) { 472 if (orientation == this.orientation) { 473 return; 474 } 475 switch (orientation) { 476 case HORIZONTAL: 477 case VERTICAL: 478 this.orientation = orientation; 479 break; 480 default: 481 throw new IllegalArgumentException("illegal scrollbar orientation"); 482 } 483 /* Create a new peer with the specified orientation. */ 484 if (peer != null) { 485 removeNotify(); 486 addNotify(); 487 invalidate(); 488 } 489 } 490 if (accessibleContext != null) { 491 accessibleContext.firePropertyChange( 492 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 493 ((orientation == VERTICAL) 494 ? AccessibleState.HORIZONTAL : AccessibleState.VERTICAL), 495 ((orientation == VERTICAL) 496 ? AccessibleState.VERTICAL : AccessibleState.HORIZONTAL)); 497 } 498 } 499 500 /** 501 * Gets the current value of this scroll bar. 502 * 503 * @return the current value of this scroll bar 504 * @see java.awt.Scrollbar#getMinimum 505 * @see java.awt.Scrollbar#getMaximum 506 */ 507 public int getValue() { 508 return value; 509 } 510 511 /** 512 * Sets the value of this scroll bar to the specified value. 513 * <p> 514 * If the value supplied is less than the current {@code minimum} 515 * or greater than the current {@code maximum - visibleAmount}, 516 * then either {@code minimum} or {@code maximum - visibleAmount} 517 * is substituted, as appropriate. 518 * <p> 519 * Normally, a program should change a scroll bar's 520 * value only by calling {@code setValues}. 521 * The {@code setValues} method simultaneously 522 * and synchronously sets the minimum, maximum, visible amount, 523 * and value properties of a scroll bar, so that they are 524 * mutually consistent. 525 * <p> 526 * Calling this method does not fire an 527 * {@code AdjustmentEvent}. 528 * 529 * @param newValue the new value of the scroll bar 530 * @see java.awt.Scrollbar#setValues 531 * @see java.awt.Scrollbar#getValue 532 * @see java.awt.Scrollbar#getMinimum 533 * @see java.awt.Scrollbar#getMaximum 534 */ 535 public void setValue(int newValue) { 536 // Use setValues so that a consistent policy relating 537 // minimum, maximum, visible amount, and value is enforced. 538 setValues(newValue, visibleAmount, minimum, maximum); 539 } 540 541 /** 542 * Gets the minimum value of this scroll bar. 543 * 544 * @return the minimum value of this scroll bar 545 * @see java.awt.Scrollbar#getValue 546 * @see java.awt.Scrollbar#getMaximum 547 */ 548 public int getMinimum() { 549 return minimum; 550 } 551 552 /** 553 * Sets the minimum value of this scroll bar. 554 * <p> 555 * When {@code setMinimum} is called, the minimum value 556 * is changed, and other values (including the maximum, the 557 * visible amount, and the current scroll bar value) 558 * are changed to be consistent with the new minimum. 559 * <p> 560 * Normally, a program should change a scroll bar's minimum 561 * value only by calling {@code setValues}. 562 * The {@code setValues} method simultaneously 563 * and synchronously sets the minimum, maximum, visible amount, 564 * and value properties of a scroll bar, so that they are 565 * mutually consistent. 566 * <p> 567 * Note that setting the minimum value to {@code Integer.MAX_VALUE} 568 * will result in the new minimum value being set to 569 * {@code Integer.MAX_VALUE - 1}. 570 * 571 * @param newMinimum the new minimum value for this scroll bar 572 * @see java.awt.Scrollbar#setValues 573 * @see java.awt.Scrollbar#setMaximum 574 * @since 1.1 575 */ 576 public void setMinimum(int newMinimum) { 577 // No checks are necessary in this method since minimum is 578 // the first variable checked in the setValues function. 579 580 // Use setValues so that a consistent policy relating 581 // minimum, maximum, visible amount, and value is enforced. 582 setValues(value, visibleAmount, newMinimum, maximum); 583 } 584 585 /** 586 * Gets the maximum value of this scroll bar. 587 * 588 * @return the maximum value of this scroll bar 589 * @see java.awt.Scrollbar#getValue 590 * @see java.awt.Scrollbar#getMinimum 591 */ 592 public int getMaximum() { 593 return maximum; 594 } 595 596 /** 597 * Sets the maximum value of this scroll bar. 598 * <p> 599 * When {@code setMaximum} is called, the maximum value 600 * is changed, and other values (including the minimum, the 601 * visible amount, and the current scroll bar value) 602 * are changed to be consistent with the new maximum. 603 * <p> 604 * Normally, a program should change a scroll bar's maximum 605 * value only by calling {@code setValues}. 606 * The {@code setValues} method simultaneously 607 * and synchronously sets the minimum, maximum, visible amount, 608 * and value properties of a scroll bar, so that they are 609 * mutually consistent. 610 * <p> 611 * Note that setting the maximum value to {@code Integer.MIN_VALUE} 612 * will result in the new maximum value being set to 613 * {@code Integer.MIN_VALUE + 1}. 614 * 615 * @param newMaximum the new maximum value 616 * for this scroll bar 617 * @see java.awt.Scrollbar#setValues 618 * @see java.awt.Scrollbar#setMinimum 619 * @since 1.1 620 */ 621 public void setMaximum(int newMaximum) { 622 // minimum is checked first in setValues, so we need to 623 // enforce minimum and maximum checks here. 624 if (newMaximum == Integer.MIN_VALUE) { 625 newMaximum = Integer.MIN_VALUE + 1; 626 } 627 628 if (minimum >= newMaximum) { 629 minimum = newMaximum - 1; 630 } 631 632 // Use setValues so that a consistent policy relating 633 // minimum, maximum, visible amount, and value is enforced. 634 setValues(value, visibleAmount, minimum, newMaximum); 635 } 636 637 /** 638 * Gets the visible amount of this scroll bar. 639 * <p> 640 * When a scroll bar is used to select a range of values, 641 * the visible amount is used to represent the range of values 642 * that are currently visible. The size of the scroll bar's 643 * bubble (also called a thumb or scroll box), usually gives a 644 * visual representation of the relationship of the visible 645 * amount to the range of the scroll bar. 646 * Note that depending on platform, the value of the visible amount property 647 * may not be visually indicated by the size of the bubble. 648 * <p> 649 * The scroll bar's bubble may not be displayed when it is not 650 * moveable (e.g. when it takes up the entire length of the 651 * scroll bar's track, or when the scroll bar is disabled). 652 * Whether the bubble is displayed or not will not affect 653 * the value returned by {@code getVisibleAmount}. 654 * 655 * @return the visible amount of this scroll bar 656 * @see java.awt.Scrollbar#setVisibleAmount 657 * @since 1.1 658 */ 659 public int getVisibleAmount() { 660 return getVisible(); 661 } 662 663 /** 664 * Returns the visible amount of this scroll bar. 665 * 666 * @return the visible amount of this scroll bar 667 * @deprecated As of JDK version 1.1, 668 * replaced by {@code getVisibleAmount()}. 669 */ 670 @Deprecated 671 public int getVisible() { 672 return visibleAmount; 673 } 674 675 /** 676 * Sets the visible amount of this scroll bar. 677 * <p> 678 * When a scroll bar is used to select a range of values, 679 * the visible amount is used to represent the range of values 680 * that are currently visible. The size of the scroll bar's 681 * bubble (also called a thumb or scroll box), usually gives a 682 * visual representation of the relationship of the visible 683 * amount to the range of the scroll bar. 684 * Note that depending on platform, the value of the visible amount property 685 * may not be visually indicated by the size of the bubble. 686 * <p> 687 * The scroll bar's bubble may not be displayed when it is not 688 * moveable (e.g. when it takes up the entire length of the 689 * scroll bar's track, or when the scroll bar is disabled). 690 * Whether the bubble is displayed or not will not affect 691 * the value returned by {@code getVisibleAmount}. 692 * <p> 693 * If the visible amount supplied is less than {@code one} 694 * or greater than the current {@code maximum - minimum}, 695 * then either {@code one} or {@code maximum - minimum} 696 * is substituted, as appropriate. 697 * <p> 698 * Normally, a program should change a scroll bar's 699 * value only by calling {@code setValues}. 700 * The {@code setValues} method simultaneously 701 * and synchronously sets the minimum, maximum, visible amount, 702 * and value properties of a scroll bar, so that they are 703 * mutually consistent. 704 * 705 * @param newAmount the new visible amount 706 * @see java.awt.Scrollbar#getVisibleAmount 707 * @see java.awt.Scrollbar#setValues 708 * @since 1.1 709 */ 710 public void setVisibleAmount(int newAmount) { 711 // Use setValues so that a consistent policy relating 712 // minimum, maximum, visible amount, and value is enforced. 713 setValues(value, newAmount, minimum, maximum); 714 } 715 716 /** 717 * Sets the unit increment for this scroll bar. 718 * <p> 719 * The unit increment is the value that is added or subtracted 720 * when the user activates the unit increment area of the 721 * scroll bar, generally through a mouse or keyboard gesture 722 * that the scroll bar receives as an adjustment event. 723 * The unit increment must be greater than zero. 724 * Attempts to set the unit increment to a value lower than 1 725 * will result in a value of 1 being set. 726 * <p> 727 * In some operating systems, this property 728 * can be ignored by the underlying controls. 729 * 730 * @param v the amount by which to increment or decrement 731 * the scroll bar's value 732 * @see java.awt.Scrollbar#getUnitIncrement 733 * @since 1.1 734 */ 735 public void setUnitIncrement(int v) { 736 setLineIncrement(v); 737 } 738 739 /** 740 * Sets the unit increment for this scroll bar. 741 * 742 * @param v the increment value 743 * 744 * @deprecated As of JDK version 1.1, 745 * replaced by {@code setUnitIncrement(int)}. 746 */ 747 @Deprecated 748 public synchronized void setLineIncrement(int v) { 749 int tmp = (v < 1) ? 1 : v; 750 751 if (lineIncrement == tmp) { 752 return; 753 } 754 lineIncrement = tmp; 755 756 ScrollbarPeer peer = (ScrollbarPeer)this.peer; 757 if (peer != null) { 758 peer.setLineIncrement(lineIncrement); 759 } 760 } 761 762 /** 763 * Gets the unit increment for this scrollbar. 764 * <p> 765 * The unit increment is the value that is added or subtracted 766 * when the user activates the unit increment area of the 767 * scroll bar, generally through a mouse or keyboard gesture 768 * that the scroll bar receives as an adjustment event. 769 * The unit increment must be greater than zero. 770 * <p> 771 * In some operating systems, this property 772 * can be ignored by the underlying controls. 773 * 774 * @return the unit increment of this scroll bar 775 * @see java.awt.Scrollbar#setUnitIncrement 776 * @since 1.1 777 */ 778 public int getUnitIncrement() { 779 return getLineIncrement(); 780 } 781 782 /** 783 * Returns the unit increment for this scrollbar. 784 * 785 * @return the unit increment for this scrollbar 786 * @deprecated As of JDK version 1.1, 787 * replaced by {@code getUnitIncrement()}. 788 */ 789 @Deprecated 790 public int getLineIncrement() { 791 return lineIncrement; 792 } 793 794 /** 795 * Sets the block increment for this scroll bar. 796 * <p> 797 * The block increment is the value that is added or subtracted 798 * when the user activates the block increment area of the 799 * scroll bar, generally through a mouse or keyboard gesture 800 * that the scroll bar receives as an adjustment event. 801 * The block increment must be greater than zero. 802 * Attempts to set the block increment to a value lower than 1 803 * will result in a value of 1 being set. 804 * 805 * @param v the amount by which to increment or decrement 806 * the scroll bar's value 807 * @see java.awt.Scrollbar#getBlockIncrement 808 * @since 1.1 809 */ 810 public void setBlockIncrement(int v) { 811 setPageIncrement(v); 812 } 813 814 /** 815 * Sets the block increment for this scroll bar. 816 * 817 * @param v the block increment 818 * @deprecated As of JDK version 1.1, 819 * replaced by {@code setBlockIncrement()}. 820 */ 821 @Deprecated 822 public synchronized void setPageIncrement(int v) { 823 int tmp = (v < 1) ? 1 : v; 824 825 if (pageIncrement == tmp) { 826 return; 827 } 828 pageIncrement = tmp; 829 830 ScrollbarPeer peer = (ScrollbarPeer)this.peer; 831 if (peer != null) { 832 peer.setPageIncrement(pageIncrement); 833 } 834 } 835 836 /** 837 * Gets the block increment of this scroll bar. 838 * <p> 839 * The block increment is the value that is added or subtracted 840 * when the user activates the block increment area of the 841 * scroll bar, generally through a mouse or keyboard gesture 842 * that the scroll bar receives as an adjustment event. 843 * The block increment must be greater than zero. 844 * 845 * @return the block increment of this scroll bar 846 * @see java.awt.Scrollbar#setBlockIncrement 847 * @since 1.1 848 */ 849 public int getBlockIncrement() { 850 return getPageIncrement(); 851 } 852 853 /** 854 * Returns the block increment of this scroll bar. 855 * 856 * @return the block increment of this scroll bar 857 * 858 * @deprecated As of JDK version 1.1, 859 * replaced by {@code getBlockIncrement()}. 860 */ 861 @Deprecated 862 public int getPageIncrement() { 863 return pageIncrement; 864 } 865 866 /** 867 * Sets the values of four properties for this scroll bar: 868 * {@code value}, {@code visibleAmount}, 869 * {@code minimum}, and {@code maximum}. 870 * If the values supplied for these properties are inconsistent 871 * or incorrect, they will be changed to ensure consistency. 872 * <p> 873 * This method simultaneously and synchronously sets the values 874 * of four scroll bar properties, assuring that the values of 875 * these properties are mutually consistent. It enforces the 876 * following constraints: 877 * {@code maximum} must be greater than {@code minimum}, 878 * {@code maximum - minimum} must not be greater 879 * than {@code Integer.MAX_VALUE}, 880 * {@code visibleAmount} must be greater than zero. 881 * {@code visibleAmount} must not be greater than 882 * {@code maximum - minimum}, 883 * {@code value} must not be less than {@code minimum}, 884 * and {@code value} must not be greater than 885 * {@code maximum - visibleAmount} 886 * <p> 887 * Calling this method does not fire an 888 * {@code AdjustmentEvent}. 889 * 890 * @param value is the position in the current window 891 * @param visible is the visible amount of the scroll bar 892 * @param minimum is the minimum value of the scroll bar 893 * @param maximum is the maximum value of the scroll bar 894 * @see #setMinimum 895 * @see #setMaximum 896 * @see #setVisibleAmount 897 * @see #setValue 898 */ 899 public void setValues(int value, int visible, int minimum, int maximum) { 900 int oldValue; 901 synchronized (this) { 902 if (minimum == Integer.MAX_VALUE) { 903 minimum = Integer.MAX_VALUE - 1; 904 } 905 if (maximum <= minimum) { 906 maximum = minimum + 1; 907 } 908 909 long maxMinusMin = (long) maximum - (long) minimum; 910 if (maxMinusMin > Integer.MAX_VALUE) { 911 maxMinusMin = Integer.MAX_VALUE; 912 maximum = minimum + (int) maxMinusMin; 913 } 914 if (visible > (int) maxMinusMin) { 915 visible = (int) maxMinusMin; 916 } 917 if (visible < 1) { 918 visible = 1; 919 } 920 921 if (value < minimum) { 922 value = minimum; 923 } 924 if (value > maximum - visible) { 925 value = maximum - visible; 926 } 927 928 oldValue = this.value; 929 this.value = value; 930 this.visibleAmount = visible; 931 this.minimum = minimum; 932 this.maximum = maximum; 933 ScrollbarPeer peer = (ScrollbarPeer)this.peer; 934 if (peer != null) { 935 peer.setValues(value, visibleAmount, minimum, maximum); 936 } 937 } 938 939 if ((oldValue != value) && (accessibleContext != null)) { 940 accessibleContext.firePropertyChange( 941 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, 942 Integer.valueOf(oldValue), 943 Integer.valueOf(value)); 944 } 945 } 946 947 /** 948 * Returns true if the value is in the process of changing as a 949 * result of actions being taken by the user. 950 * 951 * @return the value of the {@code valueIsAdjusting} property 952 * @see #setValueIsAdjusting 953 * @since 1.4 954 */ 955 public boolean getValueIsAdjusting() { 956 return isAdjusting; 957 } 958 959 /** 960 * Sets the {@code valueIsAdjusting} property. 961 * 962 * @param b new adjustment-in-progress status 963 * @see #getValueIsAdjusting 964 * @since 1.4 965 */ 966 public void setValueIsAdjusting(boolean b) { 967 boolean oldValue; 968 969 synchronized (this) { 970 oldValue = isAdjusting; 971 isAdjusting = b; 972 } 973 974 if ((oldValue != b) && (accessibleContext != null)) { 975 accessibleContext.firePropertyChange( 976 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 977 ((oldValue) ? AccessibleState.BUSY : null), 978 ((b) ? AccessibleState.BUSY : null)); 979 } 980 } 981 982 983 984 /** 985 * Adds the specified adjustment listener to receive instances of 986 * {@code AdjustmentEvent} from this scroll bar. 987 * If l is {@code null}, no exception is thrown and no 988 * action is performed. 989 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 990 * >AWT Threading Issues</a> for details on AWT's threading model. 991 * 992 * @param l the adjustment listener 993 * @see #removeAdjustmentListener 994 * @see #getAdjustmentListeners 995 * @see java.awt.event.AdjustmentEvent 996 * @see java.awt.event.AdjustmentListener 997 * @since 1.1 998 */ 999 public synchronized void addAdjustmentListener(AdjustmentListener l) { 1000 if (l == null) { 1001 return; 1002 } 1003 adjustmentListener = AWTEventMulticaster.add(adjustmentListener, l); 1004 newEventsOnly = true; 1005 } 1006 1007 /** 1008 * Removes the specified adjustment listener so that it no longer 1009 * receives instances of {@code AdjustmentEvent} from this scroll bar. 1010 * If l is {@code null}, no exception is thrown and no action 1011 * is performed. 1012 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 1013 * >AWT Threading Issues</a> for details on AWT's threading model. 1014 * 1015 * @param l the adjustment listener 1016 * @see #addAdjustmentListener 1017 * @see #getAdjustmentListeners 1018 * @see java.awt.event.AdjustmentEvent 1019 * @see java.awt.event.AdjustmentListener 1020 * @since 1.1 1021 */ 1022 public synchronized void removeAdjustmentListener(AdjustmentListener l) { 1023 if (l == null) { 1024 return; 1025 } 1026 adjustmentListener = AWTEventMulticaster.remove(adjustmentListener, l); 1027 } 1028 1029 /** 1030 * Returns an array of all the adjustment listeners 1031 * registered on this scrollbar. 1032 * 1033 * @return all of this scrollbar's {@code AdjustmentListener}s 1034 * or an empty array if no adjustment 1035 * listeners are currently registered 1036 * @see #addAdjustmentListener 1037 * @see #removeAdjustmentListener 1038 * @see java.awt.event.AdjustmentEvent 1039 * @see java.awt.event.AdjustmentListener 1040 * @since 1.4 1041 */ 1042 public synchronized AdjustmentListener[] getAdjustmentListeners() { 1043 return getListeners(AdjustmentListener.class); 1044 } 1045 1046 /** 1047 * Returns an array of all the objects currently registered 1048 * as <code><em>Foo</em>Listener</code>s 1049 * upon this {@code Scrollbar}. 1050 * <code><em>Foo</em>Listener</code>s are registered using the 1051 * <code>add<em>Foo</em>Listener</code> method. 1052 * <p> 1053 * You can specify the {@code listenerType} argument 1054 * with a class literal, such as 1055 * <code><em>Foo</em>Listener.class</code>. 1056 * For example, you can query a 1057 * {@code Scrollbar c} 1058 * for its mouse listeners with the following code: 1059 * 1060 * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre> 1061 * 1062 * If no such listeners exist, this method returns an empty array. 1063 * 1064 * @param listenerType the type of listeners requested; this parameter 1065 * should specify an interface that descends from 1066 * {@code java.util.EventListener} 1067 * @return an array of all objects registered as 1068 * <code><em>Foo</em>Listener</code>s on this component, 1069 * or an empty array if no such listeners have been added 1070 * @exception ClassCastException if {@code listenerType} 1071 * doesn't specify a class or interface that implements 1072 * {@code java.util.EventListener} 1073 * 1074 * @since 1.3 1075 */ 1076 public <T extends EventListener> T[] getListeners(Class<T> listenerType) { 1077 EventListener l = null; 1078 if (listenerType == AdjustmentListener.class) { 1079 l = adjustmentListener; 1080 } else { 1081 return super.getListeners(listenerType); 1082 } 1083 return AWTEventMulticaster.getListeners(l, listenerType); 1084 } 1085 1086 // REMIND: remove when filtering is done at lower level 1087 boolean eventEnabled(AWTEvent e) { 1088 if (e.id == AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED) { 1089 if ((eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0 || 1090 adjustmentListener != null) { 1091 return true; 1092 } 1093 return false; 1094 } 1095 return super.eventEnabled(e); 1096 } 1097 1098 /** 1099 * Processes events on this scroll bar. If the event is an 1100 * instance of {@code AdjustmentEvent}, it invokes the 1101 * {@code processAdjustmentEvent} method. 1102 * Otherwise, it invokes its superclass's 1103 * {@code processEvent} method. 1104 * <p>Note that if the event parameter is {@code null} 1105 * the behavior is unspecified and may result in an 1106 * exception. 1107 * 1108 * @param e the event 1109 * @see java.awt.event.AdjustmentEvent 1110 * @see java.awt.Scrollbar#processAdjustmentEvent 1111 * @since 1.1 1112 */ 1113 protected void processEvent(AWTEvent e) { 1114 if (e instanceof AdjustmentEvent) { 1115 processAdjustmentEvent((AdjustmentEvent)e); 1116 return; 1117 } 1118 super.processEvent(e); 1119 } 1120 1121 /** 1122 * Processes adjustment events occurring on this 1123 * scrollbar by dispatching them to any registered 1124 * {@code AdjustmentListener} objects. 1125 * <p> 1126 * This method is not called unless adjustment events are 1127 * enabled for this component. Adjustment events are enabled 1128 * when one of the following occurs: 1129 * <ul> 1130 * <li>An {@code AdjustmentListener} object is registered 1131 * via {@code addAdjustmentListener}. 1132 * <li>Adjustment events are enabled via {@code enableEvents}. 1133 * </ul> 1134 * <p>Note that if the event parameter is {@code null} 1135 * the behavior is unspecified and may result in an 1136 * exception. 1137 * 1138 * @param e the adjustment event 1139 * @see java.awt.event.AdjustmentEvent 1140 * @see java.awt.event.AdjustmentListener 1141 * @see java.awt.Scrollbar#addAdjustmentListener 1142 * @see java.awt.Component#enableEvents 1143 * @since 1.1 1144 */ 1145 protected void processAdjustmentEvent(AdjustmentEvent e) { 1146 AdjustmentListener listener = adjustmentListener; 1147 if (listener != null) { 1148 listener.adjustmentValueChanged(e); 1149 } 1150 } 1151 1152 /** 1153 * Returns a string representing the state of this {@code Scrollbar}. 1154 * This method is intended to be used only for debugging purposes, and the 1155 * content and format of the returned string may vary between 1156 * implementations. The returned string may be empty but may not be 1157 * {@code null}. 1158 * 1159 * @return the parameter string of this scroll bar 1160 */ 1161 protected String paramString() { 1162 return super.paramString() + 1163 ",val=" + value + 1164 ",vis=" + visibleAmount + 1165 ",min=" + minimum + 1166 ",max=" + maximum + 1167 ((orientation == VERTICAL) ? ",vert" : ",horz") + 1168 ",isAdjusting=" + isAdjusting; 1169 } 1170 1171 1172 /* Serialization support. 1173 */ 1174 1175 /** 1176 * The scroll bar's serialized Data Version. 1177 * 1178 * @serial 1179 */ 1180 private int scrollbarSerializedDataVersion = 1; 1181 1182 /** 1183 * Writes default serializable fields to stream. Writes 1184 * a list of serializable {@code AdjustmentListeners} 1185 * as optional data. The non-serializable listeners are 1186 * detected and no attempt is made to serialize them. 1187 * 1188 * @param s the {@code ObjectOutputStream} to write 1189 * @serialData {@code null} terminated sequence of 0 1190 * or more pairs; the pair consists of a {@code String} 1191 * and an {@code Object}; the {@code String} indicates 1192 * the type of object and is one of the following: 1193 * {@code adjustmentListenerK} indicating an 1194 * {@code AdjustmentListener} object 1195 * 1196 * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener) 1197 * @see java.awt.Component#adjustmentListenerK 1198 * @see #readObject(ObjectInputStream) 1199 */ 1200 private void writeObject(ObjectOutputStream s) 1201 throws IOException 1202 { 1203 s.defaultWriteObject(); 1204 1205 AWTEventMulticaster.save(s, adjustmentListenerK, adjustmentListener); 1206 s.writeObject(null); 1207 } 1208 1209 /** 1210 * Reads the {@code ObjectInputStream} and if 1211 * it isn't {@code null} adds a listener to 1212 * receive adjustment events fired by the 1213 * {@code Scrollbar}. 1214 * Unrecognized keys or values will be ignored. 1215 * 1216 * @param s the {@code ObjectInputStream} to read 1217 * @exception HeadlessException if 1218 * {@code GraphicsEnvironment.isHeadless} returns 1219 * {@code true} 1220 * @see java.awt.GraphicsEnvironment#isHeadless 1221 * @see #writeObject(ObjectOutputStream) 1222 */ 1223 private void readObject(ObjectInputStream s) 1224 throws ClassNotFoundException, IOException, HeadlessException 1225 { 1226 GraphicsEnvironment.checkHeadless(); 1227 s.defaultReadObject(); 1228 1229 Object keyOrNull; 1230 while(null != (keyOrNull = s.readObject())) { 1231 String key = ((String)keyOrNull).intern(); 1232 1233 if (adjustmentListenerK == key) 1234 addAdjustmentListener((AdjustmentListener)(s.readObject())); 1235 1236 else // skip value for unrecognized key 1237 s.readObject(); 1238 } 1239 } 1240 1241 1242 ///////////////// 1243 // Accessibility support 1244 //////////////// 1245 1246 /** 1247 * Gets the {@code AccessibleContext} associated with this 1248 * {@code Scrollbar}. For scrollbars, the 1249 * {@code AccessibleContext} takes the form of an 1250 * {@code AccessibleAWTScrollBar}. A new 1251 * {@code AccessibleAWTScrollBar} instance is created if necessary. 1252 * 1253 * @return an {@code AccessibleAWTScrollBar} that serves as the 1254 * {@code AccessibleContext} of this {@code ScrollBar} 1255 * @since 1.3 1256 */ 1257 public AccessibleContext getAccessibleContext() { 1258 if (accessibleContext == null) { 1259 accessibleContext = new AccessibleAWTScrollBar(); 1260 } 1261 return accessibleContext; 1262 } 1263 1264 /** 1265 * This class implements accessibility support for the 1266 * {@code Scrollbar} class. It provides an implementation of 1267 * the Java Accessibility API appropriate to scrollbar 1268 * user-interface elements. 1269 * @since 1.3 1270 */ 1271 protected class AccessibleAWTScrollBar extends AccessibleAWTComponent 1272 implements AccessibleValue 1273 { 1274 /* 1275 * JDK 1.3 serialVersionUID 1276 */ 1277 private static final long serialVersionUID = -344337268523697807L; 1278 1279 /** 1280 * Get the state set of this object. 1281 * 1282 * @return an instance of {@code AccessibleState} 1283 * containing the current state of the object 1284 * @see AccessibleState 1285 */ 1286 public AccessibleStateSet getAccessibleStateSet() { 1287 AccessibleStateSet states = super.getAccessibleStateSet(); 1288 if (getValueIsAdjusting()) { 1289 states.add(AccessibleState.BUSY); 1290 } 1291 if (getOrientation() == VERTICAL) { 1292 states.add(AccessibleState.VERTICAL); 1293 } else { 1294 states.add(AccessibleState.HORIZONTAL); 1295 } 1296 return states; 1297 } 1298 1299 /** 1300 * Get the role of this object. 1301 * 1302 * @return an instance of {@code AccessibleRole} 1303 * describing the role of the object 1304 */ 1305 public AccessibleRole getAccessibleRole() { 1306 return AccessibleRole.SCROLL_BAR; 1307 } 1308 1309 /** 1310 * Get the {@code AccessibleValue} associated with this 1311 * object. In the implementation of the Java Accessibility 1312 * API for this class, return this object, which is 1313 * responsible for implementing the 1314 * {@code AccessibleValue} interface on behalf of itself. 1315 * 1316 * @return this object 1317 */ 1318 public AccessibleValue getAccessibleValue() { 1319 return this; 1320 } 1321 1322 /** 1323 * Get the accessible value of this object. 1324 * 1325 * @return The current value of this object. 1326 */ 1327 public Number getCurrentAccessibleValue() { 1328 return Integer.valueOf(getValue()); 1329 } 1330 1331 /** 1332 * Set the value of this object as a Number. 1333 * 1334 * @return True if the value was set. 1335 */ 1336 public boolean setCurrentAccessibleValue(Number n) { 1337 if (n instanceof Integer) { 1338 setValue(n.intValue()); 1339 return true; 1340 } else { 1341 return false; 1342 } 1343 } 1344 1345 /** 1346 * Get the minimum accessible value of this object. 1347 * 1348 * @return The minimum value of this object. 1349 */ 1350 public Number getMinimumAccessibleValue() { 1351 return Integer.valueOf(getMinimum()); 1352 } 1353 1354 /** 1355 * Get the maximum accessible value of this object. 1356 * 1357 * @return The maximum value of this object. 1358 */ 1359 public Number getMaximumAccessibleValue() { 1360 return Integer.valueOf(getMaximum()); 1361 } 1362 1363 } // AccessibleAWTScrollBar 1364 1365 }