1 /* 2 * Copyright (c) 1997, 2018, 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 javax.swing; 26 27 import java.io.Serializable; 28 import java.awt.Component; 29 import java.awt.Adjustable; 30 import java.awt.Dimension; 31 import java.awt.event.AdjustmentListener; 32 import java.awt.event.AdjustmentEvent; 33 import java.beans.JavaBean; 34 import java.beans.BeanProperty; 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.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 79 public 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 checkOrientation(int orientation)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 */ JScrollBar(int orientation, int value, int extent, int min, int max)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 */ JScrollBar(int orientation)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 */ JScrollBar()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") setUI(ScrollBarUI ui)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 */ getUI()221 public ScrollBarUI getUI() { 222 return (ScrollBarUI)ui; 223 } 224 225 226 /** 227 * Overrides <code>JComponent.updateUI</code>. 228 * @see JComponent#updateUI 229 */ updateUI()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 the string "ScrollBarUI" 239 * @see JComponent#getUIClassID 240 * @see UIDefaults#getUI 241 */ 242 @BeanProperty(bound = false) getUIClassID()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 */ getOrientation()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.") setOrientation(int 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 */ getModel()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.") setModel(BoundedRangeModel newModel)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 may override this method to compute 344 * a value, e.g. the change required to scroll one 345 * (variable height) line of 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 feel implementations that provide custom scrolling 353 * behavior 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 */ getUnitIncrement(int direction)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 * then most look and feel implementations will not provide scrolling 371 * to the right/down. 372 * <p> 373 * Some look and feel implementations that provide custom scrolling 374 * behavior ignore this property. 375 * 376 * @see #getUnitIncrement 377 */ 378 @BeanProperty(preferred = true, description 379 = "The scrollbar's unit increment.") setUnitIncrement(int unitIncrement)380 public void setUnitIncrement(int unitIncrement) { 381 int oldValue = this.unitIncrement; 382 this.unitIncrement = unitIncrement; 383 firePropertyChange("unitIncrement", oldValue, unitIncrement); 384 } 385 386 387 /** 388 * Returns the amount to change the scrollbar's value by, 389 * given a block (usually "page") up/down request. A ScrollBarUI 390 * implementation typically calls this method when the user clicks 391 * outside the scrollbar "knob" to scroll up or down by a large amount. 392 * Subclasses may override this method to compute a 393 * value, e.g. the change required to scroll one paragraph 394 * in a text document. 395 * <p> 396 * The JScrollPane component creates scrollbars (by default) 397 * that override this method and delegate to the viewports 398 * Scrollable view, if it has one. The Scrollable interface 399 * provides a more specialized version of this method. 400 * <p> 401 * Some look and feel implementations that provide custom scrolling 402 * behavior ignore this property. 403 * 404 * @param direction is -1 or 1 for up/down respectively 405 * @return the value of the blockIncrement property 406 * @see #setBlockIncrement 407 * @see #setValue 408 * @see Scrollable#getScrollableBlockIncrement 409 */ getBlockIncrement(int direction)410 public int getBlockIncrement(int direction) { 411 return blockIncrement; 412 } 413 414 415 /** 416 * Sets the blockIncrement property. 417 * <p> 418 * Note, that if the argument is equal to the value of Integer.MIN_VALUE, 419 * then most look and feel implementations will not provide scrolling 420 * to the right/down. 421 * <p> 422 * Some look and feel implementations that provide custom scrolling 423 * behavior ignore this property. 424 * 425 * @see #getBlockIncrement() 426 */ 427 @BeanProperty(preferred = true, description 428 = "The scrollbar's block increment.") setBlockIncrement(int blockIncrement)429 public void setBlockIncrement(int blockIncrement) { 430 int oldValue = this.blockIncrement; 431 this.blockIncrement = blockIncrement; 432 firePropertyChange("blockIncrement", oldValue, blockIncrement); 433 } 434 435 436 /** 437 * For backwards compatibility with java.awt.Scrollbar. 438 * @see Adjustable#getUnitIncrement 439 * @see #getUnitIncrement(int) 440 */ getUnitIncrement()441 public int getUnitIncrement() { 442 return unitIncrement; 443 } 444 445 446 /** 447 * For backwards compatibility with java.awt.Scrollbar. 448 * @see Adjustable#getBlockIncrement 449 * @see #getBlockIncrement(int) 450 */ getBlockIncrement()451 public int getBlockIncrement() { 452 return blockIncrement; 453 } 454 455 456 /** 457 * Returns the scrollbar's value. 458 * @return the model's value property 459 * @see #setValue 460 */ getValue()461 public int getValue() { 462 return getModel().getValue(); 463 } 464 465 466 /** 467 * Sets the scrollbar's value. This method just forwards the value 468 * to the model. 469 * 470 * @see #getValue 471 * @see BoundedRangeModel#setValue 472 */ 473 @BeanProperty(bound = false, preferred = true, description 474 = "The scrollbar's current value.") setValue(int value)475 public void setValue(int value) { 476 BoundedRangeModel m = getModel(); 477 int oldValue = m.getValue(); 478 m.setValue(value); 479 480 if (accessibleContext != null) { 481 accessibleContext.firePropertyChange( 482 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, 483 Integer.valueOf(oldValue), 484 Integer.valueOf(m.getValue())); 485 } 486 } 487 488 489 /** 490 * Returns the scrollbar's extent, aka its "visibleAmount". In many 491 * scrollbar look and feel implementations the size of the 492 * scrollbar "knob" or "thumb" is proportional to the extent. 493 * 494 * @return the value of the model's extent property 495 * @see #setVisibleAmount 496 */ getVisibleAmount()497 public int getVisibleAmount() { 498 return getModel().getExtent(); 499 } 500 501 502 /** 503 * Set the model's extent property. 504 * 505 * @see #getVisibleAmount 506 * @see BoundedRangeModel#setExtent 507 */ 508 @BeanProperty(bound = false, preferred = true, description 509 = "The amount of the view that is currently visible.") setVisibleAmount(int extent)510 public void setVisibleAmount(int extent) { 511 getModel().setExtent(extent); 512 } 513 514 515 /** 516 * Returns the minimum value supported by the scrollbar 517 * (usually zero). 518 * 519 * @return the value of the model's minimum property 520 * @see #setMinimum 521 */ getMinimum()522 public int getMinimum() { 523 return getModel().getMinimum(); 524 } 525 526 527 /** 528 * Sets the model's minimum property. 529 * 530 * @see #getMinimum 531 * @see BoundedRangeModel#setMinimum 532 */ 533 @BeanProperty(bound = false, preferred = true, description 534 = "The scrollbar's minimum value.") setMinimum(int minimum)535 public void setMinimum(int minimum) { 536 getModel().setMinimum(minimum); 537 } 538 539 540 /** 541 * The maximum value of the scrollbar is maximum - extent. 542 * 543 * @return the value of the model's maximum property 544 * @see #setMaximum 545 */ getMaximum()546 public int getMaximum() { 547 return getModel().getMaximum(); 548 } 549 550 551 /** 552 * Sets the model's maximum property. Note that the scrollbar's value 553 * can only be set to maximum - extent. 554 * 555 * @see #getMaximum 556 * @see BoundedRangeModel#setMaximum 557 */ 558 @BeanProperty(bound = false, preferred = true, description 559 = "The scrollbar's maximum value.") setMaximum(int maximum)560 public void setMaximum(int maximum) { 561 getModel().setMaximum(maximum); 562 } 563 564 565 /** 566 * True if the scrollbar knob is being dragged. 567 * 568 * @return the value of the model's valueIsAdjusting property 569 * @see #setValueIsAdjusting 570 */ getValueIsAdjusting()571 public boolean getValueIsAdjusting() { 572 return getModel().getValueIsAdjusting(); 573 } 574 575 576 /** 577 * Sets the model's valueIsAdjusting property. Scrollbar look and 578 * feel implementations should set this property to true when 579 * a knob drag begins, and to false when the drag ends. The 580 * scrollbar model will not generate ChangeEvents while 581 * valueIsAdjusting is true. 582 * 583 * @param b {@code true} if the upcoming changes to the value property are part of a series 584 * 585 * @see #getValueIsAdjusting 586 * @see BoundedRangeModel#setValueIsAdjusting 587 */ 588 @BeanProperty(bound = false, expert = true, description 589 = "True if the scrollbar thumb is being dragged.") setValueIsAdjusting(boolean b)590 public void setValueIsAdjusting(boolean b) { 591 BoundedRangeModel m = getModel(); 592 boolean oldValue = m.getValueIsAdjusting(); 593 m.setValueIsAdjusting(b); 594 595 if ((oldValue != b) && (accessibleContext != null)) { 596 accessibleContext.firePropertyChange( 597 AccessibleContext.ACCESSIBLE_STATE_PROPERTY, 598 ((oldValue) ? AccessibleState.BUSY : null), 599 ((b) ? AccessibleState.BUSY : null)); 600 } 601 } 602 603 604 /** 605 * Sets the four BoundedRangeModel properties after forcing 606 * the arguments to obey the usual constraints: 607 * <pre> 608 * minimum ≤ value ≤ value+extent ≤ maximum 609 * </pre> 610 * 611 * @param newValue an int giving the current value 612 * @param newExtent an int giving the amount by which the value can "jump" 613 * @param newMin an int giving the minimum value 614 * @param newMax an int giving the maximum value 615 * 616 * @see BoundedRangeModel#setRangeProperties 617 * @see #setValue 618 * @see #setVisibleAmount 619 * @see #setMinimum 620 * @see #setMaximum 621 */ setValues(int newValue, int newExtent, int newMin, int newMax)622 public void setValues(int newValue, int newExtent, int newMin, int newMax) 623 { 624 BoundedRangeModel m = getModel(); 625 int oldValue = m.getValue(); 626 m.setRangeProperties(newValue, newExtent, newMin, newMax, m.getValueIsAdjusting()); 627 628 if (accessibleContext != null) { 629 accessibleContext.firePropertyChange( 630 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, 631 Integer.valueOf(oldValue), 632 Integer.valueOf(m.getValue())); 633 } 634 } 635 636 637 /** 638 * Adds an AdjustmentListener. Adjustment listeners are notified 639 * each time the scrollbar's model changes. Adjustment events are 640 * provided for backwards compatibility with java.awt.Scrollbar. 641 * <p> 642 * Note that the AdjustmentEvents type property will always have a 643 * placeholder value of AdjustmentEvent.TRACK because all changes 644 * to a BoundedRangeModels value are considered equivalent. To change 645 * the value of a BoundedRangeModel one just sets its value property, 646 * i.e. model.setValue(123). No information about the origin of the 647 * change, e.g. it's a block decrement, is provided. We don't try to 648 * fabricate the origin of the change here. 649 * 650 * @param l the AdjustmentLister to add 651 * @see #removeAdjustmentListener 652 * @see BoundedRangeModel#addChangeListener 653 */ addAdjustmentListener(AdjustmentListener l)654 public void addAdjustmentListener(AdjustmentListener l) { 655 listenerList.add(AdjustmentListener.class, l); 656 } 657 658 659 /** 660 * Removes an AdjustmentEvent listener. 661 * 662 * @param l the AdjustmentLister to remove 663 * @see #addAdjustmentListener 664 */ removeAdjustmentListener(AdjustmentListener l)665 public void removeAdjustmentListener(AdjustmentListener l) { 666 listenerList.remove(AdjustmentListener.class, l); 667 } 668 669 670 /** 671 * Returns an array of all the <code>AdjustmentListener</code>s added 672 * to this JScrollBar with addAdjustmentListener(). 673 * 674 * @return all of the <code>AdjustmentListener</code>s added or an empty 675 * array if no listeners have been added 676 * @since 1.4 677 */ 678 @BeanProperty(bound = false) getAdjustmentListeners()679 public AdjustmentListener[] getAdjustmentListeners() { 680 return listenerList.getListeners(AdjustmentListener.class); 681 } 682 683 684 /** 685 * Notify listeners that the scrollbar's model has changed. 686 * 687 * @param id an integer indicating the type of event. 688 * @param type an integer indicating the adjustment type. 689 * @param value the current value of the adjustment 690 * 691 * @see #addAdjustmentListener 692 * @see EventListenerList 693 */ fireAdjustmentValueChanged(int id, int type, int value)694 protected void fireAdjustmentValueChanged(int id, int type, int value) { 695 fireAdjustmentValueChanged(id, type, value, getValueIsAdjusting()); 696 } 697 698 /** 699 * Notify listeners that the scrollbar's model has changed. 700 * 701 * @see #addAdjustmentListener 702 * @see EventListenerList 703 */ fireAdjustmentValueChanged(int id, int type, int value, boolean isAdjusting)704 private void fireAdjustmentValueChanged(int id, int type, int value, 705 boolean isAdjusting) { 706 Object[] listeners = listenerList.getListenerList(); 707 AdjustmentEvent e = null; 708 for (int i = listeners.length - 2; i >= 0; i -= 2) { 709 if (listeners[i]==AdjustmentListener.class) { 710 if (e == null) { 711 e = new AdjustmentEvent(this, id, type, value, isAdjusting); 712 } 713 ((AdjustmentListener)listeners[i+1]).adjustmentValueChanged(e); 714 } 715 } 716 } 717 718 719 /** 720 * This class listens to ChangeEvents on the model and forwards 721 * AdjustmentEvents for the sake of backwards compatibility. 722 * Unfortunately there's no way to determine the proper 723 * type of the AdjustmentEvent as all updates to the model's 724 * value are considered equivalent. 725 */ 726 private class ModelListener implements ChangeListener, Serializable { stateChanged(ChangeEvent e)727 public void stateChanged(ChangeEvent e) { 728 Object obj = e.getSource(); 729 if (obj instanceof BoundedRangeModel) { 730 int id = AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED; 731 int type = AdjustmentEvent.TRACK; 732 BoundedRangeModel model = (BoundedRangeModel)obj; 733 int value = model.getValue(); 734 boolean isAdjusting = model.getValueIsAdjusting(); 735 fireAdjustmentValueChanged(id, type, value, isAdjusting); 736 } 737 } 738 } 739 740 // PENDING(hmuller) - the next three methods should be removed 741 742 /** 743 * The scrollbar is flexible along it's scrolling axis and 744 * rigid along the other axis. 745 */ getMinimumSize()746 public Dimension getMinimumSize() { 747 Dimension pref = getPreferredSize(); 748 if (orientation == VERTICAL) { 749 return new Dimension(pref.width, 5); 750 } else { 751 return new Dimension(5, pref.height); 752 } 753 } 754 755 /** 756 * The scrollbar is flexible along it's scrolling axis and 757 * rigid along the other axis. 758 */ getMaximumSize()759 public Dimension getMaximumSize() { 760 Dimension pref = getPreferredSize(); 761 if (getOrientation() == VERTICAL) { 762 return new Dimension(pref.width, Short.MAX_VALUE); 763 } else { 764 return new Dimension(Short.MAX_VALUE, pref.height); 765 } 766 } 767 768 /** 769 * Enables the component so that the knob position can be changed. 770 * When the disabled, the knob position cannot be changed. 771 * 772 * @param x a boolean value, where true enables the component and 773 * false disables it 774 */ setEnabled(boolean x)775 public void setEnabled(boolean x) { 776 super.setEnabled(x); 777 Component[] children = getComponents(); 778 for (Component child : children) { 779 child.setEnabled(x); 780 } 781 } 782 783 /** 784 * See readObject() and writeObject() in JComponent for more 785 * information about serialization in Swing. 786 */ writeObject(ObjectOutputStream s)787 private void writeObject(ObjectOutputStream s) throws IOException { 788 s.defaultWriteObject(); 789 if (getUIClassID().equals(uiClassID)) { 790 byte count = JComponent.getWriteObjCounter(this); 791 JComponent.setWriteObjCounter(this, --count); 792 if (count == 0 && ui != null) { 793 ui.installUI(this); 794 } 795 } 796 } 797 798 799 /** 800 * Returns a string representation of this JScrollBar. This method 801 * is intended to be used only for debugging purposes, and the 802 * content and format of the returned string may vary between 803 * implementations. The returned string may be empty but may not 804 * be <code>null</code>. 805 * 806 * @return a string representation of this JScrollBar. 807 */ paramString()808 protected String paramString() { 809 String orientationString = (orientation == HORIZONTAL ? 810 "HORIZONTAL" : "VERTICAL"); 811 812 return super.paramString() + 813 ",blockIncrement=" + blockIncrement + 814 ",orientation=" + orientationString + 815 ",unitIncrement=" + unitIncrement; 816 } 817 818 ///////////////// 819 // Accessibility support 820 //////////////// 821 822 /** 823 * Gets the AccessibleContext associated with this JScrollBar. 824 * For JScrollBar, the AccessibleContext takes the form of an 825 * AccessibleJScrollBar. 826 * A new AccessibleJScrollBar instance is created if necessary. 827 * 828 * @return an AccessibleJScrollBar that serves as the 829 * AccessibleContext of this JScrollBar 830 */ 831 @BeanProperty(bound = false) getAccessibleContext()832 public AccessibleContext getAccessibleContext() { 833 if (accessibleContext == null) { 834 accessibleContext = new AccessibleJScrollBar(); 835 } 836 return accessibleContext; 837 } 838 839 /** 840 * This class implements accessibility support for the 841 * <code>JScrollBar</code> class. It provides an implementation of the 842 * Java Accessibility API appropriate to scroll bar user-interface 843 * elements. 844 * <p> 845 * <strong>Warning:</strong> 846 * Serialized objects of this class will not be compatible with 847 * future Swing releases. The current serialization support is 848 * appropriate for short term storage or RMI between applications running 849 * the same version of Swing. As of 1.4, support for long term storage 850 * of all JavaBeans™ 851 * has been added to the <code>java.beans</code> package. 852 * Please see {@link java.beans.XMLEncoder}. 853 */ 854 @SuppressWarnings("serial") // Same-version serialization only 855 protected class AccessibleJScrollBar extends AccessibleJComponent 856 implements AccessibleValue { 857 858 /** 859 * Get the state set of this object. 860 * 861 * @return an instance of AccessibleState containing the current state 862 * of the object 863 * @see AccessibleState 864 */ getAccessibleStateSet()865 public AccessibleStateSet getAccessibleStateSet() { 866 AccessibleStateSet states = super.getAccessibleStateSet(); 867 if (getValueIsAdjusting()) { 868 states.add(AccessibleState.BUSY); 869 } 870 if (getOrientation() == VERTICAL) { 871 states.add(AccessibleState.VERTICAL); 872 } else { 873 states.add(AccessibleState.HORIZONTAL); 874 } 875 return states; 876 } 877 878 /** 879 * Get the role of this object. 880 * 881 * @return an instance of AccessibleRole describing the role of the 882 * object 883 */ getAccessibleRole()884 public AccessibleRole getAccessibleRole() { 885 return AccessibleRole.SCROLL_BAR; 886 } 887 888 /** 889 * Get the AccessibleValue associated with this object. In the 890 * implementation of the Java Accessibility API for this class, 891 * return this object, which is responsible for implementing the 892 * AccessibleValue interface on behalf of itself. 893 * 894 * @return this object 895 */ getAccessibleValue()896 public AccessibleValue getAccessibleValue() { 897 return this; 898 } 899 900 /** 901 * Get the accessible value of this object. 902 * 903 * @return The current value of this object. 904 */ getCurrentAccessibleValue()905 public Number getCurrentAccessibleValue() { 906 return Integer.valueOf(getValue()); 907 } 908 909 /** 910 * Set the value of this object as a Number. 911 * 912 * @return True if the value was set. 913 */ setCurrentAccessibleValue(Number n)914 public boolean setCurrentAccessibleValue(Number n) { 915 // TIGER - 4422535 916 if (n == null) { 917 return false; 918 } 919 setValue(n.intValue()); 920 return true; 921 } 922 923 /** 924 * Get the minimum accessible value of this object. 925 * 926 * @return The minimum value of this object. 927 */ getMinimumAccessibleValue()928 public Number getMinimumAccessibleValue() { 929 return Integer.valueOf(getMinimum()); 930 } 931 932 /** 933 * Get the maximum accessible value of this object. 934 * 935 * @return The maximum value of this object. 936 */ getMaximumAccessibleValue()937 public Number getMaximumAccessibleValue() { 938 // TIGER - 4422362 939 return model.getMaximum() - model.getExtent(); 940 } 941 942 } // AccessibleJScrollBar 943 } 944