OSDN Git Service

* javax/swing/JToggleButton.java (ToggleButtonModel):
[pf3gnuchains/gcc-fork.git] / libjava / javax / swing / JSlider.java
1 /* JSlider.java --
2    Copyright (C) 2002, 2004 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 package javax.swing;
39
40 import java.awt.ComponentOrientation;
41 import java.awt.MenuContainer;
42 import java.awt.Dimension;
43 import java.awt.image.ImageObserver;
44 import java.io.IOException;
45 import java.io.ObjectOutputStream;
46 import java.io.Serializable;
47 import java.util.Dictionary;
48 import java.util.Enumeration;
49 import java.util.Hashtable;
50 import javax.accessibility.Accessible;
51 import javax.accessibility.AccessibleContext;
52 import javax.accessibility.AccessibleRole;
53 import javax.accessibility.AccessibleStateSet;
54 import javax.accessibility.AccessibleValue;
55 import javax.swing.event.ChangeEvent;
56 import javax.swing.event.ChangeListener;
57 import javax.swing.event.EventListenerList;
58 import javax.swing.plaf.SliderUI;
59
60
61 /**
62  * <p>
63  * The JSlider is a Swing component that allows selection of a value within a
64  * range by adjusting a thumb in a track. The values for the minimum,
65  * maximum, extent and value are stored in a {@link
66  * DefaultBoundedRangeModel}.
67  * </p>
68  * 
69  * <p>
70  * JSliders have the following properties:
71  * </p>
72  * 
73  * <table>
74  * <tr><th> Property         </td><th> Stored in </td><th> Bound? </td></tr>
75  * <tr><td> extent           </td><td> model     </td><td> no     </td></tr>
76  * <tr><td> inverted         </td><td> slider    </td><td> yes    </td></tr>
77  * <tr><td> labelTable       </td><td> slider    </td><td> yes    </td></tr>
78  * <tr><td> majorTickSpacing </td><td> slider    </td><td> yes    </td></tr> 
79  * <tr><td> maximum          </td><td> model     </td><td> no     </td></tr>
80  * <tr><td> minimum          </td><td> model     </td><td> no     </td></tr>
81  * <tr><td> minorTickSpacing </td><td> slider    </td><td> yes    </td></tr>
82  * <tr><td> model            </td><td> slider    </td><td> yes    </td></tr> 
83  * <tr><td> orientation      </td><td> slider    </td><td> yes    </td></tr>
84  * <tr><td> paintLabels      </td><td> slider    </td><td> yes    </td></tr>
85  * <tr><td> paintTicks       </td><td> slider    </td><td> yes    </td></tr>
86  * <tr><td> snapToTicks      </td><td> slider    </td><td> no     </td></tr>
87  * <tr><td> value            </td><td> model     </td><td> no     </td></tr>
88  * <tr><td> valueIsAdjusting </td><td> model     </td><td> no     </td></tr>
89  * </table>
90  * 
91  * <p>
92  * The various behavioral aspects of these properties follows:
93  * </p>
94  * 
95  * <ul>
96  * <li>
97  * When non-bound properties stored in the slider change, the slider fires
98  * ChangeEvents to its ChangeListeners.
99  * </li>
100  * <li>
101  * When bound properties stored in the slider change, the slider fires
102  * PropertyChangeEvents to its PropertyChangeListeners
103  * </li>
104  * <li>
105  * If any of the model's properties change, it fires a ChangeEvent to its
106  * ChangeListeners, which include the slider.
107  * </li>
108  * <li>
109  * If the slider receives a ChangeEvent from its model, it will propagate the
110  * ChangeEvent to its ChangeListeners, with the ChangeEvent's "source"
111  * property set to refer to the slider, rather than the model.
112  * </li>
113  * </ul>
114  */
115 public class JSlider extends JComponent implements SwingConstants, Accessible,
116                                                    ImageObserver,
117                                                    MenuContainer, Serializable
118 {
119   /** DOCUMENT ME! */
120   static final long serialVersionUID = -1441275936141218479L;
121
122   /**
123    * DOCUMENT ME!
124    */
125   protected class AccessibleJSlider extends JComponent.AccessibleJComponent
126     implements AccessibleValue
127   {
128     /**
129      * Creates a new AccessibleJSlider object.
130      *
131      * @param value0 DOCUMENT ME!
132      */
133     protected AccessibleJSlider(JSlider value0)
134     {
135       super(value0);
136     }
137
138     /**
139      * DOCUMENT ME!
140      *
141      * @return DOCUMENT ME!
142      */
143     public AccessibleStateSet getAccessibleStateSet()
144     {
145       return null;
146     }
147
148     /**
149      * DOCUMENT ME!
150      *
151      * @return DOCUMENT ME!
152      */
153     public AccessibleRole getAccessibleRole()
154     {
155       return null;
156     }
157
158     /**
159      * DOCUMENT ME!
160      *
161      * @return DOCUMENT ME!
162      */
163     public AccessibleValue getAccessibleValue()
164     {
165       return null;
166     }
167
168     /**
169      * DOCUMENT ME!
170      *
171      * @return DOCUMENT ME!
172      */
173     public Number getCurrentAccessibleValue()
174     {
175       return null;
176     }
177
178     /**
179      * setCurrentAccessibleValue
180      *
181      * @param value0 TODO
182      *
183      * @return boolean
184      */
185     public boolean setCurrentAccessibleValue(Number value0)
186     {
187       return false;
188     }
189
190     /**
191      * getMinimumAccessibleValue
192      *
193      * @return Number
194      */
195     public Number getMinimumAccessibleValue()
196     {
197       return null;
198     }
199
200     /**
201      * getMaximumAccessibleValue
202      *
203      * @return Number
204      */
205     public Number getMaximumAccessibleValue()
206     {
207       return null;
208     }
209   }
210
211   /** Fired in a PropertyChangeEvent when the "inverted" property changes. */
212   public static final String INVERTED_CHANGED_PROPERTY = "inverted";
213
214   /** Fired in a PropertyChangeEvent when the "labelTable" property changes. */
215   public static final String LABEL_TABLE_CHANGED_PROPERTY = "labelTable";
216
217   /**
218    * Fired in a PropertyChangeEvent when the "majorTickSpacing" property
219    * changes.
220    */
221   public static final String MAJOR_TICK_SPACING_CHANGED_PROPERTY = "majorTickSpacing";
222
223   /**
224    * Fired in a PropertyChangeEvent when the "minorTickSpacing" property
225    * changes.
226    */
227   public static final String MINOR_TICK_SPACING_CHANGED_PROPERTY = "minorTickSpacing";
228
229   /** Fired in a PropertyChangeEvent when the "model" property changes. */
230   public static final String MODEL_CHANGED_PROPERTY = "model";
231
232   /** Fired in a PropertyChangeEvent when the "orientation" property changes. */
233   public static final String ORIENTATION_CHANGED_PROPERTY = "orientation";
234
235   /** Fired in a PropertyChangeEvent when the "paintLabels" property changes. */
236   public static final String PAINT_LABELS_CHANGED_PROPERTY = "paintLabels";
237
238   /** Fired in a PropertyChangeEvent when the "paintTicks" property changes. */
239   public static final String PAINT_TICKS_CHANGED_PROPERTY = "paintTicks";
240   
241   /** Whether or not this slider paints its ticks. */
242   private transient boolean paintTicks = false;
243
244   /** Whether or not this slider paints its track. */
245   private transient boolean paintTrack = true;
246
247   /** Whether or not this slider paints its labels. */
248   private transient boolean paintLabels = false;
249
250   /**
251    * A dictionary of (Integer, Component) pairs where each Component is a
252    * JLabel and the Integer determines where the label will be painted.
253    */
254   private transient Dictionary labelTable;
255
256   /** The model used to describe the slider. */
257   protected BoundedRangeModel sliderModel;
258
259   /** The space between major ticks. */
260   protected int majorTickSpacing;
261
262   /** The space between minor ticks. */
263   protected int minorTickSpacing;
264
265   /** Whether the slider snaps its values to ticks. */
266   protected boolean snapToTicks = true;
267
268   /** The orientation of the slider. */
269   protected int orientation = HORIZONTAL;
270
271   /** Whether the slider is inverted. */
272   private transient boolean isInverted;
273
274   /** The ChangeListener that listens to the model. */
275   protected ChangeListener changeListener;
276
277   /** The ChangeEvent that is passed to all listeners of this slider. */
278   protected transient ChangeEvent changeEvent;
279
280   /**
281    * Creates a new horizontal JSlider object with a minimum of 0, a maximum of
282    * 100, and a value of 50.
283    */
284   public JSlider()
285   {
286     this(HORIZONTAL, 0, 100, 50);
287   }
288
289   /**
290    * Creates a new JSlider object with the given orientation and a minimum of
291    * 0, a maximum of 100, and a value of 50.
292    *
293    * @param orientation The orientation of the slider.
294    */
295   public JSlider(int orientation)
296   {
297     this(orientation, 0, 100, 50);
298   }
299
300   /**
301    * Creates a new horizontal JSlider object with the given maximum and
302    * minimum and a value that is  halfway between the minimum and the
303    * maximum.
304    *
305    * @param minimum The minimum value of the JSlider.
306    * @param maximum The maximum value of the JSlider.
307    */
308   public JSlider(int minimum, int maximum)
309   {
310     this(HORIZONTAL, minimum, maximum, (maximum - minimum) / 2);
311   }
312
313   /**
314    * Creates a new horizontal JSlider object with the given minimum, maximum,
315    * and value.
316    *
317    * @param minimum The minimum value of the JSlider.
318    * @param maximum The maximum value of the JSlider.
319    * @param value The initial value of the JSlider.
320    */
321   public JSlider(int minimum, int maximum, int value)
322   {
323     this(HORIZONTAL, minimum, maximum, value);
324   }
325
326   /**
327    * Creates a new JSlider object with the given orientation, minimum,
328    * maximum, and value.
329    *
330    * @param orientation The orientation of the JSlider.
331    * @param minimum The minimum value of the JSlider.
332    * @param maximum The maximum value of the JSlider.
333    * @param value The initial value of the JSlider.
334    */
335   public JSlider(int orientation, int minimum, int maximum, int value)
336   {
337     sliderModel = new DefaultBoundedRangeModel(value, 0, minimum, maximum);
338     if (orientation != HORIZONTAL && orientation != VERTICAL)
339       throw new IllegalArgumentException(orientation + " is not a legal orientation");
340     this.orientation = orientation;
341     changeListener = createChangeListener();
342     sliderModel.addChangeListener(changeListener);
343     updateUI();
344   }
345
346   /**
347    * Creates a new horizontal JSlider object with the given model.
348    *
349    * @param model The model the slider will be created with.
350    */
351   public JSlider(BoundedRangeModel model)
352   {
353     if (model == null)
354       sliderModel = new DefaultBoundedRangeModel(50, 0, 0, 100);
355     else
356       sliderModel = model;
357     changeListener = createChangeListener();
358     sliderModel.addChangeListener(changeListener);
359     updateUI();
360   }
361
362   /**
363    * This method returns the current value of the slider.
364    *
365    * @return The value of the slider stored in the model.
366    */
367   public int getValue()
368   {
369     return sliderModel.getValue();
370   }
371
372   /**
373    * This method sets the value of the slider.
374    *
375    * @param value The slider's new value.
376    */
377   public void setValue(int value)
378   {
379     sliderModel.setValue(value);
380   }
381
382   /**
383    * This method returns the slider's UI delegate.
384    *
385    * @return The slider's UI delegate.
386    */
387   public SliderUI getUI()
388   {
389     return (SliderUI) ui;
390   }
391
392   /**
393    * This method sets the slider's UI delegate.
394    *
395    * @param ui A SliderUI object to use with this slider.
396    */
397   public void setUI(SliderUI ui)
398   {
399     super.setUI(ui);
400   }
401
402   /**
403    * This method sets this slider's UI to the UIManager's default for the
404    * current look and feel.
405    */
406   public void updateUI()
407   {
408     setUI((SliderUI) UIManager.getUI(this));
409     invalidate();
410     repaint();
411   }
412
413   /**
414    * This method returns a name to identify which look and feel class will be
415    * the UI delegate for the slider.
416    *
417    * @return The L&F classID. "SliderUI"
418    */
419   public String getUIClassID()
420   {
421     return "SliderUI";
422   }
423
424   /**
425    * Creates a ChangeListener for this Slider.
426    *
427    * @return A new ChangeListener.
428    */
429   protected ChangeListener createChangeListener()
430   {
431     return new ChangeListener()
432       {
433         public void stateChanged(ChangeEvent ce)
434         {
435           // No need to trigger a repaint since the UI listens to the model
436           // as well. All we need to do is pass on the stateChanged event 
437           // to our listeners.
438           fireStateChanged();
439         }
440       };
441   }
442
443   /**
444    * This method registers a listener to this slider. The listener will be
445    * informed of new ChangeEvents.
446    *
447    * @param listener The listener to register.
448    */
449   public void addChangeListener(ChangeListener listener)
450   {
451     listenerList.add(ChangeListener.class, listener);
452   }
453
454   /**
455    * This method removes a listener from this slider.
456    *
457    * @param listener The listener to remove.
458    */
459   public void removeChangeListener(ChangeListener listener)
460   {
461     listenerList.remove(ChangeListener.class, listener);
462   }
463
464   /**
465    * This method is called whenever the model fires a ChangeEvent. It should
466    * propagate the ChangeEvent to its listeners with a new ChangeEvent that
467    * identifies the slider as the source.
468    */
469   protected void fireStateChanged()
470   {
471     Object[] changeListeners = listenerList.getListenerList();
472     if (changeEvent == null)
473       changeEvent = new ChangeEvent(this);
474     for (int i = changeListeners.length - 2; i >= 0; i -= 2)
475       {
476         if (changeListeners[i] == ChangeListener.class)
477           ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
478       }
479   }
480
481   /**
482    * This method returns an array of all ChangeListeners listening to this
483    * slider.
484    *
485    * @return An array of ChangeListeners listening to this slider.
486    */
487   public ChangeListener[] getChangeListeners()
488   {
489     return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
490   }
491
492   /**
493    * This method returns the model of the slider.
494    *
495    * @return The slider's model.
496    */
497   public BoundedRangeModel getModel()
498   {
499     return sliderModel;
500   }
501
502   /**
503    * This method changes the "model" property. It also needs  to unregister
504    * any listeners to the old model and register any listeners to the new
505    * model.
506    *
507    * @param model The model to use with the slider.
508    */
509   public void setModel(BoundedRangeModel model)
510   {
511     // I didn't do the null pointer check on purpose.
512     // If you try it with Sun's, it'll go ahead and set it to null
513     // and bork the next time it tries to access the model.
514     if (model != sliderModel)
515       {
516         BoundedRangeModel oldModel = sliderModel;
517         sliderModel = model;
518         oldModel.removeChangeListener(changeListener);
519         sliderModel.addChangeListener(changeListener);
520         firePropertyChange(MODEL_CHANGED_PROPERTY, oldModel, sliderModel);
521       }
522   }
523
524   /**
525    * This method returns the minimum value of the slider.
526    *
527    * @return The minimum value of the slider.
528    */
529   public int getMinimum()
530   {
531     return sliderModel.getMinimum();
532   }
533
534   /**
535    * This method sets the minimum value of the slider.
536    *
537    * @param minimum The minimum value of the slider.
538    */
539   public void setMinimum(int minimum)
540   {
541     sliderModel.setMinimum(minimum);
542   }
543
544   /**
545    * This method returns the maximum value of the slider.
546    *
547    * @return The maximum value of the slider.
548    */
549   public int getMaximum()
550   {
551     return sliderModel.getMaximum();
552   }
553
554   /**
555    * This method sets the maximum value of the slider.
556    *
557    * @param maximum The maximum value of the slider.
558    */
559   public void setMaximum(int maximum)
560   {
561     sliderModel.setMaximum(maximum);
562   }
563
564   /**
565    * This method returns this slider's isAdjusting value which is true if the
566    * thumb is being dragged.
567    *
568    * @return The slider's isAdjusting value.
569    */
570   public boolean getValueIsAdjusting()
571   {
572     return sliderModel.getValueIsAdjusting();
573   }
574
575   /**
576    * This method sets the isAdjusting value for the slider.
577    *
578    * @param adjusting The slider's isAdjusting value.
579    */
580   public void setValueIsAdjusting(boolean adjusting)
581   {
582     sliderModel.setValueIsAdjusting(adjusting);
583   }
584
585   /**
586    * This method returns the extent value for this slider.
587    *
588    * @return The extent value for this slider.
589    */
590   public int getExtent()
591   {
592     return sliderModel.getExtent();
593   }
594
595   /**
596    * This method sets the extent value for this slider.
597    *
598    * @param extent The extent value for this slider.
599    */
600   public void setExtent(int extent)
601   {
602     sliderModel.setExtent(extent);
603   }
604
605   /**
606    * This method returns the slider orientation.
607    *
608    * @return The orientation of the slider.
609    */
610   public int getOrientation()
611   {
612     return orientation;
613   }
614
615   /**
616    * This method changes the "orientation" property of this slider. If the
617    * orientation is not VERTICAL or HORIZONTAL, this method does nothing.
618    *
619    * @param orientation The orientation of this slider.
620    */
621   public void setOrientation(int orientation)
622   {
623     if (orientation != VERTICAL && orientation != HORIZONTAL)
624       throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL");
625     if (orientation != this.orientation)
626       {
627         int oldOrientation = this.orientation;
628         this.orientation = orientation;
629         firePropertyChange(ORIENTATION_CHANGED_PROPERTY, oldOrientation,
630                            this.orientation);
631       }
632   }
633
634   /**
635    * This method returns the label table for this slider.
636    *
637    * @return The label table for this slider.
638    */
639   public Dictionary getLabelTable()
640   {
641     return labelTable;
642   }
643
644   /**
645    * This method changes the "labelTable" property of this slider.
646    *
647    * @param table The label table for this slider.
648    */
649   public void setLabelTable(Dictionary table)
650   {
651     if (table != labelTable)
652       {
653         Dictionary oldTable = labelTable;
654         labelTable = table;
655         firePropertyChange(LABEL_TABLE_CHANGED_PROPERTY, oldTable, labelTable);
656       }
657   }
658
659   /**
660    * This method is called to reset UI delegates for the labels in the
661    * labelTable to a default for the current look and feel.
662    */
663   protected void updateLabelUIs()
664   {
665     if (labelTable == null)
666       return;
667     for (Enumeration list = labelTable.elements(); list.hasMoreElements();)
668       {
669         JLabel label = (JLabel) list.nextElement();
670         label.updateUI();
671       }
672   }
673
674   /**
675    * Creates a hashtable of (Integer, JLabel) pairs that can be used as a
676    * label table for this slider. The labels will start from the sliders
677    * minimum and increase by the increment. Each  label will have a text
678    * string indicating their integer value.
679    *
680    * @param increment The increment to between labels.
681    *
682    * @return A hashtable with the labels and their keys.
683    */
684   public Hashtable createStandardLabels(int increment)
685   {
686     return createStandardLabels(increment, sliderModel.getMinimum());
687   }
688
689   /**
690    * Creates a hashtable of (Integer, JLabel) pairs that can be used as a
691    * label table for this slider. The labels will start from the given start
692    * value and increase by the increment. Each  label will have a text string
693    * indicating their integer value.
694    *
695    * @param increment The increment to between labels.
696    * @param start The value to start from.
697    *
698    * @return A hashtable with the labels and their keys.
699    */
700   public Hashtable createStandardLabels(int increment, int start)
701   {
702     Hashtable table = new Hashtable();
703     JLabel label;
704     Dimension dim;
705
706     int max = sliderModel.getMaximum();
707
708     for (int i = start; i <= max; i += increment)
709       {
710         label = new JLabel(String.valueOf(i));
711         label.setVerticalAlignment(CENTER);
712         label.setHorizontalAlignment(CENTER);
713         
714         // Make sure these labels have the width and height
715         // they want.
716         dim = label.getPreferredSize();
717         label.setBounds(label.getX(), label.getY(),
718                         (int) dim.getWidth(),
719                         (int) dim.getHeight()); 
720         table.put(new Integer(i), label);
721       }
722     return table;
723   }
724
725   /**
726    * This method returns whether the slider is inverted. Horizontal sliders
727    * that are not inverted will have the minimums on the left. If they are
728    * inverted, the minimums will be  on the right. Vertical sliders that are
729    * not inverted will have the minimums at the bottom. If they are inverted,
730    * the minimums will be at the top.
731    *
732    * @return Whether this slider is inverted.
733    */
734   public boolean getInverted()
735   {
736     return isInverted;
737   }
738
739   /**
740    * This method changes the "inverted" property for this slider.Horizontal
741    * sliders  that are not inverted will have the minimums on the left. If
742    * they are inverted, the minimums will be  on the right. Vertical sliders
743    * that are not inverted will have the minimums at the bottom. If they are
744    * inverted, the minimums will be at the top. However, if the slider's
745    * componentOrientation is set to RIGHT_TO_LEFT, then everything gets
746    * reversed again.
747    *
748    * @param inverted Whether the slider should be inverted.
749    */
750   public void setInverted(boolean inverted)
751   {
752     if (isInverted != inverted)
753       {
754         boolean oldInverted = isInverted;
755         isInverted = inverted;
756         firePropertyChange(INVERTED_CHANGED_PROPERTY, oldInverted, isInverted);
757       }
758   }
759
760   /**
761    * This method returns the amount of units between each major tick mark.
762    *
763    * @return The amount of units between each major tick mark.
764    */
765   public int getMajorTickSpacing()
766   {
767     return majorTickSpacing;
768   }
769
770   /**
771    * This method changes the "majorTickSpacing" property for this slider. The
772    * major tick spacing is the amount of units between each major tick mark.
773    *
774    * @param spacing The amount of units between each major tick mark.
775    */
776   public void setMajorTickSpacing(int spacing)
777   {
778     if (majorTickSpacing != spacing)
779       {
780         int oldSpacing = majorTickSpacing;
781         majorTickSpacing = spacing;
782         firePropertyChange(MAJOR_TICK_SPACING_CHANGED_PROPERTY, oldSpacing,
783                            majorTickSpacing);
784       }
785   }
786
787   /**
788    * This method returns the amount of units between each minor tick mark.
789    *
790    * @return The amount of units between each minor tick mark.
791    */
792   public int getMinorTickSpacing()
793   {
794     return minorTickSpacing;
795   }
796
797   /**
798    * This method changes the "minorTickSpacing" property for this slider. The
799    * minor tick spacing is the amount of units between each minor tick mark.
800    *
801    * @param spacing The amount of units between each minor tick mark.
802    */
803   public void setMinorTickSpacing(int spacing)
804   {
805     if (minorTickSpacing != spacing)
806       {
807         int oldSpacing = minorTickSpacing;
808         minorTickSpacing = spacing;
809         firePropertyChange(MINOR_TICK_SPACING_CHANGED_PROPERTY, oldSpacing,
810                            minorTickSpacing);
811       }
812   }
813
814   /**
815    * This method returns whether this slider is snapping to ticks.  Sliders
816    * that snap to ticks will automatically move the thumb to the nearest tick
817    * mark.
818    *
819    * @return Whether this slider snaps to ticks.
820    */
821   public boolean getSnapToTicks()
822   {
823     return snapToTicks;
824   }
825
826   /**
827    * This method sets whether this slider will snap to ticks. Sliders that
828    * snap to ticks will automatically move the thumb to the nearest tick
829    * mark.
830    *
831    * @param snap Whether this slider snaps to ticks.
832    */
833   public void setSnapToTicks(boolean snap)
834   {
835     if (snap != snapToTicks)
836       {
837         snapToTicks = snap;
838         fireStateChanged();
839       }
840   }
841
842   /**
843    * This method returns whether the slider will paint its tick marks. In
844    * addition to setting this property to true, one of minor tick spacing  or
845    * major tick spacing must be set to a value greater than 0 in order for
846    * ticks to be painted.
847    *
848    * @return Whether ticks will be painted.
849    */
850   public boolean getPaintTicks()
851   {
852     return paintTicks;
853   }
854
855   /**
856    * This method changes the "paintTicks" property for this slider. In
857    * addition to setting this property to true, one of minor tick spacing  or
858    * major tick spacing must be set to a value greater than 0 in order for
859    * ticks to be painted.
860    *
861    * @param paint Whether ticks will be painted.
862    */
863   public void setPaintTicks(boolean paint)
864   {
865     if (paint != paintTicks)
866       {
867         boolean oldPaintTicks = paintTicks;
868         paintTicks = paint;
869         firePropertyChange(PAINT_TICKS_CHANGED_PROPERTY, oldPaintTicks,
870                            paintTicks);
871       }
872   }
873
874   /**
875    * This method returns whether the track will be painted.
876    *
877    * @return Whether the track will be painted.
878    */
879   public boolean getPaintTrack()
880   {
881     return paintTrack;
882   }
883
884   /**
885    * This method sets whether the track will be painted.
886    *
887    * @param paint Whether the track will be painted.
888    */
889   public void setPaintTrack(boolean paint)
890   {
891     paintTrack = paint;
892   }
893
894   /**
895    * This method returns whether labels will be painted.
896    *
897    * @return Whether labels will be painted.
898    */
899   public boolean getPaintLabels()
900   {
901     return paintLabels;
902   }
903
904   /**
905    * This method changes the "paintLabels" property.
906    *
907    * @param paint Whether labels will be painted.
908    */
909   public void setPaintLabels(boolean paint)
910   {
911     if (paint != paintLabels)
912       {
913         boolean oldPaintLabels = paintLabels;
914         paintLabels = paint;
915         firePropertyChange(PAINT_LABELS_CHANGED_PROPERTY, oldPaintLabels,
916                            paintLabels);
917       }
918   }
919
920   /**
921    * This method is used primarily for debugging purposes and returns a string
922    * that can be used to represent this slider.
923    *
924    * @return A string representing this slider.
925    */
926   protected String paramString()
927   {
928     return "JSlider";
929   }
930
931   /**
932    * DOCUMENT ME!
933    *
934    * @return DOCUMENT ME!
935    */
936   public AccessibleContext getAccessibleContext()
937   {
938     if (accessibleContext == null)
939       accessibleContext = new AccessibleJSlider(this);
940     return accessibleContext;
941   }
942 }