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