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