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