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