KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > JSlider


1 /*
2  * @(#)JSlider.java 1.105 04/05/12
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing;
9
10 import javax.swing.border.*;
11 import javax.swing.event.*;
12 import javax.swing.plaf.*;
13 import javax.accessibility.*;
14
15 import java.io.Serializable JavaDoc;
16 import java.io.ObjectOutputStream JavaDoc;
17 import java.io.ObjectInputStream JavaDoc;
18 import java.io.IOException JavaDoc;
19
20 import java.util.*;
21 import java.beans.*;
22
23
24 /**
25  * A component that lets the user graphically select a value by sliding
26  * a knob within a bounded interval. The slider can show both
27  * major tick marks and minor tick marks between them. The number of
28  * values between the tick marks is controlled with
29  * <code>setMajorTickSpacing</code> and <code>setMinorTickSpacing</code>.
30  * <p>
31  * For further information and examples see
32  * <a
33  href="http://java.sun.com/docs/books/tutorial/uiswing/components/slider.html">How to Use Sliders</a>,
34  * a section in <em>The Java Tutorial.</em>
35  * <p>
36  * <strong>Warning:</strong>
37  * Serialized objects of this class will not be compatible with
38  * future Swing releases. The current serialization support is
39  * appropriate for short term storage or RMI between applications running
40  * the same version of Swing. As of 1.4, support for long term storage
41  * of all JavaBeans<sup><font size="-2">TM</font></sup>
42  * has been added to the <code>java.beans</code> package.
43  * Please see {@link java.beans.XMLEncoder}.
44  *
45  * @beaninfo
46  * attribute: isContainer false
47  * description: A component that supports selecting a integer value from a range.
48  *
49  * @version 1.105 05/12/04
50  * @author David Kloba
51  */

52 public class JSlider extends JComponent JavaDoc implements SwingConstants JavaDoc, Accessible {
53     /**
54      * @see #getUIClassID
55      * @see #readObject
56      */

57     private static final String JavaDoc uiClassID = "SliderUI";
58
59     private boolean paintTicks = false;
60     private boolean paintTrack = true;
61     private boolean paintLabels = false;
62     private boolean isInverted = false;
63
64     /**
65      * The data model that handles the numeric maximum value,
66      * minimum value, and current-position value for the slider.
67      */

68     protected BoundedRangeModel JavaDoc sliderModel;
69
70     /**
71      * The number of values between the major tick marks -- the
72      * larger marks that break up the minor tick marks.
73      */

74     protected int majorTickSpacing;
75
76     /**
77      * The number of values between the minor tick marks -- the
78      * smaller marks that occur between the major tick marks.
79      * @see #setMinorTickSpacing
80      */

81     protected int minorTickSpacing;
82
83     /**
84      * If true, the knob (and the data value it represents)
85      * resolve to the closest tick mark next to where the user
86      * positioned the knob. The default is false.
87      * @see #setSnapToTicks
88      */

89     protected boolean snapToTicks = false;
90
91     /**
92      * If true, the knob (and the data value it represents)
93      * resolve to the closest slider value next to where the user
94      * positioned the knob.
95      */

96     boolean snapToValue = true;
97
98     /**
99      * @see #setOrientation
100      */

101     protected int orientation;
102
103
104     /**
105      */

106     private Dictionary labelTable;
107
108
109     /**
110      * The changeListener (no suffix) is the listener we add to the
111      * Sliders model. By default this listener just forwards events
112      * to ChangeListeners (if any) added directly to the slider.
113      *
114      * @see #addChangeListener
115      * @see #createChangeListener
116      */

117     protected ChangeListener changeListener = createChangeListener();
118
119
120     /**
121      * Only one <code>ChangeEvent</code> is needed per slider instance since the
122      * event's only (read-only) state is the source property. The source
123      * of events generated here is always "this". The event is lazily
124      * created the first time that an event notification is fired.
125      *
126      * @see #fireStateChanged
127      */

128     protected transient ChangeEvent changeEvent = null;
129
130
131     private void checkOrientation(int orientation) {
132         switch (orientation) {
133         case VERTICAL:
134         case HORIZONTAL:
135             break;
136         default:
137             throw new IllegalArgumentException JavaDoc("orientation must be one of: VERTICAL, HORIZONTAL");
138         }
139     }
140
141
142     /**
143      * Creates a horizontal slider with the range 0 to 100 and
144      * an initial value of 50.
145      */

146     public JSlider() {
147         this(HORIZONTAL, 0, 100, 50);
148     }
149
150
151     /**
152      * Creates a slider using the specified orientation with the
153      * range 0 to 100 and an initial value of 50.
154      */

155     public JSlider(int orientation) {
156         this(orientation, 0, 100, 50);
157     }
158
159
160     /**
161      * Creates a horizontal slider using the specified min and max
162      * with an initial value equal to the average of the min plus max.
163      */

164     public JSlider(int min, int max) {
165         this(HORIZONTAL, min, max, (min + max) / 2);
166     }
167
168
169     /**
170      * Creates a horizontal slider using the specified min, max and value.
171      */

172     public JSlider(int min, int max, int value) {
173         this(HORIZONTAL, min, max, value);
174     }
175
176
177     /**
178      * Creates a slider with the specified orientation and the
179      * specified minimum, maximum, and initial values.
180      *
181      * @exception IllegalArgumentException if orientation is not one of VERTICAL, HORIZONTAL
182      *
183      * @see #setOrientation
184      * @see #setMinimum
185      * @see #setMaximum
186      * @see #setValue
187      */

188     public JSlider(int orientation, int min, int max, int value)
189     {
190         checkOrientation(orientation);
191         this.orientation = orientation;
192         sliderModel = new DefaultBoundedRangeModel JavaDoc(value, 0, min, max);
193         sliderModel.addChangeListener(changeListener);
194         updateUI();
195     }
196
197
198     /**
199      * Creates a horizontal slider using the specified
200      * BoundedRangeModel.
201      */

202     public JSlider(BoundedRangeModel JavaDoc brm)
203     {
204         this.orientation = JSlider.HORIZONTAL;
205         setModel(brm);
206         sliderModel.addChangeListener(changeListener);
207         updateUI();
208     }
209
210
211     /**
212      * Gets the UI object which implements the L&F for this component.
213      *
214      * @return the SliderUI object that implements the Slider L&F
215      */

216     public SliderUI getUI() {
217         return(SliderUI)ui;
218     }
219
220
221     /**
222      * Sets the UI object which implements the L&F for this component.
223      *
224      * @param ui the SliderUI L&F object
225      * @see UIDefaults#getUI
226      * @beaninfo
227      * bound: true
228      * hidden: true
229      * attribute: visualUpdate true
230      * description: The UI object that implements the slider's LookAndFeel.
231      */

232     public void setUI(SliderUI ui) {
233         super.setUI(ui);
234     }
235
236
237     /**
238      * Resets the UI property to a value from the current look and feel.
239      *
240      * @see JComponent#updateUI
241      */

242     public void updateUI() {
243         updateLabelUIs();
244         setUI((SliderUI)UIManager.getUI(this));
245     }
246
247
248     /**
249      * Returns the name of the L&F class that renders this component.
250      *
251      * @return "SliderUI"
252      * @see JComponent#getUIClassID
253      * @see UIDefaults#getUI
254      */

255     public String JavaDoc getUIClassID() {
256         return uiClassID;
257     }
258
259
260     /**
261      * We pass Change events along to the listeners with the
262      * the slider (instead of the model itself) as the event source.
263      */

264     private class ModelListener implements ChangeListener, Serializable JavaDoc {
265         public void stateChanged(ChangeEvent e) {
266             fireStateChanged();
267         }
268     }
269
270
271     /**
272      * Subclasses that want to handle model ChangeEvents differently
273      * can override this method to return their own ChangeListener
274      * implementation. The default ChangeListener just forwards
275      * ChangeEvents to the ChangeListeners added directly to the slider.
276      *
277      * @see #fireStateChanged
278      */

279     protected ChangeListener createChangeListener() {
280         return new ModelListener();
281     }
282
283
284     /**
285      * Adds a ChangeListener to the slider.
286      *
287      * @param l the ChangeListener to add
288      * @see #fireStateChanged
289      * @see #removeChangeListener
290      */

291     public void addChangeListener(ChangeListener l) {
292         listenerList.add(ChangeListener.class, l);
293     }
294
295
296     /**
297      * Removes a ChangeListener from the slider.
298      *
299      * @param l the ChangeListener to remove
300      * @see #fireStateChanged
301      * @see #addChangeListener
302
303      */

304     public void removeChangeListener(ChangeListener l) {
305         listenerList.remove(ChangeListener.class, l);
306     }
307
308
309     /**
310      * Returns an array of all the <code>ChangeListener</code>s added
311      * to this JSlider with addChangeListener().
312      *
313      * @return all of the <code>ChangeListener</code>s added or an empty
314      * array if no listeners have been added
315      * @since 1.4
316      */

317     public ChangeListener[] getChangeListeners() {
318         return (ChangeListener[])listenerList.getListeners(
319                 ChangeListener.class);
320     }
321
322
323     /**
324      * Send a ChangeEvent, whose source is this Slider, to
325      * each listener. This method method is called each time
326      * a ChangeEvent is received from the model.
327      *
328      * @see #addChangeListener
329      * @see EventListenerList
330      */

331     protected void fireStateChanged() {
332         Object JavaDoc[] listeners = listenerList.getListenerList();
333         for (int i = listeners.length - 2; i >= 0; i -= 2) {
334             if (listeners[i]==ChangeListener.class) {
335                 if (changeEvent == null) {
336                     changeEvent = new ChangeEvent(this);
337                 }
338                 ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
339             }
340         }
341     }
342
343
344     /**
345      * Returns data model that handles the sliders three
346      * fundamental properties: minimum, maximum, value.
347      *
348      * @see #setModel
349      */

350     public BoundedRangeModel JavaDoc getModel() {
351         return sliderModel;
352     }
353
354
355     /**
356      * Sets the model that handles the sliders three
357      * fundamental properties: minimum, maximum, value.
358      *
359      * @see #getModel
360      * @beaninfo
361      * bound: true
362      * description: The sliders BoundedRangeModel.
363      */

364     public void setModel(BoundedRangeModel JavaDoc newModel)
365     {
366         BoundedRangeModel JavaDoc oldModel = getModel();
367
368         if (oldModel != null) {
369             oldModel.removeChangeListener(changeListener);
370         }
371
372         sliderModel = newModel;
373
374         if (newModel != null) {
375             newModel.addChangeListener(changeListener);
376
377             if (accessibleContext != null) {
378                 accessibleContext.firePropertyChange(
379                                                     AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
380                                                     (oldModel == null
381                                                      ? null : new Integer JavaDoc(oldModel.getValue())),
382                                                     (newModel == null
383                                                      ? null : new Integer JavaDoc(newModel.getValue())));
384             }
385         }
386
387         firePropertyChange("model", oldModel, sliderModel);
388     }
389
390
391     /**
392      * Returns the sliders value.
393      * @return the models value property
394      * @see #setValue
395      */

396     public int getValue() {
397         return getModel().getValue();
398     }
399
400
401     /**
402      * Sets the sliders current value. This method just forwards
403      * the value to the model.
404      *
405      * @see #getValue
406      * @beaninfo
407      * preferred: true
408      * description: The sliders current value.
409      */

410     public void setValue(int n) {
411         BoundedRangeModel JavaDoc m = getModel();
412         int oldValue = m.getValue();
413         if (oldValue == n) {
414             return;
415         }
416         m.setValue(n);
417
418         if (accessibleContext != null) {
419             accessibleContext.firePropertyChange(
420                                                 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
421                                                 new Integer JavaDoc(oldValue),
422                                                 new Integer JavaDoc(m.getValue()));
423         }
424     }
425
426
427     /**
428      * Returns the minimum value supported by the slider.
429      *
430      * @return the value of the models minimum property
431      * @see #setMinimum
432      */

433     public int getMinimum() {
434         return getModel().getMinimum();
435     }
436
437
438     /**
439      * Sets the models minimum property.
440      *
441      * @see #getMinimum
442      * @see BoundedRangeModel#setMinimum
443      * @beaninfo
444      * bound: true
445      * preferred: true
446      * description: The sliders minimum value.
447      */

448     public void setMinimum(int minimum) {
449         int oldMin = getModel().getMinimum();
450         getModel().setMinimum(minimum);
451         firePropertyChange( "minimum", new Integer JavaDoc( oldMin ), new Integer JavaDoc( minimum ) );
452     }
453
454
455     /**
456      * Returns the maximum value supported by the slider.
457      *
458      * @return the value of the models maximum property
459      * @see #setMaximum
460      */

461     public int getMaximum() {
462         return getModel().getMaximum();
463     }
464
465
466     /**
467      * Sets the models maximum property.
468      *
469      * @see #getMaximum
470      * @see BoundedRangeModel#setMaximum
471      * @beaninfo
472      * bound: true
473      * preferred: true
474      * description: The sliders maximum value.
475      */

476     public void setMaximum(int maximum) {
477         int oldMax = getModel().getMaximum();
478         getModel().setMaximum(maximum);
479         firePropertyChange( "maximum", new Integer JavaDoc( oldMax ), new Integer JavaDoc( maximum ) );
480     }
481
482
483     /**
484      * True if the slider knob is being dragged.
485      *
486      * @return the value of the models valueIsAdjusting property
487      * @see #setValueIsAdjusting
488      */

489     public boolean getValueIsAdjusting() {
490         return getModel().getValueIsAdjusting();
491     }
492
493
494     /**
495      * Sets the models valueIsAdjusting property. Slider look and
496      * feel implementations should set this property to true when
497      * a knob drag begins, and to false when the drag ends. The
498      * slider model will not generate ChangeEvents while
499      * valueIsAdjusting is true.
500      *
501      * @see #getValueIsAdjusting
502      * @see BoundedRangeModel#setValueIsAdjusting
503      * @beaninfo
504      * expert: true
505      * description: True if the slider knob is being dragged.
506      */

507     public void setValueIsAdjusting(boolean b) {
508         BoundedRangeModel JavaDoc m = getModel();
509         boolean oldValue = m.getValueIsAdjusting();
510         m.setValueIsAdjusting(b);
511
512         if ((oldValue != b) && (accessibleContext != null)) {
513             accessibleContext.firePropertyChange(
514                                                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
515                                                 ((oldValue) ? AccessibleState.BUSY : null),
516                                                 ((b) ? AccessibleState.BUSY : null));
517         }
518     }
519
520
521     /**
522      * Returns the "extent" -- the range of values "covered" by the knob.
523      * @return an int representing the extent
524      * @see #setExtent
525      * @see BoundedRangeModel#getExtent
526      */

527     public int getExtent() {
528         return getModel().getExtent();
529     }
530
531
532     /**
533      * Sets the size of the range "covered" by the knob. Most look
534      * and feel implementations will change the value by this amount
535      * if the user clicks on either side of the knob.
536      *
537      * @see #getExtent
538      * @see BoundedRangeModel#setExtent
539      * @beaninfo
540      * expert: true
541      * description: Size of the range covered by the knob.
542      */

543     public void setExtent(int extent) {
544         getModel().setExtent(extent);
545     }
546
547
548     /**
549      * Return this slider's vertical or horizontal orientation.
550      * @return VERTICAL or HORIZONTAL
551      * @see #setOrientation
552      */

553     public int getOrientation() {
554         return orientation;
555     }
556
557
558     /**
559      * Set the scrollbars orientation to either VERTICAL or HORIZONTAL.
560      *
561      * @exception IllegalArgumentException if orientation is not one of VERTICAL, HORIZONTAL
562      * @see #getOrientation
563      * @beaninfo
564      * preferred: true
565      * bound: true
566      * attribute: visualUpdate true
567      * description: Set the scrollbars orientation to either VERTICAL or HORIZONTAL.
568      * enum: VERTICAL JSlider.VERTICAL
569      * HORIZONTAL JSlider.HORIZONTAL
570      *
571      */

572     public void setOrientation(int orientation)
573     {
574         checkOrientation(orientation);
575         int oldValue = this.orientation;
576         this.orientation = orientation;
577         firePropertyChange("orientation", oldValue, orientation);
578
579         if ((oldValue != orientation) && (accessibleContext != null)) {
580             accessibleContext.firePropertyChange(
581                                                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
582                                                 ((oldValue == VERTICAL)
583                                                  ? AccessibleState.VERTICAL : AccessibleState.HORIZONTAL),
584                                                 ((orientation == VERTICAL)
585                                                  ? AccessibleState.VERTICAL : AccessibleState.HORIZONTAL));
586         }
587         if (orientation != oldValue) {
588             revalidate();
589         }
590     }
591
592
593
594     /**
595      * Returns the dictionary of what labels to draw at which values.
596      *
597      * @return the <code>Dictionary</code> containing labels and
598      * where to draw them
599      */

600     public Dictionary getLabelTable() {
601 /*
602         if ( labelTable == null && getMajorTickSpacing() > 0 ) {
603             setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
604         }
605 */

606         return labelTable;
607     }
608
609
610     /**
611      * Used to specify what label will be drawn at any given value.
612      * The key-value pairs are of this format:
613      * <code>{ Integer value, java.swing.JComponent label }</code>.
614      *
615      * @see #createStandardLabels
616      * @see #getLabelTable
617      * @beaninfo
618      * hidden: true
619      * bound: true
620      * attribute: visualUpdate true
621      * description: Specifies what labels will be drawn for any given value.
622      */

623     public void setLabelTable( Dictionary labels ) {
624         Dictionary oldTable = labelTable;
625         labelTable = labels;
626         updateLabelUIs();
627         firePropertyChange("labelTable", oldTable, labelTable );
628         if (labels != oldTable) {
629             revalidate();
630             repaint();
631         }
632     }
633
634
635     /**
636      * Resets the UI property to a value from the current look and feel.
637      *
638      * @see JComponent#updateUI
639      */

640     protected void updateLabelUIs() {
641         if ( getLabelTable() == null ) {
642             return;
643         }
644         Enumeration labels = getLabelTable().keys();
645         while ( labels.hasMoreElements() ) {
646             Object JavaDoc value = getLabelTable().get( labels.nextElement() );
647             if ( value instanceof JComponent JavaDoc ) {
648                 JComponent JavaDoc component = (JComponent JavaDoc)value;
649                 component.updateUI();
650                 component.setSize( component.getPreferredSize() );
651             }
652         }
653     }
654
655
656     /**
657      * Creates a hashtable that will draw text labels starting at the
658      * slider minimum using the increment specified.
659      * If you call <code>createStandardLabels( 10 )</code>
660      * and the slider minimum is
661      * zero, then it will make labels for the values 0, 10, 20, 30, and so on.
662      * @see #setLabelTable
663      */

664     public Hashtable createStandardLabels( int increment ) {
665         return createStandardLabels( increment, getMinimum() );
666     }
667
668
669     /**
670      * Creates a hashtable that will draw text labels starting at the
671      * start point
672      * specified using the increment specified. If you call
673      * <code>createStandardLabels( 10, 2 )</code>,
674      * then it will make labels for the values 2, 12, 22, 32, and so on.
675      * @see #setLabelTable
676      * @exception IllegalArgumentException if slider label start point
677      * out of range or if label increment is less than or equal
678      * to zero
679      */

680     public Hashtable createStandardLabels( int increment, int start ) {
681         if ( start > getMaximum() || start < getMinimum() ) {
682             throw new IllegalArgumentException JavaDoc( "Slider label start point out of range." );
683         }
684
685         if ( increment <= 0 ) {
686             throw new IllegalArgumentException JavaDoc( "Label incremement must be > 0" );
687         }
688
689         class SmartHashtable extends Hashtable implements PropertyChangeListener {
690             int increment = 0;
691             int start = 0;
692             boolean startAtMin = false;
693
694             class LabelUIResource extends JLabel JavaDoc implements UIResource {
695                 public LabelUIResource( String JavaDoc text, int alignment ) {
696                     super( text, alignment );
697                     setName("Slider.label");
698                 }
699             }
700
701             public SmartHashtable( int increment, int start ) {
702                 super();
703                 this.increment = increment;
704                 this.start = start;
705                 startAtMin = start == getMinimum();
706                 createLabels();
707             }
708
709             public void propertyChange( PropertyChangeEvent e ) {
710                 if ( e.getPropertyName().equals( "minimum" ) && startAtMin ) {
711                     start = getMinimum();
712                 }
713
714                 if ( e.getPropertyName().equals( "minimum" ) ||
715                      e.getPropertyName().equals( "maximum" ) ) {
716
717                     Enumeration keys = getLabelTable().keys();
718                     Object JavaDoc key = null;
719                     Hashtable hashtable = new Hashtable();
720
721                     // Save the labels that were added by the developer
722
while ( keys.hasMoreElements() ) {
723                         key = keys.nextElement();
724                         Object JavaDoc value = getLabelTable().get( key );
725                         if ( !(value instanceof LabelUIResource) ) {
726                             hashtable.put( key, value );
727                         }
728                     }
729
730                     clear();
731                     createLabels();
732
733                     // Add the saved labels
734
keys = hashtable.keys();
735                     while ( keys.hasMoreElements() ) {
736                         key = keys.nextElement();
737                         put( key, hashtable.get( key ) );
738                     }
739
740                     ((JSlider JavaDoc)e.getSource()).setLabelTable( this );
741                 }
742             }
743
744             void createLabels() {
745                 for ( int labelIndex = start; labelIndex <= getMaximum(); labelIndex += increment ) {
746                     put( new Integer JavaDoc( labelIndex ), new LabelUIResource( ""+labelIndex, JLabel.CENTER ) );
747                 }
748             }
749         }
750
751         SmartHashtable table = new SmartHashtable( increment, start );
752
753         if ( getLabelTable() != null && (getLabelTable() instanceof PropertyChangeListener) ) {
754             removePropertyChangeListener( (PropertyChangeListener)getLabelTable() );
755         }
756
757         addPropertyChangeListener( table );
758
759         return table;
760     }
761
762
763     /**
764      * Returns true if the value-range shown for the slider is reversed,
765      *
766      * @return true if the slider values are reversed from their normal order
767      * @see #setInverted
768      */

769     public boolean getInverted() {
770         return isInverted;
771     }
772
773
774     /**
775      * Specify true to reverse the value-range shown for the slider and false to
776      * put the value range in the normal order. The order depends on the
777      * slider's <code>ComponentOrientation</code> property. Normal (non-inverted)
778      * horizontal sliders with a <code>ComponentOrientation</code> value of
779      * <code>LEFT_TO_RIGHT</code> have their maximum on the right.
780      * Normal horizontal sliders with a <code>ComponentOrientation</code> value of
781      * <code>RIGHT_TO_LEFT</code> have their maximum on the left. Normal vertical
782      * sliders have their maximum on the top. These labels are reversed when the
783      * slider is inverted.
784      *
785      * @param b true to reverse the slider values from their normal order
786      * @beaninfo
787      * bound: true
788      * attribute: visualUpdate true
789      * description: If true reverses the slider values from their normal order
790      *
791      */

792     public void setInverted( boolean b ) {
793         boolean oldValue = isInverted;
794         isInverted = b;
795         firePropertyChange("inverted", oldValue, isInverted);
796         if (b != oldValue) {
797             repaint();
798         }
799     }
800
801
802     /**
803      * This method returns the major tick spacing. The number that is returned
804      * represents the distance, measured in values, between each major tick mark.
805      * If you have a slider with a range from 0 to 50 and the major tick spacing
806      * is set to 10, you will get major ticks next to the following values:
807      * 0, 10, 20, 30, 40, 50.
808      *
809      * @return the number of values between major ticks
810      * @see #setMajorTickSpacing
811      */

812     public int getMajorTickSpacing() {
813         return majorTickSpacing;
814     }
815
816
817     /**
818      * This method sets the major tick spacing. The number that is passed-in
819      * represents the distance, measured in values, between each major tick mark.
820      * If you have a slider with a range from 0 to 50 and the major tick spacing
821      * is set to 10, you will get major ticks next to the following values:
822      * 0, 10, 20, 30, 40, 50.
823      *
824      * @see #getMajorTickSpacing
825      * @beaninfo
826      * bound: true
827      * attribute: visualUpdate true
828      * description: Sets the number of values between major tick marks.
829      *
830      */

831     public void setMajorTickSpacing(int n) {
832         int oldValue = majorTickSpacing;
833         majorTickSpacing = n;
834         if ( labelTable == null && getMajorTickSpacing() > 0 && getPaintLabels() ) {
835             setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
836         }
837         firePropertyChange("majorTickSpacing", oldValue, majorTickSpacing);
838         if (majorTickSpacing != oldValue && getPaintTicks()) {
839             repaint();
840         }
841     }
842
843
844
845     /**
846      * This method returns the minor tick spacing. The number that is returned
847      * represents the distance, measured in values, between each minor tick mark.
848      * If you have a slider with a range from 0 to 50 and the minor tick spacing
849      * is set to 10, you will get minor ticks next to the following values:
850      * 0, 10, 20, 30, 40, 50.
851      *
852      * @return the number of values between minor ticks
853      * @see #getMinorTickSpacing
854      */

855     public int getMinorTickSpacing() {
856         return minorTickSpacing;
857     }
858
859
860     /**
861      * This method sets the minor tick spacing. The number that is passed-in
862      * represents the distance, measured in values, between each minor tick mark.
863      * If you have a slider with a range from 0 to 50 and the minor tick spacing
864      * is set to 10, you will get minor ticks next to the following values:
865      * 0, 10, 20, 30, 40, 50.
866      *
867      * @see #getMinorTickSpacing
868      * @beaninfo
869      * bound: true
870      * attribute: visualUpdate true
871      * description: Sets the number of values between minor tick marks.
872      */

873     public void setMinorTickSpacing(int n) {
874         int oldValue = minorTickSpacing;
875         minorTickSpacing = n;
876         firePropertyChange("minorTickSpacing", oldValue, minorTickSpacing);
877         if (minorTickSpacing != oldValue && getPaintTicks()) {
878             repaint();
879         }
880     }
881
882
883     /**
884      * Returns true if the knob (and the data value it represents)
885      * resolve to the closest tick mark next to where the user
886      * positioned the knob.
887      *
888      * @return true if the value snaps to the nearest tick mark, else false
889      * @see #setSnapToTicks
890      */

891     public boolean getSnapToTicks() {
892         return snapToTicks;
893     }
894
895
896     /**
897      * Returns true if the knob (and the data value it represents)
898      * resolve to the closest slider value next to where the user
899      * positioned the knob.
900      *
901      * @return true if the value snaps to the nearest slider value, else false
902      */

903     boolean getSnapToValue() {
904         return snapToValue;
905     }
906
907
908     /**
909      * Specifying true makes the knob (and the data value it represents)
910      * resolve to the closest tick mark next to where the user
911      * positioned the knob.
912      *
913      * @param b true to snap the knob to the nearest tick mark
914      * @see #getSnapToTicks
915      * @beaninfo
916      * bound: true
917      * description: If true snap the knob to the nearest tick mark.
918      */

919     public void setSnapToTicks(boolean b) {
920         boolean oldValue = snapToTicks;
921         snapToTicks = b;
922         firePropertyChange("snapToTicks", oldValue, snapToTicks);
923     }
924
925
926     /**
927      * Specifying true makes the knob (and the data value it represents)
928      * resolve to the closest slider value next to where the user
929      * positioned the knob. If the snapToTicks property has been set to
930      * true, the snap-to-ticks behavior will prevail.
931      *
932      * @param b true to snap the knob to the nearest slider value
933      * @see #getSnapToValue
934      * @see #setSnapToTicks
935      * @beaninfo
936      * bound: true
937      * description: If true snap the knob to the nearest slider value.
938      */

939     void setSnapToValue(boolean b) {
940         boolean oldValue = snapToValue;
941         snapToValue = b;
942         firePropertyChange("snapToValue", oldValue, snapToValue);
943     }
944
945
946     /**
947      * Tells if tick marks are to be painted.
948      * @return true if tick marks are painted, else false
949      * @see #setPaintTicks
950      */

951     public boolean getPaintTicks() {
952         return paintTicks;
953     }
954
955
956     /**
957      * Determines whether tick marks are painted on the slider.
958      * @see #getPaintTicks
959      * @beaninfo
960      * bound: true
961      * attribute: visualUpdate true
962      * description: If true tick marks are painted on the slider.
963      */

964     public void setPaintTicks(boolean b) {
965         boolean oldValue = paintTicks;
966         paintTicks = b;
967         firePropertyChange("paintTicks", oldValue, paintTicks);
968         if (paintTicks != oldValue) {
969             revalidate();
970             repaint();
971         }
972     }
973
974     /**
975      * Tells if the track (area the slider slides in) is to be painted.
976      * @return true if track is painted, else false
977      * @see #setPaintTrack
978      */

979     public boolean getPaintTrack() {
980         return paintTrack;
981     }
982
983
984     /**
985      * Determines whether the track is painted on the slider.
986      * @see #getPaintTrack
987      * @beaninfo
988      * bound: true
989      * attribute: visualUpdate true
990      * description: If true, the track is painted on the slider.
991      */

992     public void setPaintTrack(boolean b) {
993         boolean oldValue = paintTrack;
994         paintTrack = b;
995         firePropertyChange("paintTrack", oldValue, paintTrack);
996         if (paintTrack != oldValue) {
997             repaint();
998         }
999     }
1000
1001
1002    /**
1003     * Tells if labels are to be painted.
1004     * @return true if labels are painted, else false
1005     * @see #setPaintLabels
1006     */

1007    public boolean getPaintLabels() {
1008        return paintLabels;
1009    }
1010
1011
1012    /**
1013     * Determines whether labels are painted on the slider.
1014     * @see #getPaintLabels
1015     * @beaninfo
1016     * bound: true
1017     * attribute: visualUpdate true
1018     * description: If true labels are painted on the slider.
1019     */

1020    public void setPaintLabels(boolean b) {
1021        boolean oldValue = paintLabels;
1022        paintLabels = b;
1023        if ( labelTable == null && getMajorTickSpacing() > 0 ) {
1024            setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
1025        }
1026        firePropertyChange("paintLabels", oldValue, paintLabels);
1027        if (paintLabels != oldValue) {
1028            revalidate();
1029            repaint();
1030        }
1031    }
1032
1033
1034    /**
1035     * See readObject() and writeObject() in JComponent for more
1036     * information about serialization in Swing.
1037     */

1038    private void writeObject(ObjectOutputStream JavaDoc s) throws IOException JavaDoc {
1039        s.defaultWriteObject();
1040        if (getUIClassID().equals(uiClassID)) {
1041            byte count = JComponent.getWriteObjCounter(this);
1042            JComponent.setWriteObjCounter(this, --count);
1043            if (count == 0 && ui != null) {
1044                ui.installUI(this);
1045            }
1046        }
1047    }
1048
1049
1050    /**
1051     * Returns a string representation of this JSlider. This method
1052     * is intended to be used only for debugging purposes, and the
1053     * content and format of the returned string may vary between
1054     * implementations. The returned string may be empty but may not
1055     * be <code>null</code>.
1056     *
1057     * @return a string representation of this JSlider.
1058     */

1059    protected String JavaDoc paramString() {
1060        String JavaDoc paintTicksString = (paintTicks ?
1061                                   "true" : "false");
1062        String JavaDoc paintTrackString = (paintTrack ?
1063                                   "true" : "false");
1064        String JavaDoc paintLabelsString = (paintLabels ?
1065                                    "true" : "false");
1066        String JavaDoc isInvertedString = (isInverted ?
1067                                   "true" : "false");
1068        String JavaDoc snapToTicksString = (snapToTicks ?
1069                                    "true" : "false");
1070        String JavaDoc snapToValueString = (snapToValue ?
1071                                    "true" : "false");
1072        String JavaDoc orientationString = (orientation == HORIZONTAL ?
1073                                    "HORIZONTAL" : "VERTICAL");
1074
1075        return super.paramString() +
1076        ",isInverted=" + isInvertedString +
1077        ",majorTickSpacing=" + majorTickSpacing +
1078        ",minorTickSpacing=" + minorTickSpacing +
1079        ",orientation=" + orientationString +
1080        ",paintLabels=" + paintLabelsString +
1081        ",paintTicks=" + paintTicksString +
1082        ",paintTrack=" + paintTrackString +
1083        ",snapToTicks=" + snapToTicksString +
1084        ",snapToValue=" + snapToValueString;
1085    }
1086
1087
1088/////////////////
1089
// Accessibility support
1090
////////////////
1091

1092    /**
1093     * Gets the AccessibleContext associated with this JSlider.
1094     * For sliders, the AccessibleContext takes the form of an
1095     * AccessibleJSlider.
1096     * A new AccessibleJSlider instance is created if necessary.
1097     *
1098     * @return an AccessibleJSlider that serves as the
1099     * AccessibleContext of this JSlider
1100     */

1101    public AccessibleContext getAccessibleContext() {
1102        if (accessibleContext == null) {
1103            accessibleContext = new AccessibleJSlider();
1104        }
1105        return accessibleContext;
1106    }
1107
1108    /**
1109     * This class implements accessibility support for the
1110     * <code>JSlider</code> class. It provides an implementation of the
1111     * Java Accessibility API appropriate to slider user-interface elements.
1112     * <p>
1113     * <strong>Warning:</strong>
1114     * Serialized objects of this class will not be compatible with
1115     * future Swing releases. The current serialization support is
1116     * appropriate for short term storage or RMI between applications running
1117     * the same version of Swing. As of 1.4, support for long term storage
1118     * of all JavaBeans<sup><font size="-2">TM</font></sup>
1119     * has been added to the <code>java.beans</code> package.
1120     * Please see {@link java.beans.XMLEncoder}.
1121     */

1122    protected class AccessibleJSlider extends AccessibleJComponent
1123    implements AccessibleValue {
1124
1125        /**
1126         * Get the state set of this object.
1127         *
1128         * @return an instance of AccessibleState containing the current state
1129         * of the object
1130         * @see AccessibleState
1131         */

1132        public AccessibleStateSet getAccessibleStateSet() {
1133            AccessibleStateSet states = super.getAccessibleStateSet();
1134            if (getValueIsAdjusting()) {
1135                states.add(AccessibleState.BUSY);
1136            }
1137            if (getOrientation() == VERTICAL) {
1138                states.add(AccessibleState.VERTICAL);
1139            }
1140            else {
1141                states.add(AccessibleState.HORIZONTAL);
1142            }
1143            return states;
1144        }
1145
1146        /**
1147         * Get the role of this object.
1148         *
1149         * @return an instance of AccessibleRole describing the role of the object
1150         */

1151        public AccessibleRole getAccessibleRole() {
1152            return AccessibleRole.SLIDER;
1153        }
1154
1155        /**
1156         * Get the AccessibleValue associated with this object. In the
1157         * implementation of the Java Accessibility API for this class,
1158     * return this object, which is responsible for implementing the
1159         * AccessibleValue interface on behalf of itself.
1160     *
1161     * @return this object
1162         */

1163        public AccessibleValue getAccessibleValue() {
1164            return this;
1165        }
1166
1167        /**
1168         * Get the accessible value of this object.
1169         *
1170         * @return The current value of this object.
1171         */

1172        public Number JavaDoc getCurrentAccessibleValue() {
1173            return new Integer JavaDoc(getValue());
1174        }
1175
1176        /**
1177         * Set the value of this object as a Number.
1178         *
1179         * @return True if the value was set.
1180         */

1181        public boolean setCurrentAccessibleValue(Number JavaDoc n) {
1182        // TIGER - 4422535
1183
if (n == null) {
1184        return false;
1185        }
1186        setValue(n.intValue());
1187        return true;
1188        }
1189
1190        /**
1191         * Get the minimum accessible value of this object.
1192         *
1193         * @return The minimum value of this object.
1194         */

1195        public Number JavaDoc getMinimumAccessibleValue() {
1196            return new Integer JavaDoc(getMinimum());
1197        }
1198
1199        /**
1200         * Get the maximum accessible value of this object.
1201         *
1202         * @return The maximum value of this object.
1203         */

1204        public Number JavaDoc getMaximumAccessibleValue() {
1205        // TIGER - 4422362
1206
BoundedRangeModel JavaDoc model = JSlider.this.getModel();
1207            return new Integer JavaDoc(model.getMaximum() - model.getExtent());
1208        }
1209    } // AccessibleJSlider
1210
}
1211
Popular Tags