1 /* 2 * Copyright (c) 1997, 2014, 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 26 package javax.swing; 27 28 import java.io.Serializable; 29 import java.awt.Component; 30 import java.awt.Adjustable; 31 import java.awt.Dimension; 32 import java.awt.event.AdjustmentListener; 33 import java.awt.event.AdjustmentEvent; 34 import java.awt.Graphics; 35 36 import javax.swing.event.*; 37 import javax.swing.plaf.*; 38 import javax.accessibility.*; 39 40 import java.io.ObjectOutputStream; 41 import java.io.ObjectInputStream; 42 import java.io.IOException; 43 44 45 46 /** 47 * An implementation of a scrollbar. The user positions the knob in the 48 * scrollbar to determine the contents of the viewing area. The 49 * program typically adjusts the display so that the end of the 50 * scrollbar represents the end of the displayable contents, or 100% 51 * of the contents. The start of the scrollbar is the beginning of the 52 * displayable contents, or 0%. The position of the knob within 53 * those bounds then translates to the corresponding percentage of 54 * the displayable contents. 55 * <p> 56 * Typically, as the position of the knob in the scrollbar changes 57 * a corresponding change is made to the position of the JViewport on 58 * the underlying view, changing the contents of the JViewport. 59 * <p> 60 * <strong>Warning:</strong> Swing is not thread safe. For more 61 * information see <a 62 * href="package-summary.html#threading">Swing's Threading 63 * Policy</a>. 64 * <p> 65 * <strong>Warning:</strong> 66 * Serialized objects of this class will not be compatible with 67 * future Swing releases. The current serialization support is 68 * appropriate for short term storage or RMI between applications running 69 * the same version of Swing. As of 1.4, support for long term storage 70 * of all JavaBeans™ 71 * has been added to the <code>java.beans</code> package. 72 * Please see {@link java.beans.XMLEncoder}. 73 * 74 * @see JScrollPane 75 * @beaninfo 76 * attribute: isContainer false 77 * description: A component that helps determine the visible content range of an area. 78 * 79 * @author David Kloba 80 * @since 1.2 81 */ 82 @SuppressWarnings("serial") // Same-version serialization only 83 public class JScrollBar extends JComponent implements Adjustable, Accessible 84 { 85 /** 86 * @see #getUIClassID 87 * @see #readObject 88 */ 89 private static final String uiClassID = "ScrollBarUI"; 90 91 /** 92 * All changes from the model are treated as though the user moved 93 * the scrollbar knob. 94 */ 95 private ChangeListener fwdAdjustmentEvents = new ModelListener(); 96 97 98 /** 99 * The model that represents the scrollbar's minimum, maximum, extent 100 * (aka "visibleAmount") and current value. 101 * @see #setModel 102 */ 103 protected BoundedRangeModel model; 104 105 106 /** 107 * @see #setOrientation 108 */ 109 protected int orientation; 110 111 112 /** 113 * @see #setUnitIncrement 114 */ 115 protected int unitIncrement; 116 117 118 /** 119 * @see #setBlockIncrement 120 */ 121 protected int blockIncrement; 122 123 124 private void checkOrientation(int orientation) { 125 switch (orientation) { 126 case VERTICAL: 127 case HORIZONTAL: 128 break; 129 default: 130 throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL"); 131 } 132 } 133 134 135 /** 136 * Creates a scrollbar with the specified orientation, 137 * value, extent, minimum, and maximum. 138 * The "extent" is the size of the viewable area. It is also known 139 * as the "visible amount". 140 * <p> 141 * Note: Use <code>setBlockIncrement</code> to set the block 142 * increment to a size slightly smaller than the view's extent. 143 * That way, when the user jumps the knob to an adjacent position, 144 * one or two lines of the original contents remain in view. 145 * 146 * @exception IllegalArgumentException if orientation is not one of VERTICAL, HORIZONTAL 147 * 148 * @see #setOrientation 149 * @see #setValue 150 * @see #setVisibleAmount 151 * @see #setMinimum 152 * @see #setMaximum 153 * 154 * @param orientation an orientation of the {@code JScrollBar} 155 * @param value an int giving the current value 156 * @param extent an int giving the amount by which the value can "jump" 157 * @param min an int giving the minimum value 158 * @param max an int giving the maximum value 159 */ 160 public JScrollBar(int orientation, int value, int extent, int min, int max) 161 { 162 checkOrientation(orientation); 163 this.unitIncrement = 1; 164 this.blockIncrement = (extent == 0) ? 1 : extent; 165 this.orientation = orientation; 166 this.model = new DefaultBoundedRangeModel(value, extent, min, max); 167 this.model.addChangeListener(fwdAdjustmentEvents); 168 setRequestFocusEnabled(false); 169 updateUI(); 170 } 171 172 173 /** 174 * Creates a scrollbar with the specified orientation 175 * and the following initial values: 176 * <pre> 177 * minimum = 0 178 * maximum = 100 179 * value = 0 180 * extent = 10 181 * </pre> 182 * 183 * @param orientation an orientation of the {@code JScrollBar} 184 */ 185 public JScrollBar(int orientation) { 186 this(orientation, 0, 10, 0, 100); 187 } 188 189 190 /** 191 * Creates a vertical scrollbar with the following initial values: 192 * <pre> 193 * minimum = 0 194 * maximum = 100 195 * value = 0 196 * extent = 10 197 * </pre> 198 */ 199 public JScrollBar() { 200 this(VERTICAL); 201 } 202 203 204 /** 205 * Sets the {@literal L&F} object that renders this component. 206 * 207 * @param ui the <code>ScrollBarUI</code> {@literal L&F} object 208 * @see UIDefaults#getUI 209 * @since 1.4 210 * @beaninfo 211 * bound: true 212 * hidden: true 213 * attribute: visualUpdate true 214 * description: The UI object that implements the Component's LookAndFeel 215 */ 216 public void setUI(ScrollBarUI ui) { 217 super.setUI(ui); 218 } 219 220 221 /** 222 * Returns the delegate that implements the look and feel for 223 * this component. 224 * 225 * @return the scroll bar's current UI. 226 * @see JComponent#setUI 227 */ 228 public ScrollBarUI getUI() { 229 return (ScrollBarUI)ui; 230 } 231 232 233 /** 234 * Overrides <code>JComponent.updateUI</code>. 235 * @see JComponent#updateUI 236 */ 237 public void updateUI() { 238 setUI((ScrollBarUI)UIManager.getUI(this)); 239 } 240 241 242 /** 243 * Returns the name of the LookAndFeel class for this component. 244 * 245 * @return "ScrollBarUI" 246 * @see JComponent#getUIClassID 247 * @see UIDefaults#getUI 248 */ 249 public String getUIClassID() { 250 return uiClassID; 251 } 252 253 254 255 /** 256 * Returns the component's orientation (horizontal or vertical). 257 * 258 * @return VERTICAL or HORIZONTAL 259 * @see #setOrientation 260 * @see java.awt.Adjustable#getOrientation 261 */ 262 public int getOrientation() { 263 return orientation; 264 } 265 266 267 /** 268 * Set the scrollbar's orientation to either VERTICAL or 269 * HORIZONTAL. 270 * 271 * @param orientation an orientation of the {@code JScrollBar} 272 * @exception IllegalArgumentException if orientation is not one of VERTICAL, HORIZONTAL 273 * @see #getOrientation 274 * @beaninfo 275 * preferred: true 276 * bound: true 277 * attribute: visualUpdate true 278 * description: The scrollbar's orientation. 279 * enum: VERTICAL JScrollBar.VERTICAL 280 * HORIZONTAL JScrollBar.HORIZONTAL 281 */ 282 public void setOrientation(int orientation) 283 { 284 checkOrientation(orientation); 285 int oldValue = this.orientation; 286 this.orientation = orientation; 287 firePropertyChange("orientation", oldValue, orientation); 288 289 if ((oldValue != orientation) && (accessibleContext != null)) { 290 accessibleContext.firePropertyChange( 291 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 292 ((oldValue == VERTICAL) 293 ? AccessibleState.VERTICAL : AccessibleState.HORIZONTAL), 294 ((orientation == VERTICAL) 295 ? AccessibleState.VERTICAL : AccessibleState.HORIZONTAL)); 296 } 297 if (orientation != oldValue) { 298 revalidate(); 299 } 300 } 301 302 303 /** 304 * Returns data model that handles the scrollbar's four 305 * fundamental properties: minimum, maximum, value, extent. 306 * 307 * @return the data model 308 * 309 * @see #setModel 310 */ 311 public BoundedRangeModel getModel() { 312 return model; 313 } 314 315 316 /** 317 * Sets the model that handles the scrollbar's four 318 * fundamental properties: minimum, maximum, value, extent. 319 * 320 * @param newModel a new model 321 * @see #getModel 322 * @beaninfo 323 * bound: true 324 * expert: true 325 * description: The scrollbar's BoundedRangeModel. 326 */ 327 public void setModel(BoundedRangeModel newModel) { 328 Integer oldValue = null; 329 BoundedRangeModel oldModel = model; 330 if (model != null) { 331 model.removeChangeListener(fwdAdjustmentEvents); 332 oldValue = Integer.valueOf(model.getValue()); 333 } 334 model = newModel; 335 if (model != null) { 336 model.addChangeListener(fwdAdjustmentEvents); 337 } 338 339 firePropertyChange("model", oldModel, model); 340 341 if (accessibleContext != null) { 342 accessibleContext.firePropertyChange( 343 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, 344 oldValue, model.getValue()); 345 } 346 } 347 348 349 /** 350 * Returns the amount to change the scrollbar's value by, 351 * given a unit up/down request. A ScrollBarUI implementation 352 * typically calls this method when the user clicks on a scrollbar 353 * up/down arrow and uses the result to update the scrollbar's 354 * value. Subclasses my override this method to compute 355 * a value, e.g. the change required to scroll up or down one 356 * (variable height) line text or one row in a table. 357 * <p> 358 * The JScrollPane component creates scrollbars (by default) 359 * that override this method and delegate to the viewports 360 * Scrollable view, if it has one. The Scrollable interface 361 * provides a more specialized version of this method. 362 * <p> 363 * Some look and feels implement custom scrolling behavior 364 * and ignore this property. 365 * 366 * @param direction is -1 or 1 for up/down respectively 367 * @return the value of the unitIncrement property 368 * @see #setUnitIncrement 369 * @see #setValue 370 * @see Scrollable#getScrollableUnitIncrement 371 */ 372 public int getUnitIncrement(int direction) { 373 return unitIncrement; 374 } 375 376 377 /** 378 * Sets the unitIncrement property. 379 * <p> 380 * Note, that if the argument is equal to the value of Integer.MIN_VALUE, 381 * the most look and feels will not provide the scrolling to the right/down. 382 * <p> 383 * Some look and feels implement custom scrolling behavior 384 * and ignore this property. 385 * 386 * @see #getUnitIncrement 387 * @beaninfo 388 * preferred: true 389 * bound: true 390 * description: The scrollbar's unit increment. 391 */ 392 public void setUnitIncrement(int unitIncrement) { 393 int oldValue = this.unitIncrement; 394 this.unitIncrement = unitIncrement; 395 firePropertyChange("unitIncrement", oldValue, unitIncrement); 396 } 397 398 399 /** 400 * Returns the amount to change the scrollbar's value by, 401 * given a block (usually "page") up/down request. A ScrollBarUI 402 * implementation typically calls this method when the user clicks 403 * above or below the scrollbar "knob" to change the value 404 * up or down by large amount. Subclasses my override this 405 * method to compute a value, e.g. the change required to scroll 406 * up or down one paragraph in a text document. 407 * <p> 408 * The JScrollPane component creates scrollbars (by default) 409 * that override this method and delegate to the viewports 410 * Scrollable view, if it has one. The Scrollable interface 411 * provides a more specialized version of this method. 412 * <p> 413 * Some look and feels implement custom scrolling behavior 414 * and ignore this property. 415 * 416 * @param direction is -1 or 1 for up/down respectively 417 * @return the value of the blockIncrement property 418 * @see #setBlockIncrement 419 * @see #setValue 420 * @see Scrollable#getScrollableBlockIncrement 421 */ 422 public int getBlockIncrement(int direction) { 423 return blockIncrement; 424 } 425 426 427 /** 428 * Sets the blockIncrement property. 429 * <p> 430 * Note, that if the argument is equal to the value of Integer.MIN_VALUE, 431 * the most look and feels will not provide the scrolling to the right/down. 432 * <p> 433 * Some look and feels implement custom scrolling behavior 434 * and ignore this property. 435 * 436 * @see #getBlockIncrement() 437 * @beaninfo 438 * preferred: true 439 * bound: true 440 * description: The scrollbar's block increment. 441 */ 442 public void setBlockIncrement(int blockIncrement) { 443 int oldValue = this.blockIncrement; 444 this.blockIncrement = blockIncrement; 445 firePropertyChange("blockIncrement", oldValue, blockIncrement); 446 } 447 448 449 /** 450 * For backwards compatibility with java.awt.Scrollbar. 451 * @see Adjustable#getUnitIncrement 452 * @see #getUnitIncrement(int) 453 */ 454 public int getUnitIncrement() { 455 return unitIncrement; 456 } 457 458 459 /** 460 * For backwards compatibility with java.awt.Scrollbar. 461 * @see Adjustable#getBlockIncrement 462 * @see #getBlockIncrement(int) 463 */ 464 public int getBlockIncrement() { 465 return blockIncrement; 466 } 467 468 469 /** 470 * Returns the scrollbar's value. 471 * @return the model's value property 472 * @see #setValue 473 */ 474 public int getValue() { 475 return getModel().getValue(); 476 } 477 478 479 /** 480 * Sets the scrollbar's value. This method just forwards the value 481 * to the model. 482 * 483 * @see #getValue 484 * @see BoundedRangeModel#setValue 485 * @beaninfo 486 * preferred: true 487 * description: The scrollbar's current value. 488 */ 489 public void setValue(int value) { 490 BoundedRangeModel m = getModel(); 491 int oldValue = m.getValue(); 492 m.setValue(value); 493 494 if (accessibleContext != null) { 495 accessibleContext.firePropertyChange( 496 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, 497 Integer.valueOf(oldValue), 498 Integer.valueOf(m.getValue())); 499 } 500 } 501 502 503 /** 504 * Returns the scrollbar's extent, aka its "visibleAmount". In many 505 * scrollbar look and feel implementations the size of the 506 * scrollbar "knob" or "thumb" is proportional to the extent. 507 * 508 * @return the value of the model's extent property 509 * @see #setVisibleAmount 510 */ 511 public int getVisibleAmount() { 512 return getModel().getExtent(); 513 } 514 515 516 /** 517 * Set the model's extent property. 518 * 519 * @see #getVisibleAmount 520 * @see BoundedRangeModel#setExtent 521 * @beaninfo 522 * preferred: true 523 * description: The amount of the view that is currently visible. 524 */ 525 public void setVisibleAmount(int extent) { 526 getModel().setExtent(extent); 527 } 528 529 530 /** 531 * Returns the minimum value supported by the scrollbar 532 * (usually zero). 533 * 534 * @return the value of the model's minimum property 535 * @see #setMinimum 536 */ 537 public int getMinimum() { 538 return getModel().getMinimum(); 539 } 540 541 542 /** 543 * Sets the model's minimum property. 544 * 545 * @see #getMinimum 546 * @see BoundedRangeModel#setMinimum 547 * @beaninfo 548 * preferred: true 549 * description: The scrollbar's minimum value. 550 */ 551 public void setMinimum(int minimum) { 552 getModel().setMinimum(minimum); 553 } 554 555 556 /** 557 * The maximum value of the scrollbar is maximum - extent. 558 * 559 * @return the value of the model's maximum property 560 * @see #setMaximum 561 */ 562 public int getMaximum() { 563 return getModel().getMaximum(); 564 } 565 566 567 /** 568 * Sets the model's maximum property. Note that the scrollbar's value 569 * can only be set to maximum - extent. 570 * 571 * @see #getMaximum 572 * @see BoundedRangeModel#setMaximum 573 * @beaninfo 574 * preferred: true 575 * description: The scrollbar's maximum value. 576 */ 577 public void setMaximum(int maximum) { 578 getModel().setMaximum(maximum); 579 } 580 581 582 /** 583 * True if the scrollbar knob is being dragged. 584 * 585 * @return the value of the model's valueIsAdjusting property 586 * @see #setValueIsAdjusting 587 */ 588 public boolean getValueIsAdjusting() { 589 return getModel().getValueIsAdjusting(); 590 } 591 592 593 /** 594 * Sets the model's valueIsAdjusting property. Scrollbar look and 595 * feel implementations should set this property to true when 596 * a knob drag begins, and to false when the drag ends. The 597 * scrollbar model will not generate ChangeEvents while 598 * valueIsAdjusting is true. 599 * 600 * @param b {@code true} if the upcoming changes to the value property are part of a series 601 * 602 * @see #getValueIsAdjusting 603 * @see BoundedRangeModel#setValueIsAdjusting 604 * @beaninfo 605 * expert: true 606 * description: True if the scrollbar thumb is being dragged. 607 */ 608 public void setValueIsAdjusting(boolean b) { 609 BoundedRangeModel m = getModel(); 610 boolean oldValue = m.getValueIsAdjusting(); 611 m.setValueIsAdjusting(b); 612 613 if ((oldValue != b) && (accessibleContext != null)) { 614 accessibleContext.firePropertyChange( 615 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 616 ((oldValue) ? AccessibleState.BUSY : null), 617 ((b) ? AccessibleState.BUSY : null)); 618 } 619 } 620 621 622 /** 623 * Sets the four BoundedRangeModel properties after forcing 624 * the arguments to obey the usual constraints: 625 * <pre> 626 * minimum ≤ value ≤ value+extent ≤ maximum 627 * </pre> 628 * 629 * @param newValue an int giving the current value 630 * @param newExtent an int giving the amount by which the value can "jump" 631 * @param newMin an int giving the minimum value 632 * @param newMax an int giving the maximum value 633 * 634 * @see BoundedRangeModel#setRangeProperties 635 * @see #setValue 636 * @see #setVisibleAmount 637 * @see #setMinimum 638 * @see #setMaximum 639 */ 640 public void setValues(int newValue, int newExtent, int newMin, int newMax) 641 { 642 BoundedRangeModel m = getModel(); 643 int oldValue = m.getValue(); 644 m.setRangeProperties(newValue, newExtent, newMin, newMax, m.getValueIsAdjusting()); 645 646 if (accessibleContext != null) { 647 accessibleContext.firePropertyChange( 648 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, 649 Integer.valueOf(oldValue), 650 Integer.valueOf(m.getValue())); 651 } 652 } 653 654 655 /** 656 * Adds an AdjustmentListener. Adjustment listeners are notified 657 * each time the scrollbar's model changes. Adjustment events are 658 * provided for backwards compatibility with java.awt.Scrollbar. 659 * <p> 660 * Note that the AdjustmentEvents type property will always have a 661 * placeholder value of AdjustmentEvent.TRACK because all changes 662 * to a BoundedRangeModels value are considered equivalent. To change 663 * the value of a BoundedRangeModel one just sets its value property, 664 * i.e. model.setValue(123). No information about the origin of the 665 * change, e.g. it's a block decrement, is provided. We don't try 666 * fabricate the origin of the change here. 667 * 668 * @param l the AdjustmentLister to add 669 * @see #removeAdjustmentListener 670 * @see BoundedRangeModel#addChangeListener 671 */ 672 public void addAdjustmentListener(AdjustmentListener l) { 673 listenerList.add(AdjustmentListener.class, l); 674 } 675 676 677 /** 678 * Removes an AdjustmentEvent listener. 679 * 680 * @param l the AdjustmentLister to remove 681 * @see #addAdjustmentListener 682 */ 683 public void removeAdjustmentListener(AdjustmentListener l) { 684 listenerList.remove(AdjustmentListener.class, l); 685 } 686 687 688 /** 689 * Returns an array of all the <code>AdjustmentListener</code>s added 690 * to this JScrollBar with addAdjustmentListener(). 691 * 692 * @return all of the <code>AdjustmentListener</code>s added or an empty 693 * array if no listeners have been added 694 * @since 1.4 695 */ 696 public AdjustmentListener[] getAdjustmentListeners() { 697 return listenerList.getListeners(AdjustmentListener.class); 698 } 699 700 701 /** 702 * Notify listeners that the scrollbar's model has changed. 703 * 704 * @param id an integer indicating the type of event. 705 * @param type an integer indicating the adjustment type. 706 * @param value the current value of the adjustment 707 * 708 * @see #addAdjustmentListener 709 * @see EventListenerList 710 */ 711 protected void fireAdjustmentValueChanged(int id, int type, int value) { 712 fireAdjustmentValueChanged(id, type, value, getValueIsAdjusting()); 713 } 714 715 /** 716 * Notify listeners that the scrollbar's model has changed. 717 * 718 * @see #addAdjustmentListener 719 * @see EventListenerList 720 */ 721 private void fireAdjustmentValueChanged(int id, int type, int value, 722 boolean isAdjusting) { 723 Object[] listeners = listenerList.getListenerList(); 724 AdjustmentEvent e = null; 725 for (int i = listeners.length - 2; i >= 0; i -= 2) { 726 if (listeners[i]==AdjustmentListener.class) { 727 if (e == null) { 728 e = new AdjustmentEvent(this, id, type, value, isAdjusting); 729 } 730 ((AdjustmentListener)listeners[i+1]).adjustmentValueChanged(e); 731 } 732 } 733 } 734 735 736 /** 737 * This class listens to ChangeEvents on the model and forwards 738 * AdjustmentEvents for the sake of backwards compatibility. 739 * Unfortunately there's no way to determine the proper 740 * type of the AdjustmentEvent as all updates to the model's 741 * value are considered equivalent. 742 */ 743 private class ModelListener implements ChangeListener, Serializable { 744 public void stateChanged(ChangeEvent e) { 745 Object obj = e.getSource(); 746 if (obj instanceof BoundedRangeModel) { 747 int id = AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED; 748 int type = AdjustmentEvent.TRACK; 749 BoundedRangeModel model = (BoundedRangeModel)obj; 750 int value = model.getValue(); 751 boolean isAdjusting = model.getValueIsAdjusting(); 752 fireAdjustmentValueChanged(id, type, value, isAdjusting); 753 } 754 } 755 } 756 757 // PENDING(hmuller) - the next three methods should be removed 758 759 /** 760 * The scrollbar is flexible along it's scrolling axis and 761 * rigid along the other axis. 762 */ 763 public Dimension getMinimumSize() { 764 Dimension pref = getPreferredSize(); 765 if (orientation == VERTICAL) { 766 return new Dimension(pref.width, 5); 767 } else { 768 return new Dimension(5, pref.height); 769 } 770 } 771 772 /** 773 * The scrollbar is flexible along it's scrolling axis and 774 * rigid along the other axis. 775 */ 776 public Dimension getMaximumSize() { 777 Dimension pref = getPreferredSize(); 778 if (getOrientation() == VERTICAL) { 779 return new Dimension(pref.width, Short.MAX_VALUE); 780 } else { 781 return new Dimension(Short.MAX_VALUE, pref.height); 782 } 783 } 784 785 /** 786 * Enables the component so that the knob position can be changed. 787 * When the disabled, the knob position cannot be changed. 788 * 789 * @param x a boolean value, where true enables the component and 790 * false disables it 791 */ 792 public void setEnabled(boolean x) { 793 super.setEnabled(x); 794 Component[] children = getComponents(); 795 for (Component child : children) { 796 child.setEnabled(x); 797 } 798 } 799 800 /** 801 * See readObject() and writeObject() in JComponent for more 802 * information about serialization in Swing. 803 */ 804 private void writeObject(ObjectOutputStream s) throws IOException { 805 s.defaultWriteObject(); 806 if (getUIClassID().equals(uiClassID)) { 807 byte count = JComponent.getWriteObjCounter(this); 808 JComponent.setWriteObjCounter(this, --count); 809 if (count == 0 && ui != null) { 810 ui.installUI(this); 811 } 812 } 813 } 814 815 816 /** 817 * Returns a string representation of this JScrollBar. This method 818 * is intended to be used only for debugging purposes, and the 819 * content and format of the returned string may vary between 820 * implementations. The returned string may be empty but may not 821 * be <code>null</code>. 822 * 823 * @return a string representation of this JScrollBar. 824 */ 825 protected String paramString() { 826 String orientationString = (orientation == HORIZONTAL ? 827 "HORIZONTAL" : "VERTICAL"); 828 829 return super.paramString() + 830 ",blockIncrement=" + blockIncrement + 831 ",orientation=" + orientationString + 832 ",unitIncrement=" + unitIncrement; 833 } 834 835 ///////////////// 836 // Accessibility support 837 //////////////// 838 839 /** 840 * Gets the AccessibleContext associated with this JScrollBar. 841 * For JScrollBar, the AccessibleContext takes the form of an 842 * AccessibleJScrollBar. 843 * A new AccessibleJScrollBar instance is created if necessary. 844 * 845 * @return an AccessibleJScrollBar that serves as the 846 * AccessibleContext of this JScrollBar 847 */ 848 public AccessibleContext getAccessibleContext() { 849 if (accessibleContext == null) { 850 accessibleContext = new AccessibleJScrollBar(); 851 } 852 return accessibleContext; 853 } 854 855 /** 856 * This class implements accessibility support for the 857 * <code>JScrollBar</code> class. It provides an implementation of the 858 * Java Accessibility API appropriate to scroll bar user-interface 859 * elements. 860 * <p> 861 * <strong>Warning:</strong> 862 * Serialized objects of this class will not be compatible with 863 * future Swing releases. The current serialization support is 864 * appropriate for short term storage or RMI between applications running 865 * the same version of Swing. As of 1.4, support for long term storage 866 * of all JavaBeans™ 867 * has been added to the <code>java.beans</code> package. 868 * Please see {@link java.beans.XMLEncoder}. 869 */ 870 @SuppressWarnings("serial") // Same-version serialization only 871 protected class AccessibleJScrollBar extends AccessibleJComponent 872 implements AccessibleValue { 873 874 /** 875 * Get the state set of this object. 876 * 877 * @return an instance of AccessibleState containing the current state 878 * of the object 879 * @see AccessibleState 880 */ 881 public AccessibleStateSet getAccessibleStateSet() { 882 AccessibleStateSet states = super.getAccessibleStateSet(); 883 if (getValueIsAdjusting()) { 884 states.add(AccessibleState.BUSY); 885 } 886 if (getOrientation() == VERTICAL) { 887 states.add(AccessibleState.VERTICAL); 888 } else { 889 states.add(AccessibleState.HORIZONTAL); 890 } 891 return states; 892 } 893 894 /** 895 * Get the role of this object. 896 * 897 * @return an instance of AccessibleRole describing the role of the 898 * object 899 */ 900 public AccessibleRole getAccessibleRole() { 901 return AccessibleRole.SCROLL_BAR; 902 } 903 904 /** 905 * Get the AccessibleValue associated with this object. In the 906 * implementation of the Java Accessibility API for this class, 907 * return this object, which is responsible for implementing the 908 * AccessibleValue interface on behalf of itself. 909 * 910 * @return this object 911 */ 912 public AccessibleValue getAccessibleValue() { 913 return this; 914 } 915 916 /** 917 * Get the accessible value of this object. 918 * 919 * @return The current value of this object. 920 */ 921 public Number getCurrentAccessibleValue() { 922 return Integer.valueOf(getValue()); 923 } 924 925 /** 926 * Set the value of this object as a Number. 927 * 928 * @return True if the value was set. 929 */ 930 public boolean setCurrentAccessibleValue(Number n) { 931 // TIGER - 4422535 932 if (n == null) { 933 return false; 934 } 935 setValue(n.intValue()); 936 return true; 937 } 938 939 /** 940 * Get the minimum accessible value of this object. 941 * 942 * @return The minimum value of this object. 943 */ 944 public Number getMinimumAccessibleValue() { 945 return Integer.valueOf(getMinimum()); 946 } 947 948 /** 949 * Get the maximum accessible value of this object. 950 * 951 * @return The maximum value of this object. 952 */ 953 public Number getMaximumAccessibleValue() { 954 // TIGER - 4422362 955 return model.getMaximum() - model.getExtent(); 956 } 957 958 } // AccessibleJScrollBar 959 }