1 /* 2 * Copyright (c) 1995, 2013, 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 = getToolkit().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 * @deprecated As of JDK version 1.1, 660 * replaced by <code>getVisibleAmount()</code>. 661 */ 662 @Deprecated 663 public int getVisible() { 664 return visibleAmount; 665 } 666 667 /** 668 * Sets the visible amount of this scroll bar. 669 * <p> 670 * When a scroll bar is used to select a range of values, 671 * the visible amount is used to represent the range of values 672 * that are currently visible. The size of the scroll bar's 673 * bubble (also called a thumb or scroll box), usually gives a 674 * visual representation of the relationship of the visible 675 * amount to the range of the scroll bar. 676 * Note that depending on platform, the value of the visible amount property 677 * may not be visually indicated by the size of the bubble. 678 * <p> 679 * The scroll bar's bubble may not be displayed when it is not 680 * moveable (e.g. when it takes up the entire length of the 681 * scroll bar's track, or when the scroll bar is disabled). 682 * Whether the bubble is displayed or not will not affect 683 * the value returned by <code>getVisibleAmount</code>. 684 * <p> 685 * If the visible amount supplied is less than <code>one</code> 686 * or greater than the current <code>maximum - minimum</code>, 687 * then either <code>one</code> or <code>maximum - minimum</code> 688 * is substituted, as appropriate. 689 * <p> 690 * Normally, a program should change a scroll bar's 691 * value only by calling <code>setValues</code>. 692 * The <code>setValues</code> method simultaneously 693 * and synchronously sets the minimum, maximum, visible amount, 694 * and value properties of a scroll bar, so that they are 695 * mutually consistent. 696 * 697 * @param newAmount the new visible amount 698 * @see java.awt.Scrollbar#getVisibleAmount 699 * @see java.awt.Scrollbar#setValues 700 * @since 1.1 701 */ 702 public void setVisibleAmount(int newAmount) { 703 // Use setValues so that a consistent policy relating 704 // minimum, maximum, visible amount, and value is enforced. 705 setValues(value, newAmount, minimum, maximum); 706 } 707 708 /** 709 * Sets the unit increment for this scroll bar. 710 * <p> 711 * The unit increment is the value that is added or subtracted 712 * when the user activates the unit increment area of the 713 * scroll bar, generally through a mouse or keyboard gesture 714 * that the scroll bar receives as an adjustment event. 715 * The unit increment must be greater than zero. 716 * Attepts to set the unit increment to a value lower than 1 717 * will result in a value of 1 being set. 718 * <p> 719 * In some operating systems, this property 720 * can be ignored by the underlying controls. 721 * 722 * @param v the amount by which to increment or decrement 723 * the scroll bar's value 724 * @see java.awt.Scrollbar#getUnitIncrement 725 * @since 1.1 726 */ 727 public void setUnitIncrement(int v) { 728 setLineIncrement(v); 729 } 730 731 /** 732 * @deprecated As of JDK version 1.1, 733 * replaced by <code>setUnitIncrement(int)</code>. 734 */ 735 @Deprecated 736 public synchronized void setLineIncrement(int v) { 737 int tmp = (v < 1) ? 1 : v; 738 739 if (lineIncrement == tmp) { 740 return; 741 } 742 lineIncrement = tmp; 743 744 ScrollbarPeer peer = (ScrollbarPeer)this.peer; 745 if (peer != null) { 746 peer.setLineIncrement(lineIncrement); 747 } 748 } 749 750 /** 751 * Gets the unit increment for this scrollbar. 752 * <p> 753 * The unit increment is the value that is added or subtracted 754 * when the user activates the unit increment area of the 755 * scroll bar, generally through a mouse or keyboard gesture 756 * that the scroll bar receives as an adjustment event. 757 * The unit increment must be greater than zero. 758 * <p> 759 * In some operating systems, this property 760 * can be ignored by the underlying controls. 761 * 762 * @return the unit increment of this scroll bar 763 * @see java.awt.Scrollbar#setUnitIncrement 764 * @since 1.1 765 */ 766 public int getUnitIncrement() { 767 return getLineIncrement(); 768 } 769 770 /** 771 * @deprecated As of JDK version 1.1, 772 * replaced by <code>getUnitIncrement()</code>. 773 */ 774 @Deprecated 775 public int getLineIncrement() { 776 return lineIncrement; 777 } 778 779 /** 780 * Sets the block increment for this scroll bar. 781 * <p> 782 * The block increment is the value that is added or subtracted 783 * when the user activates the block increment area of the 784 * scroll bar, generally through a mouse or keyboard gesture 785 * that the scroll bar receives as an adjustment event. 786 * The block increment must be greater than zero. 787 * Attepts to set the block increment to a value lower than 1 788 * will result in a value of 1 being set. 789 * 790 * @param v the amount by which to increment or decrement 791 * the scroll bar's value 792 * @see java.awt.Scrollbar#getBlockIncrement 793 * @since 1.1 794 */ 795 public void setBlockIncrement(int v) { 796 setPageIncrement(v); 797 } 798 799 /** 800 * @deprecated As of JDK version 1.1, 801 * replaced by <code>setBlockIncrement()</code>. 802 */ 803 @Deprecated 804 public synchronized void setPageIncrement(int v) { 805 int tmp = (v < 1) ? 1 : v; 806 807 if (pageIncrement == tmp) { 808 return; 809 } 810 pageIncrement = tmp; 811 812 ScrollbarPeer peer = (ScrollbarPeer)this.peer; 813 if (peer != null) { 814 peer.setPageIncrement(pageIncrement); 815 } 816 } 817 818 /** 819 * Gets the block increment of this scroll bar. 820 * <p> 821 * The block increment is the value that is added or subtracted 822 * when the user activates the block increment area of the 823 * scroll bar, generally through a mouse or keyboard gesture 824 * that the scroll bar receives as an adjustment event. 825 * The block increment must be greater than zero. 826 * 827 * @return the block increment of this scroll bar 828 * @see java.awt.Scrollbar#setBlockIncrement 829 * @since 1.1 830 */ 831 public int getBlockIncrement() { 832 return getPageIncrement(); 833 } 834 835 /** 836 * @deprecated As of JDK version 1.1, 837 * replaced by <code>getBlockIncrement()</code>. 838 */ 839 @Deprecated 840 public int getPageIncrement() { 841 return pageIncrement; 842 } 843 844 /** 845 * Sets the values of four properties for this scroll bar: 846 * <code>value</code>, <code>visibleAmount</code>, 847 * <code>minimum</code>, and <code>maximum</code>. 848 * If the values supplied for these properties are inconsistent 849 * or incorrect, they will be changed to ensure consistency. 850 * <p> 851 * This method simultaneously and synchronously sets the values 852 * of four scroll bar properties, assuring that the values of 853 * these properties are mutually consistent. It enforces the 854 * following constraints: 855 * <code>maximum</code> must be greater than <code>minimum</code>, 856 * <code>maximum - minimum</code> must not be greater 857 * than <code>Integer.MAX_VALUE</code>, 858 * <code>visibleAmount</code> must be greater than zero. 859 * <code>visibleAmount</code> must not be greater than 860 * <code>maximum - minimum</code>, 861 * <code>value</code> must not be less than <code>minimum</code>, 862 * and <code>value</code> must not be greater than 863 * <code>maximum - visibleAmount</code> 864 * <p> 865 * Calling this method does not fire an 866 * <code>AdjustmentEvent</code>. 867 * 868 * @param value is the position in the current window 869 * @param visible is the visible amount of the scroll bar 870 * @param minimum is the minimum value of the scroll bar 871 * @param maximum is the maximum value of the scroll bar 872 * @see #setMinimum 873 * @see #setMaximum 874 * @see #setVisibleAmount 875 * @see #setValue 876 */ 877 public void setValues(int value, int visible, int minimum, int maximum) { 878 int oldValue; 879 synchronized (this) { 880 if (minimum == Integer.MAX_VALUE) { 881 minimum = Integer.MAX_VALUE - 1; 882 } 883 if (maximum <= minimum) { 884 maximum = minimum + 1; 885 } 886 887 long maxMinusMin = (long) maximum - (long) minimum; 888 if (maxMinusMin > Integer.MAX_VALUE) { 889 maxMinusMin = Integer.MAX_VALUE; 890 maximum = minimum + (int) maxMinusMin; 891 } 892 if (visible > (int) maxMinusMin) { 893 visible = (int) maxMinusMin; 894 } 895 if (visible < 1) { 896 visible = 1; 897 } 898 899 if (value < minimum) { 900 value = minimum; 901 } 902 if (value > maximum - visible) { 903 value = maximum - visible; 904 } 905 906 oldValue = this.value; 907 this.value = value; 908 this.visibleAmount = visible; 909 this.minimum = minimum; 910 this.maximum = maximum; 911 ScrollbarPeer peer = (ScrollbarPeer)this.peer; 912 if (peer != null) { 913 peer.setValues(value, visibleAmount, minimum, maximum); 914 } 915 } 916 917 if ((oldValue != value) && (accessibleContext != null)) { 918 accessibleContext.firePropertyChange( 919 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, 920 Integer.valueOf(oldValue), 921 Integer.valueOf(value)); 922 } 923 } 924 925 /** 926 * Returns true if the value is in the process of changing as a 927 * result of actions being taken by the user. 928 * 929 * @return the value of the <code>valueIsAdjusting</code> property 930 * @see #setValueIsAdjusting 931 * @since 1.4 932 */ 933 public boolean getValueIsAdjusting() { 934 return isAdjusting; 935 } 936 937 /** 938 * Sets the <code>valueIsAdjusting</code> property. 939 * 940 * @param b new adjustment-in-progress status 941 * @see #getValueIsAdjusting 942 * @since 1.4 943 */ 944 public void setValueIsAdjusting(boolean b) { 945 boolean oldValue; 946 947 synchronized (this) { 948 oldValue = isAdjusting; 949 isAdjusting = b; 950 } 951 952 if ((oldValue != b) && (accessibleContext != null)) { 953 accessibleContext.firePropertyChange( 954 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 955 ((oldValue) ? AccessibleState.BUSY : null), 956 ((b) ? AccessibleState.BUSY : null)); 957 } 958 } 959 960 961 962 /** 963 * Adds the specified adjustment listener to receive instances of 964 * <code>AdjustmentEvent</code> from this scroll bar. 965 * If l is <code>null</code>, no exception is thrown and no 966 * action is performed. 967 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 968 * >AWT Threading Issues</a> for details on AWT's threading model. 969 * 970 * @param l the adjustment listener 971 * @see #removeAdjustmentListener 972 * @see #getAdjustmentListeners 973 * @see java.awt.event.AdjustmentEvent 974 * @see java.awt.event.AdjustmentListener 975 * @since 1.1 976 */ 977 public synchronized void addAdjustmentListener(AdjustmentListener l) { 978 if (l == null) { 979 return; 980 } 981 adjustmentListener = AWTEventMulticaster.add(adjustmentListener, l); 982 newEventsOnly = true; 983 } 984 985 /** 986 * Removes the specified adjustment listener so that it no longer 987 * receives instances of <code>AdjustmentEvent</code> from this scroll bar. 988 * If l is <code>null</code>, no exception is thrown and no action 989 * is performed. 990 * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads" 991 * >AWT Threading Issues</a> for details on AWT's threading model. 992 * 993 * @param l the adjustment listener 994 * @see #addAdjustmentListener 995 * @see #getAdjustmentListeners 996 * @see java.awt.event.AdjustmentEvent 997 * @see java.awt.event.AdjustmentListener 998 * @since 1.1 999 */ 1000 public synchronized void removeAdjustmentListener(AdjustmentListener l) { 1001 if (l == null) { 1002 return; 1003 } 1004 adjustmentListener = AWTEventMulticaster.remove(adjustmentListener, l); 1005 } 1006 1007 /** 1008 * Returns an array of all the adjustment listeners 1009 * registered on this scrollbar. 1010 * 1011 * @return all of this scrollbar's <code>AdjustmentListener</code>s 1012 * or an empty array if no adjustment 1013 * listeners are currently registered 1014 * @see #addAdjustmentListener 1015 * @see #removeAdjustmentListener 1016 * @see java.awt.event.AdjustmentEvent 1017 * @see java.awt.event.AdjustmentListener 1018 * @since 1.4 1019 */ 1020 public synchronized AdjustmentListener[] getAdjustmentListeners() { 1021 return getListeners(AdjustmentListener.class); 1022 } 1023 1024 /** 1025 * Returns an array of all the objects currently registered 1026 * as <code><em>Foo</em>Listener</code>s 1027 * upon this <code>Scrollbar</code>. 1028 * <code><em>Foo</em>Listener</code>s are registered using the 1029 * <code>add<em>Foo</em>Listener</code> method. 1030 * <p> 1031 * You can specify the <code>listenerType</code> argument 1032 * with a class literal, such as 1033 * <code><em>Foo</em>Listener.class</code>. 1034 * For example, you can query a 1035 * <code>Scrollbar</code> <code>c</code> 1036 * for its mouse listeners with the following code: 1037 * 1038 * <pre>MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class));</pre> 1039 * 1040 * If no such listeners exist, this method returns an empty array. 1041 * 1042 * @param listenerType the type of listeners requested; this parameter 1043 * should specify an interface that descends from 1044 * <code>java.util.EventListener</code> 1045 * @return an array of all objects registered as 1046 * <code><em>Foo</em>Listener</code>s on this component, 1047 * or an empty array if no such listeners have been added 1048 * @exception ClassCastException if <code>listenerType</code> 1049 * doesn't specify a class or interface that implements 1050 * <code>java.util.EventListener</code> 1051 * 1052 * @since 1.3 1053 */ 1054 public <T extends EventListener> T[] getListeners(Class<T> listenerType) { 1055 EventListener l = null; 1056 if (listenerType == AdjustmentListener.class) { 1057 l = adjustmentListener; 1058 } else { 1059 return super.getListeners(listenerType); 1060 } 1061 return AWTEventMulticaster.getListeners(l, listenerType); 1062 } 1063 1064 // REMIND: remove when filtering is done at lower level 1065 boolean eventEnabled(AWTEvent e) { 1066 if (e.id == AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED) { 1067 if ((eventMask & AWTEvent.ADJUSTMENT_EVENT_MASK) != 0 || 1068 adjustmentListener != null) { 1069 return true; 1070 } 1071 return false; 1072 } 1073 return super.eventEnabled(e); 1074 } 1075 1076 /** 1077 * Processes events on this scroll bar. If the event is an 1078 * instance of <code>AdjustmentEvent</code>, it invokes the 1079 * <code>processAdjustmentEvent</code> method. 1080 * Otherwise, it invokes its superclass's 1081 * <code>processEvent</code> method. 1082 * <p>Note that if the event parameter is <code>null</code> 1083 * the behavior is unspecified and may result in an 1084 * exception. 1085 * 1086 * @param e the event 1087 * @see java.awt.event.AdjustmentEvent 1088 * @see java.awt.Scrollbar#processAdjustmentEvent 1089 * @since 1.1 1090 */ 1091 protected void processEvent(AWTEvent e) { 1092 if (e instanceof AdjustmentEvent) { 1093 processAdjustmentEvent((AdjustmentEvent)e); 1094 return; 1095 } 1096 super.processEvent(e); 1097 } 1098 1099 /** 1100 * Processes adjustment events occurring on this 1101 * scrollbar by dispatching them to any registered 1102 * <code>AdjustmentListener</code> objects. 1103 * <p> 1104 * This method is not called unless adjustment events are 1105 * enabled for this component. Adjustment events are enabled 1106 * when one of the following occurs: 1107 * <ul> 1108 * <li>An <code>AdjustmentListener</code> object is registered 1109 * via <code>addAdjustmentListener</code>. 1110 * <li>Adjustment events are enabled via <code>enableEvents</code>. 1111 * </ul> 1112 * <p>Note that if the event parameter is <code>null</code> 1113 * the behavior is unspecified and may result in an 1114 * exception. 1115 * 1116 * @param e the adjustment event 1117 * @see java.awt.event.AdjustmentEvent 1118 * @see java.awt.event.AdjustmentListener 1119 * @see java.awt.Scrollbar#addAdjustmentListener 1120 * @see java.awt.Component#enableEvents 1121 * @since 1.1 1122 */ 1123 protected void processAdjustmentEvent(AdjustmentEvent e) { 1124 AdjustmentListener listener = adjustmentListener; 1125 if (listener != null) { 1126 listener.adjustmentValueChanged(e); 1127 } 1128 } 1129 1130 /** 1131 * Returns a string representing the state of this <code>Scrollbar</code>. 1132 * This method is intended to be used only for debugging purposes, and the 1133 * content and format of the returned string may vary between 1134 * implementations. The returned string may be empty but may not be 1135 * <code>null</code>. 1136 * 1137 * @return the parameter string of this scroll bar 1138 */ 1139 protected String paramString() { 1140 return super.paramString() + 1141 ",val=" + value + 1142 ",vis=" + visibleAmount + 1143 ",min=" + minimum + 1144 ",max=" + maximum + 1145 ((orientation == VERTICAL) ? ",vert" : ",horz") + 1146 ",isAdjusting=" + isAdjusting; 1147 } 1148 1149 1150 /* Serialization support. 1151 */ 1152 1153 /** 1154 * The scroll bar's serialized Data Version. 1155 * 1156 * @serial 1157 */ 1158 private int scrollbarSerializedDataVersion = 1; 1159 1160 /** 1161 * Writes default serializable fields to stream. Writes 1162 * a list of serializable <code>AdjustmentListeners</code> 1163 * as optional data. The non-serializable listeners are 1164 * detected and no attempt is made to serialize them. 1165 * 1166 * @param s the <code>ObjectOutputStream</code> to write 1167 * @serialData <code>null</code> terminated sequence of 0 1168 * or more pairs; the pair consists of a <code>String</code> 1169 * and an <code>Object</code>; the <code>String</code> indicates 1170 * the type of object and is one of the following: 1171 * <code>adjustmentListenerK</code> indicating an 1172 * <code>AdjustmentListener</code> object 1173 * 1174 * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener) 1175 * @see java.awt.Component#adjustmentListenerK 1176 * @see #readObject(ObjectInputStream) 1177 */ 1178 private void writeObject(ObjectOutputStream s) 1179 throws IOException 1180 { 1181 s.defaultWriteObject(); 1182 1183 AWTEventMulticaster.save(s, adjustmentListenerK, adjustmentListener); 1184 s.writeObject(null); 1185 } 1186 1187 /** 1188 * Reads the <code>ObjectInputStream</code> and if 1189 * it isn't <code>null</code> adds a listener to 1190 * receive adjustment events fired by the 1191 * <code>Scrollbar</code>. 1192 * Unrecognized keys or values will be ignored. 1193 * 1194 * @param s the <code>ObjectInputStream</code> to read 1195 * @exception HeadlessException if 1196 * <code>GraphicsEnvironment.isHeadless</code> returns 1197 * <code>true</code> 1198 * @see java.awt.GraphicsEnvironment#isHeadless 1199 * @see #writeObject(ObjectOutputStream) 1200 */ 1201 private void readObject(ObjectInputStream s) 1202 throws ClassNotFoundException, IOException, HeadlessException 1203 { 1204 GraphicsEnvironment.checkHeadless(); 1205 s.defaultReadObject(); 1206 1207 Object keyOrNull; 1208 while(null != (keyOrNull = s.readObject())) { 1209 String key = ((String)keyOrNull).intern(); 1210 1211 if (adjustmentListenerK == key) 1212 addAdjustmentListener((AdjustmentListener)(s.readObject())); 1213 1214 else // skip value for unrecognized key 1215 s.readObject(); 1216 } 1217 } 1218 1219 1220 ///////////////// 1221 // Accessibility support 1222 //////////////// 1223 1224 /** 1225 * Gets the <code>AccessibleContext</code> associated with this 1226 * <code>Scrollbar</code>. For scrollbars, the 1227 * <code>AccessibleContext</code> takes the form of an 1228 * <code>AccessibleAWTScrollBar</code>. A new 1229 * <code>AccessibleAWTScrollBar</code> instance is created if necessary. 1230 * 1231 * @return an <code>AccessibleAWTScrollBar</code> that serves as the 1232 * <code>AccessibleContext</code> of this <code>ScrollBar</code> 1233 * @since 1.3 1234 */ 1235 public AccessibleContext getAccessibleContext() { 1236 if (accessibleContext == null) { 1237 accessibleContext = new AccessibleAWTScrollBar(); 1238 } 1239 return accessibleContext; 1240 } 1241 1242 /** 1243 * This class implements accessibility support for the 1244 * <code>Scrollbar</code> class. It provides an implementation of 1245 * the Java Accessibility API appropriate to scrollbar 1246 * user-interface elements. 1247 * @since 1.3 1248 */ 1249 protected class AccessibleAWTScrollBar extends AccessibleAWTComponent 1250 implements AccessibleValue 1251 { 1252 /* 1253 * JDK 1.3 serialVersionUID 1254 */ 1255 private static final long serialVersionUID = -344337268523697807L; 1256 1257 /** 1258 * Get the state set of this object. 1259 * 1260 * @return an instance of <code>AccessibleState</code> 1261 * containing the current state of the object 1262 * @see AccessibleState 1263 */ 1264 public AccessibleStateSet getAccessibleStateSet() { 1265 AccessibleStateSet states = super.getAccessibleStateSet(); 1266 if (getValueIsAdjusting()) { 1267 states.add(AccessibleState.BUSY); 1268 } 1269 if (getOrientation() == VERTICAL) { 1270 states.add(AccessibleState.VERTICAL); 1271 } else { 1272 states.add(AccessibleState.HORIZONTAL); 1273 } 1274 return states; 1275 } 1276 1277 /** 1278 * Get the role of this object. 1279 * 1280 * @return an instance of <code>AccessibleRole</code> 1281 * describing the role of the object 1282 */ 1283 public AccessibleRole getAccessibleRole() { 1284 return AccessibleRole.SCROLL_BAR; 1285 } 1286 1287 /** 1288 * Get the <code>AccessibleValue</code> associated with this 1289 * object. In the implementation of the Java Accessibility 1290 * API for this class, return this object, which is 1291 * responsible for implementing the 1292 * <code>AccessibleValue</code> interface on behalf of itself. 1293 * 1294 * @return this object 1295 */ 1296 public AccessibleValue getAccessibleValue() { 1297 return this; 1298 } 1299 1300 /** 1301 * Get the accessible value of this object. 1302 * 1303 * @return The current value of this object. 1304 */ 1305 public Number getCurrentAccessibleValue() { 1306 return Integer.valueOf(getValue()); 1307 } 1308 1309 /** 1310 * Set the value of this object as a Number. 1311 * 1312 * @return True if the value was set. 1313 */ 1314 public boolean setCurrentAccessibleValue(Number n) { 1315 if (n instanceof Integer) { 1316 setValue(n.intValue()); 1317 return true; 1318 } else { 1319 return false; 1320 } 1321 } 1322 1323 /** 1324 * Get the minimum accessible value of this object. 1325 * 1326 * @return The minimum value of this object. 1327 */ 1328 public Number getMinimumAccessibleValue() { 1329 return Integer.valueOf(getMinimum()); 1330 } 1331 1332 /** 1333 * Get the maximum accessible value of this object. 1334 * 1335 * @return The maximum value of this object. 1336 */ 1337 public Number getMaximumAccessibleValue() { 1338 return Integer.valueOf(getMaximum()); 1339 } 1340 1341 } // AccessibleAWTScrollBar 1342 1343 }