< prev index next >

src/java.desktop/share/classes/javax/swing/JSlider.java

Print this page




  29 import javax.swing.plaf.*;
  30 import javax.accessibility.*;
  31 
  32 import java.io.Serializable;
  33 import java.io.ObjectOutputStream;
  34 import java.io.IOException;
  35 
  36 import java.awt.*;
  37 import java.util.*;
  38 import java.beans.*;
  39 
  40 
  41 /**
  42  * A component that lets the user graphically select a value by sliding
  43  * a knob within a bounded interval. The knob is always positioned
  44  * at the points that match integer values within the specified interval.
  45  * <p>
  46  * The slider can show both
  47  * major tick marks, and minor tick marks between the major ones.  The number of
  48  * values between the tick marks is controlled with
  49  * <code>setMajorTickSpacing</code> and <code>setMinorTickSpacing</code>.
  50  * Painting of tick marks is controlled by {@code setPaintTicks}.
  51  * <p>
  52  * Sliders can also print text labels at regular intervals (or at
  53  * arbitrary locations) along the slider track.  Painting of labels is
  54  * controlled by {@code setLabelTable} and {@code setPaintLabels}.
  55  * <p>
  56  * For further information and examples see
  57  * <a
  58  href="http://docs.oracle.com/javase/tutorial/uiswing/components/slider.html">How to Use Sliders</a>,
  59  * a section in <em>The Java Tutorial.</em>
  60  * <p>
  61  * <strong>Warning:</strong> Swing is not thread safe. For more
  62  * information see <a
  63  * href="package-summary.html#threading">Swing's Threading
  64  * Policy</a>.
  65  * <p>
  66  * <strong>Warning:</strong>
  67  * Serialized objects of this class will not be compatible with
  68  * future Swing releases. The current serialization support is
  69  * appropriate for short term storage or RMI between applications running
  70  * the same version of Swing.  As of 1.4, support for long term storage
  71  * of all JavaBeans&trade;
  72  * has been added to the <code>java.beans</code> package.
  73  * Please see {@link java.beans.XMLEncoder}.
  74  *
  75  * @beaninfo
  76  *      attribute: isContainer false
  77  *    description: A component that supports selecting a integer value from a range.
  78  *
  79  * @author David Kloba
  80  * @since 1.2
  81  */
  82 @SuppressWarnings("serial") // Same-version serialization only
  83 public class JSlider extends JComponent implements SwingConstants, Accessible {
  84     /**
  85      * @see #getUIClassID
  86      * @see #readObject
  87      */
  88     private static final String uiClassID = "SliderUI";
  89 
  90     private boolean paintTicks = false;
  91     private boolean paintTrack = true;
  92     private boolean paintLabels = false;


 141     @SuppressWarnings("rawtypes")
 142     private Dictionary labelTable;
 143     // For better source compatibility, the labelTable field and
 144     // associated getter and setter methods are being left as raw
 145     // types.
 146 
 147     /**
 148      * The changeListener (no suffix) is the listener we add to the
 149      * slider's model.  This listener is initialized to the
 150      * {@code ChangeListener} returned from {@code createChangeListener},
 151      * which by default just forwards events
 152      * to {@code ChangeListener}s (if any) added directly to the slider.
 153      *
 154      * @see #addChangeListener
 155      * @see #createChangeListener
 156      */
 157     protected ChangeListener changeListener = createChangeListener();
 158 
 159 
 160     /**
 161      * Only one <code>ChangeEvent</code> is needed per slider instance since the
 162      * event's only (read-only) state is the source property.  The source
 163      * of events generated here is always "this". The event is lazily
 164      * created the first time that an event notification is fired.
 165      *
 166      * @see #fireStateChanged
 167      */
 168     protected transient ChangeEvent changeEvent = null;
 169 
 170 
 171     private void checkOrientation(int orientation) {
 172         switch (orientation) {
 173         case VERTICAL:
 174         case HORIZONTAL:
 175             break;
 176         default:
 177             throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL");
 178         }
 179     }
 180 
 181 
 182     /**
 183      * Creates a horizontal slider with the range 0 to 100 and
 184      * an initial value of 50.
 185      */
 186     public JSlider() {
 187         this(HORIZONTAL, 0, 100, 50);
 188     }
 189 
 190 
 191     /**
 192      * Creates a slider using the specified orientation with the
 193      * range {@code 0} to {@code 100} and an initial value of {@code 50}.
 194      * The orientation can be
 195      * either <code>SwingConstants.VERTICAL</code> or
 196      * <code>SwingConstants.HORIZONTAL</code>.
 197      *
 198      * @param  orientation  the orientation of the slider
 199      * @throws IllegalArgumentException if orientation is not one of {@code VERTICAL}, {@code HORIZONTAL}
 200      * @see #setOrientation
 201      */
 202     public JSlider(int orientation) {
 203         this(orientation, 0, 100, 50);
 204     }
 205 
 206 
 207     /**
 208      * Creates a horizontal slider using the specified min and max
 209      * with an initial value equal to the average of the min plus max.
 210      * <p>
 211      * The <code>BoundedRangeModel</code> that holds the slider's data
 212      * handles any issues that may arise from improperly setting the
 213      * minimum and maximum values on the slider.  See the
 214      * {@code BoundedRangeModel} documentation for details.
 215      *
 216      * @param min  the minimum value of the slider
 217      * @param max  the maximum value of the slider
 218      *
 219      * @see BoundedRangeModel
 220      * @see #setMinimum
 221      * @see #setMaximum
 222      */
 223     public JSlider(int min, int max) {
 224         this(HORIZONTAL, min, max, (min + max) / 2);
 225     }
 226 
 227 
 228     /**
 229      * Creates a horizontal slider using the specified min, max and value.
 230      * <p>
 231      * The <code>BoundedRangeModel</code> that holds the slider's data
 232      * handles any issues that may arise from improperly setting the
 233      * minimum, initial, and maximum values on the slider.  See the
 234      * {@code BoundedRangeModel} documentation for details.
 235      *
 236      * @param min  the minimum value of the slider
 237      * @param max  the maximum value of the slider
 238      * @param value  the initial value of the slider
 239      *
 240      * @see BoundedRangeModel
 241      * @see #setMinimum
 242      * @see #setMaximum
 243      * @see #setValue
 244      */
 245     public JSlider(int min, int max, int value) {
 246         this(HORIZONTAL, min, max, value);
 247     }
 248 
 249 
 250     /**
 251      * Creates a slider with the specified orientation and the
 252      * specified minimum, maximum, and initial values.
 253      * The orientation can be
 254      * either <code>SwingConstants.VERTICAL</code> or
 255      * <code>SwingConstants.HORIZONTAL</code>.
 256      * <p>
 257      * The <code>BoundedRangeModel</code> that holds the slider's data
 258      * handles any issues that may arise from improperly setting the
 259      * minimum, initial, and maximum values on the slider.  See the
 260      * {@code BoundedRangeModel} documentation for details.
 261      *
 262      * @param orientation  the orientation of the slider
 263      * @param min  the minimum value of the slider
 264      * @param max  the maximum value of the slider
 265      * @param value  the initial value of the slider
 266      *
 267      * @throws IllegalArgumentException if orientation is not one of {@code VERTICAL}, {@code HORIZONTAL}
 268      *
 269      * @see BoundedRangeModel
 270      * @see #setOrientation
 271      * @see #setMinimum
 272      * @see #setMaximum
 273      * @see #setValue
 274      */
 275     public JSlider(int orientation, int min, int max, int value)
 276     {
 277         checkOrientation(orientation);


 346     public String getUIClassID() {
 347         return uiClassID;
 348     }
 349 
 350 
 351     /**
 352      * We pass Change events along to the listeners with the
 353      * the slider (instead of the model itself) as the event source.
 354      */
 355     private class ModelListener implements ChangeListener, Serializable {
 356         public void stateChanged(ChangeEvent e) {
 357             fireStateChanged();
 358         }
 359     }
 360 
 361 
 362     /**
 363      * Subclasses that want to handle {@code ChangeEvent}s
 364      * from the model differently
 365      * can override this to return
 366      * an instance of a custom <code>ChangeListener</code> implementation.
 367      * The default {@code ChangeListener} simply calls the
 368      * {@code fireStateChanged} method to forward {@code ChangeEvent}s
 369      * to the {@code ChangeListener}s that have been added directly to the
 370      * slider.
 371      *
 372      * @return a instance of new {@code ChangeListener}
 373      * @see #changeListener
 374      * @see #fireStateChanged
 375      * @see javax.swing.event.ChangeListener
 376      * @see javax.swing.BoundedRangeModel
 377      */
 378     protected ChangeListener createChangeListener() {
 379         return new ModelListener();
 380     }
 381 
 382 
 383     /**
 384      * Adds a ChangeListener to the slider.
 385      *
 386      * @param l the ChangeListener to add


 389      */
 390     public void addChangeListener(ChangeListener l) {
 391         listenerList.add(ChangeListener.class, l);
 392     }
 393 
 394 
 395     /**
 396      * Removes a ChangeListener from the slider.
 397      *
 398      * @param l the ChangeListener to remove
 399      * @see #fireStateChanged
 400      * @see #addChangeListener
 401 
 402      */
 403     public void removeChangeListener(ChangeListener l) {
 404         listenerList.remove(ChangeListener.class, l);
 405     }
 406 
 407 
 408     /**
 409      * Returns an array of all the <code>ChangeListener</code>s added
 410      * to this JSlider with addChangeListener().
 411      *
 412      * @return all of the <code>ChangeListener</code>s added or an empty
 413      *         array if no listeners have been added
 414      * @since 1.4
 415      */
 416     public ChangeListener[] getChangeListeners() {
 417         return listenerList.getListeners(ChangeListener.class);
 418     }
 419 
 420 
 421     /**
 422      * Send a {@code ChangeEvent}, whose source is this {@code JSlider}, to
 423      * all {@code ChangeListener}s that have registered interest in
 424      * {@code ChangeEvent}s.
 425      * This method is called each time a {@code ChangeEvent} is received from
 426      * the model.
 427      * <p>
 428      * The event instance is created if necessary, and stored in
 429      * {@code changeEvent}.
 430      *
 431      * @see #addChangeListener
 432      * @see EventListenerList


 447     /**
 448      * Returns the {@code BoundedRangeModel} that handles the slider's three
 449      * fundamental properties: minimum, maximum, value.
 450      *
 451      * @return the data model for this component
 452      * @see #setModel
 453      * @see    BoundedRangeModel
 454      */
 455     public BoundedRangeModel getModel() {
 456         return sliderModel;
 457     }
 458 
 459 
 460     /**
 461      * Sets the {@code BoundedRangeModel} that handles the slider's three
 462      * fundamental properties: minimum, maximum, value.
 463      *<p>
 464      * Attempts to pass a {@code null} model to this method result in
 465      * undefined behavior, and, most likely, exceptions.
 466      *
 467      * @param  newModel the new, {@code non-null} <code>BoundedRangeModel</code> to use
 468      *
 469      * @see #getModel
 470      * @see    BoundedRangeModel
 471      * @beaninfo
 472      *       bound: true
 473      * description: The sliders BoundedRangeModel.
 474      */
 475     public void setModel(BoundedRangeModel newModel)
 476     {
 477         BoundedRangeModel oldModel = getModel();
 478 
 479         if (oldModel != null) {
 480             oldModel.removeChangeListener(changeListener);
 481         }
 482 
 483         sliderModel = newModel;
 484 
 485         if (newModel != null) {
 486             newModel.addChangeListener(changeListener);
 487         }


 533      */
 534     public void setValue(int n) {
 535         BoundedRangeModel m = getModel();
 536         int oldValue = m.getValue();
 537         if (oldValue == n) {
 538             return;
 539         }
 540         m.setValue(n);
 541 
 542         if (accessibleContext != null) {
 543             accessibleContext.firePropertyChange(
 544                                                 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
 545                                                 Integer.valueOf(oldValue),
 546                                                 Integer.valueOf(m.getValue()));
 547         }
 548     }
 549 
 550 
 551     /**
 552      * Returns the minimum value supported by the slider
 553      * from the <code>BoundedRangeModel</code>.
 554      *
 555      * @return the value of the model's minimum property
 556      * @see #setMinimum
 557      * @see     BoundedRangeModel#getMinimum
 558      */
 559     public int getMinimum() {
 560         return getModel().getMinimum();
 561     }
 562 
 563 
 564     /**
 565      * Sets the slider's minimum value to {@code minimum}.  This method
 566      * forwards the new minimum value to the model.
 567      * <p>
 568      * The data model (an instance of {@code BoundedRangeModel})
 569      * handles any mathematical
 570      * issues arising from assigning faulty values.  See the
 571      * {@code BoundedRangeModel} documentation for details.
 572      * <p>
 573      * If the new minimum value is different from the previous minimum value,
 574      * all change listeners are notified.
 575      *
 576      * @param minimum  the new minimum
 577      * @see #getMinimum
 578      * @see    #addChangeListener
 579      * @see BoundedRangeModel#setMinimum
 580      * @beaninfo
 581      *       bound: true
 582      *   preferred: true
 583      * description: The sliders minimum value.
 584      */
 585     public void setMinimum(int minimum) {
 586         int oldMin = getModel().getMinimum();
 587         getModel().setMinimum(minimum);
 588         firePropertyChange( "minimum", Integer.valueOf( oldMin ), Integer.valueOf( minimum ) );
 589     }
 590 
 591 
 592     /**
 593      * Returns the maximum value supported by the slider
 594      * from the <code>BoundedRangeModel</code>.
 595      *
 596      * @return the value of the model's maximum property
 597      * @see #setMaximum
 598      * @see BoundedRangeModel#getMaximum
 599      */
 600     public int getMaximum() {
 601         return getModel().getMaximum();
 602     }
 603 
 604 
 605     /**
 606      * Sets the slider's maximum value to {@code maximum}.  This method
 607      * forwards the new maximum value to the model.
 608      * <p>
 609      * The data model (an instance of {@code BoundedRangeModel})
 610      * handles any mathematical
 611      * issues arising from assigning faulty values.  See the
 612      * {@code BoundedRangeModel} documentation for details.
 613      * <p>
 614      * If the new maximum value is different from the previous maximum value,


 653      * @see   BoundedRangeModel#setValueIsAdjusting
 654      * @beaninfo
 655      *      expert: true
 656      * description: True if the slider knob is being dragged.
 657      */
 658     public void setValueIsAdjusting(boolean b) {
 659         BoundedRangeModel m = getModel();
 660         boolean oldValue = m.getValueIsAdjusting();
 661         m.setValueIsAdjusting(b);
 662 
 663         if ((oldValue != b) && (accessibleContext != null)) {
 664             accessibleContext.firePropertyChange(
 665                                                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
 666                                                 ((oldValue) ? AccessibleState.BUSY : null),
 667                                                 ((b) ? AccessibleState.BUSY : null));
 668         }
 669     }
 670 
 671 
 672     /**
 673      * Returns the "extent" from the <code>BoundedRangeModel</code>.
 674      * This represents the range of values "covered" by the knob.
 675      *
 676      * @return an int representing the extent
 677      * @see #setExtent
 678      * @see BoundedRangeModel#getExtent
 679      */
 680     public int getExtent() {
 681         return getModel().getExtent();
 682     }
 683 
 684 
 685     /**
 686      * Sets the size of the range "covered" by the knob.  Most look
 687      * and feel implementations will change the value by this amount
 688      * if the user clicks on either side of the knob.  This method just
 689      * forwards the new extent value to the model.
 690      * <p>
 691      * The data model (an instance of {@code BoundedRangeModel})
 692      * handles any mathematical
 693      * issues arising from assigning faulty values.  See the


 780 
 781         while (elements.hasMoreElements()) {
 782             Component component = (Component) elements.nextElement();
 783 
 784             if (component instanceof JLabel) {
 785                 JLabel label = (JLabel) component;
 786 
 787                 if (SwingUtilities.doesIconReferenceImage(label.getIcon(), img) ||
 788                         SwingUtilities.doesIconReferenceImage(label.getDisabledIcon(), img)) {
 789                     return super.imageUpdate(img, infoflags, x, y, w, h);
 790                 }
 791             }
 792         }
 793 
 794         return false;
 795     }
 796 
 797     /**
 798      * Returns the dictionary of what labels to draw at which values.
 799      *
 800      * @return the <code>Dictionary</code> containing labels and
 801      *    where to draw them
 802      */
 803     @SuppressWarnings("rawtypes")
 804     public Dictionary getLabelTable() {
 805 /*
 806         if ( labelTable == null && getMajorTickSpacing() > 0 ) {
 807             setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
 808         }
 809 */
 810         return labelTable;
 811     }
 812 
 813 
 814     /**
 815      * Used to specify what label will be drawn at any given value.
 816      * The key-value pairs are of this format:
 817      * <code>{ Integer value, java.swing.JComponent label }</code>.
 818      * <p>
 819      * An easy way to generate a standard table of value labels is by using the
 820      * {@code createStandardLabels} method.
 821      * <p>
 822      * Once the labels have been set, this method calls {@link #updateLabelUIs}.
 823      * Note that the labels are only painted if the {@code paintLabels}
 824      * property is {@code true}.
 825      *
 826      * @param labels new {@code Dictionary} of labels, or {@code null} to
 827      *        remove all labels
 828      * @see #createStandardLabels(int)
 829      * @see #getLabelTable
 830      * @see #setPaintLabels
 831      * @beaninfo
 832      *       hidden: true
 833      *        bound: true
 834      *    attribute: visualUpdate true
 835      *  description: Specifies what labels will be drawn for any given value.
 836      */
 837     @SuppressWarnings("rawtypes")


 870             component.setSize(component.getPreferredSize());
 871         }
 872     }
 873 
 874     private void updateLabelSizes() {
 875         @SuppressWarnings("rawtypes")
 876         Dictionary labelTable = getLabelTable();
 877         if (labelTable != null) {
 878             Enumeration<?> labels = labelTable.elements();
 879             while (labels.hasMoreElements()) {
 880                 JComponent component = (JComponent) labels.nextElement();
 881                 component.setSize(component.getPreferredSize());
 882             }
 883         }
 884     }
 885 
 886 
 887     /**
 888      * Creates a {@code Hashtable} of numerical text labels, starting at the
 889      * slider minimum, and using the increment specified.
 890      * For example, if you call <code>createStandardLabels( 10 )</code>
 891      * and the slider minimum is zero,
 892      * then labels will be created for the values 0, 10, 20, 30, and so on.
 893      * <p>
 894      * For the labels to be drawn on the slider, the returned {@code Hashtable}
 895      * must be passed into {@code setLabelTable}, and {@code setPaintLabels}
 896      * must be set to {@code true}.
 897      * <p>
 898      * For further details on the makeup of the returned {@code Hashtable}, see
 899      * the {@code setLabelTable} documentation.
 900      *
 901      * @param  increment  distance between labels in the generated hashtable
 902      * @return a new {@code Hashtable} of labels
 903      * @see #setLabelTable
 904      * @see #setPaintLabels
 905      * @throws IllegalArgumentException if {@code increment} is less than or
 906      *          equal to zero
 907      */
 908     public Hashtable<Integer, JComponent> createStandardLabels( int increment ) {
 909         return createStandardLabels( increment, getMinimum() );
 910     }
 911 
 912 
 913     /**
 914      * Creates a {@code Hashtable} of numerical text labels, starting at the
 915      * starting point specified, and using the increment specified.
 916      * For example, if you call
 917      * <code>createStandardLabels( 10, 2 )</code>,
 918      * then labels will be created for the values 2, 12, 22, 32, and so on.
 919      * <p>
 920      * For the labels to be drawn on the slider, the returned {@code Hashtable}
 921      * must be passed into {@code setLabelTable}, and {@code setPaintLabels}
 922      * must be set to {@code true}.
 923      * <p>
 924      * For further details on the makeup of the returned {@code Hashtable}, see
 925      * the {@code setLabelTable} documentation.
 926      *
 927      * @param  increment  distance between labels in the generated hashtable
 928      * @param  start      value at which the labels will begin
 929      * @return a new {@code Hashtable} of labels
 930      * @see #setLabelTable
 931      * @see #setPaintLabels
 932      * @exception IllegalArgumentException if {@code start} is
 933      *          out of range, or if {@code increment} is less than or equal
 934      *          to zero
 935      */
 936     public Hashtable<Integer, JComponent> createStandardLabels( int increment, int start ) {
 937         if ( start > getMaximum() || start < getMinimum() ) {


1034         addPropertyChangeListener( table );
1035 
1036         return table;
1037     }
1038 
1039 
1040     /**
1041      * Returns true if the value-range shown for the slider is reversed,
1042      *
1043      * @return true if the slider values are reversed from their normal order
1044      * @see #setInverted
1045      */
1046     public boolean getInverted() {
1047         return isInverted;
1048     }
1049 
1050 
1051     /**
1052      * Specify true to reverse the value-range shown for the slider and false to
1053      * put the value range in the normal order.  The order depends on the
1054      * slider's <code>ComponentOrientation</code> property.  Normal (non-inverted)
1055      * horizontal sliders with a <code>ComponentOrientation</code> value of
1056      * <code>LEFT_TO_RIGHT</code> have their maximum on the right.
1057      * Normal horizontal sliders with a <code>ComponentOrientation</code> value of
1058      * <code>RIGHT_TO_LEFT</code> have their maximum on the left.  Normal vertical
1059      * sliders have their maximum on the top.  These labels are reversed when the
1060      * slider is inverted.
1061      * <p>
1062      * By default, the value of this property is {@code false}.
1063      *
1064      * @param b  true to reverse the slider values from their normal order
1065      * @beaninfo
1066      *        bound: true
1067      *    attribute: visualUpdate true
1068      *  description: If true reverses the slider values from their normal order
1069      *
1070      */
1071     public void setInverted( boolean b ) {
1072         boolean oldValue = isInverted;
1073         isInverted = b;
1074         firePropertyChange("inverted", oldValue, isInverted);
1075         if (b != oldValue) {
1076             repaint();
1077         }
1078     }


1359      * See readObject() and writeObject() in JComponent for more
1360      * information about serialization in Swing.
1361      */
1362     private void writeObject(ObjectOutputStream s) throws IOException {
1363         s.defaultWriteObject();
1364         if (getUIClassID().equals(uiClassID)) {
1365             byte count = JComponent.getWriteObjCounter(this);
1366             JComponent.setWriteObjCounter(this, --count);
1367             if (count == 0 && ui != null) {
1368                 ui.installUI(this);
1369             }
1370         }
1371     }
1372 
1373 
1374     /**
1375      * Returns a string representation of this JSlider. This method
1376      * is intended to be used only for debugging purposes, and the
1377      * content and format of the returned string may vary between
1378      * implementations. The returned string may be empty but may not
1379      * be <code>null</code>.
1380      *
1381      * @return  a string representation of this JSlider.
1382      */
1383     protected String paramString() {
1384         String paintTicksString = (paintTicks ?
1385                                    "true" : "false");
1386         String paintTrackString = (paintTrack ?
1387                                    "true" : "false");
1388         String paintLabelsString = (paintLabels ?
1389                                     "true" : "false");
1390         String isInvertedString = (isInverted ?
1391                                    "true" : "false");
1392         String snapToTicksString = (snapToTicks ?
1393                                     "true" : "false");
1394         String snapToValueString = (snapToValue ?
1395                                     "true" : "false");
1396         String orientationString = (orientation == HORIZONTAL ?
1397                                     "HORIZONTAL" : "VERTICAL");
1398 
1399         return super.paramString() +


1414 ////////////////
1415 
1416     /**
1417      * Gets the AccessibleContext associated with this JSlider.
1418      * For sliders, the AccessibleContext takes the form of an
1419      * AccessibleJSlider.
1420      * A new AccessibleJSlider instance is created if necessary.
1421      *
1422      * @return an AccessibleJSlider that serves as the
1423      *         AccessibleContext of this JSlider
1424      */
1425     public AccessibleContext getAccessibleContext() {
1426         if (accessibleContext == null) {
1427             accessibleContext = new AccessibleJSlider();
1428         }
1429         return accessibleContext;
1430     }
1431 
1432     /**
1433      * This class implements accessibility support for the
1434      * <code>JSlider</code> class.  It provides an implementation of the
1435      * Java Accessibility API appropriate to slider user-interface elements.
1436      * <p>
1437      * <strong>Warning:</strong>
1438      * Serialized objects of this class will not be compatible with
1439      * future Swing releases. The current serialization support is
1440      * appropriate for short term storage or RMI between applications running
1441      * the same version of Swing.  As of 1.4, support for long term storage
1442      * of all JavaBeans&trade;
1443      * has been added to the <code>java.beans</code> package.
1444      * Please see {@link java.beans.XMLEncoder}.
1445      */
1446     @SuppressWarnings("serial") // Same-version serialization only
1447     protected class AccessibleJSlider extends AccessibleJComponent
1448     implements AccessibleValue {
1449 
1450         /**
1451          * Get the state set of this object.
1452          *
1453          * @return an instance of AccessibleState containing the current state
1454          * of the object
1455          * @see AccessibleState
1456          */
1457         public AccessibleStateSet getAccessibleStateSet() {
1458             AccessibleStateSet states = super.getAccessibleStateSet();
1459             if (getValueIsAdjusting()) {
1460                 states.add(AccessibleState.BUSY);
1461             }
1462             if (getOrientation() == VERTICAL) {
1463                 states.add(AccessibleState.VERTICAL);




  29 import javax.swing.plaf.*;
  30 import javax.accessibility.*;
  31 
  32 import java.io.Serializable;
  33 import java.io.ObjectOutputStream;
  34 import java.io.IOException;
  35 
  36 import java.awt.*;
  37 import java.util.*;
  38 import java.beans.*;
  39 
  40 
  41 /**
  42  * A component that lets the user graphically select a value by sliding
  43  * a knob within a bounded interval. The knob is always positioned
  44  * at the points that match integer values within the specified interval.
  45  * <p>
  46  * The slider can show both
  47  * major tick marks, and minor tick marks between the major ones.  The number of
  48  * values between the tick marks is controlled with
  49  * {@code setMajorTickSpacing} and {@code setMinorTickSpacing}.
  50  * Painting of tick marks is controlled by {@code setPaintTicks}.
  51  * <p>
  52  * Sliders can also print text labels at regular intervals (or at
  53  * arbitrary locations) along the slider track.  Painting of labels is
  54  * controlled by {@code setLabelTable} and {@code setPaintLabels}.
  55  * <p>
  56  * For further information and examples see
  57  * <a
  58  href="http://docs.oracle.com/javase/tutorial/uiswing/components/slider.html">How to Use Sliders</a>,
  59  * a section in <em>The Java Tutorial.</em>
  60  * <p>
  61  * <strong>Warning:</strong> Swing is not thread safe. For more
  62  * information see <a
  63  * href="package-summary.html#threading">Swing's Threading
  64  * Policy</a>.
  65  * <p>
  66  * <strong>Warning:</strong>
  67  * Serialized objects of this class will not be compatible with
  68  * future Swing releases. The current serialization support is
  69  * appropriate for short term storage or RMI between applications running
  70  * the same version of Swing.  As of 1.4, support for long term storage
  71  * of all JavaBeans&trade;
  72  * has been added to the {@code java.beans} package.
  73  * Please see {@link java.beans.XMLEncoder}.
  74  *
  75  * @beaninfo
  76  *      attribute: isContainer false
  77  *    description: A component that supports selecting a integer value from a range.
  78  *
  79  * @author David Kloba
  80  * @since 1.2
  81  */
  82 @SuppressWarnings("serial") // Same-version serialization only
  83 public class JSlider extends JComponent implements SwingConstants, Accessible {
  84     /**
  85      * @see #getUIClassID
  86      * @see #readObject
  87      */
  88     private static final String uiClassID = "SliderUI";
  89 
  90     private boolean paintTicks = false;
  91     private boolean paintTrack = true;
  92     private boolean paintLabels = false;


 141     @SuppressWarnings("rawtypes")
 142     private Dictionary labelTable;
 143     // For better source compatibility, the labelTable field and
 144     // associated getter and setter methods are being left as raw
 145     // types.
 146 
 147     /**
 148      * The changeListener (no suffix) is the listener we add to the
 149      * slider's model.  This listener is initialized to the
 150      * {@code ChangeListener} returned from {@code createChangeListener},
 151      * which by default just forwards events
 152      * to {@code ChangeListener}s (if any) added directly to the slider.
 153      *
 154      * @see #addChangeListener
 155      * @see #createChangeListener
 156      */
 157     protected ChangeListener changeListener = createChangeListener();
 158 
 159 
 160     /**
 161      * Only one {@code ChangeEvent} is needed per slider instance since the
 162      * event's only (read-only) state is the source property.  The source
 163      * of events generated here is always "this". The event is lazily
 164      * created the first time that an event notification is fired.
 165      *
 166      * @see #fireStateChanged
 167      */
 168     protected transient ChangeEvent changeEvent = null;
 169 
 170 
 171     private void checkOrientation(int orientation) {
 172         switch (orientation) {
 173         case VERTICAL:
 174         case HORIZONTAL:
 175             break;
 176         default:
 177             throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL");
 178         }
 179     }
 180 
 181 
 182     /**
 183      * Creates a horizontal slider with the range 0 to 100 and
 184      * an initial value of 50.
 185      */
 186     public JSlider() {
 187         this(HORIZONTAL, 0, 100, 50);
 188     }
 189 
 190 
 191     /**
 192      * Creates a slider using the specified orientation with the
 193      * range {@code 0} to {@code 100} and an initial value of {@code 50}.
 194      * The orientation can be
 195      * either {@code SwingConstants.VERTICAL} or
 196      * {@code SwingConstants.HORIZONTAL}.
 197      *
 198      * @param  orientation  the orientation of the slider
 199      * @throws IllegalArgumentException if orientation is not one of {@code VERTICAL}, {@code HORIZONTAL}
 200      * @see #setOrientation
 201      */
 202     public JSlider(int orientation) {
 203         this(orientation, 0, 100, 50);
 204     }
 205 
 206 
 207     /**
 208      * Creates a horizontal slider using the specified min and max
 209      * with an initial value equal to the average of the min plus max.
 210      * <p>
 211      * The {@code BoundedRangeModel} that holds the slider's data
 212      * handles any issues that may arise from improperly setting the
 213      * minimum and maximum values on the slider.  See the
 214      * {@code BoundedRangeModel} documentation for details.
 215      *
 216      * @param min  the minimum value of the slider
 217      * @param max  the maximum value of the slider
 218      *
 219      * @see BoundedRangeModel
 220      * @see #setMinimum
 221      * @see #setMaximum
 222      */
 223     public JSlider(int min, int max) {
 224         this(HORIZONTAL, min, max, (min + max) / 2);
 225     }
 226 
 227 
 228     /**
 229      * Creates a horizontal slider using the specified min, max and value.
 230      * <p>
 231      * The {@code BoundedRangeModel} that holds the slider's data
 232      * handles any issues that may arise from improperly setting the
 233      * minimum, initial, and maximum values on the slider.  See the
 234      * {@code BoundedRangeModel} documentation for details.
 235      *
 236      * @param min  the minimum value of the slider
 237      * @param max  the maximum value of the slider
 238      * @param value  the initial value of the slider
 239      *
 240      * @see BoundedRangeModel
 241      * @see #setMinimum
 242      * @see #setMaximum
 243      * @see #setValue
 244      */
 245     public JSlider(int min, int max, int value) {
 246         this(HORIZONTAL, min, max, value);
 247     }
 248 
 249 
 250     /**
 251      * Creates a slider with the specified orientation and the
 252      * specified minimum, maximum, and initial values.
 253      * The orientation can be
 254      * either {@code SwingConstants.VERTICAL} or
 255      * {@code SwingConstants.HORIZONTAL}.
 256      * <p>
 257      * The {@code BoundedRangeModel} that holds the slider's data
 258      * handles any issues that may arise from improperly setting the
 259      * minimum, initial, and maximum values on the slider.  See the
 260      * {@code BoundedRangeModel} documentation for details.
 261      *
 262      * @param orientation  the orientation of the slider
 263      * @param min  the minimum value of the slider
 264      * @param max  the maximum value of the slider
 265      * @param value  the initial value of the slider
 266      *
 267      * @throws IllegalArgumentException if orientation is not one of {@code VERTICAL}, {@code HORIZONTAL}
 268      *
 269      * @see BoundedRangeModel
 270      * @see #setOrientation
 271      * @see #setMinimum
 272      * @see #setMaximum
 273      * @see #setValue
 274      */
 275     public JSlider(int orientation, int min, int max, int value)
 276     {
 277         checkOrientation(orientation);


 346     public String getUIClassID() {
 347         return uiClassID;
 348     }
 349 
 350 
 351     /**
 352      * We pass Change events along to the listeners with the
 353      * the slider (instead of the model itself) as the event source.
 354      */
 355     private class ModelListener implements ChangeListener, Serializable {
 356         public void stateChanged(ChangeEvent e) {
 357             fireStateChanged();
 358         }
 359     }
 360 
 361 
 362     /**
 363      * Subclasses that want to handle {@code ChangeEvent}s
 364      * from the model differently
 365      * can override this to return
 366      * an instance of a custom {@code ChangeListener} implementation.
 367      * The default {@code ChangeListener} simply calls the
 368      * {@code fireStateChanged} method to forward {@code ChangeEvent}s
 369      * to the {@code ChangeListener}s that have been added directly to the
 370      * slider.
 371      *
 372      * @return a instance of new {@code ChangeListener}
 373      * @see #changeListener
 374      * @see #fireStateChanged
 375      * @see javax.swing.event.ChangeListener
 376      * @see javax.swing.BoundedRangeModel
 377      */
 378     protected ChangeListener createChangeListener() {
 379         return new ModelListener();
 380     }
 381 
 382 
 383     /**
 384      * Adds a ChangeListener to the slider.
 385      *
 386      * @param l the ChangeListener to add


 389      */
 390     public void addChangeListener(ChangeListener l) {
 391         listenerList.add(ChangeListener.class, l);
 392     }
 393 
 394 
 395     /**
 396      * Removes a ChangeListener from the slider.
 397      *
 398      * @param l the ChangeListener to remove
 399      * @see #fireStateChanged
 400      * @see #addChangeListener
 401 
 402      */
 403     public void removeChangeListener(ChangeListener l) {
 404         listenerList.remove(ChangeListener.class, l);
 405     }
 406 
 407 
 408     /**
 409      * Returns an array of all the {@code ChangeListener}s added
 410      * to this JSlider with addChangeListener().
 411      *
 412      * @return all of the {@code ChangeListener}s added or an empty
 413      *         array if no listeners have been added
 414      * @since 1.4
 415      */
 416     public ChangeListener[] getChangeListeners() {
 417         return listenerList.getListeners(ChangeListener.class);
 418     }
 419 
 420 
 421     /**
 422      * Send a {@code ChangeEvent}, whose source is this {@code JSlider}, to
 423      * all {@code ChangeListener}s that have registered interest in
 424      * {@code ChangeEvent}s.
 425      * This method is called each time a {@code ChangeEvent} is received from
 426      * the model.
 427      * <p>
 428      * The event instance is created if necessary, and stored in
 429      * {@code changeEvent}.
 430      *
 431      * @see #addChangeListener
 432      * @see EventListenerList


 447     /**
 448      * Returns the {@code BoundedRangeModel} that handles the slider's three
 449      * fundamental properties: minimum, maximum, value.
 450      *
 451      * @return the data model for this component
 452      * @see #setModel
 453      * @see    BoundedRangeModel
 454      */
 455     public BoundedRangeModel getModel() {
 456         return sliderModel;
 457     }
 458 
 459 
 460     /**
 461      * Sets the {@code BoundedRangeModel} that handles the slider's three
 462      * fundamental properties: minimum, maximum, value.
 463      *<p>
 464      * Attempts to pass a {@code null} model to this method result in
 465      * undefined behavior, and, most likely, exceptions.
 466      *
 467      * @param  newModel the new, {@code non-null BoundedRangeModel} to use
 468      *
 469      * @see #getModel
 470      * @see    BoundedRangeModel
 471      * @beaninfo
 472      *       bound: true
 473      * description: The sliders BoundedRangeModel.
 474      */
 475     public void setModel(BoundedRangeModel newModel)
 476     {
 477         BoundedRangeModel oldModel = getModel();
 478 
 479         if (oldModel != null) {
 480             oldModel.removeChangeListener(changeListener);
 481         }
 482 
 483         sliderModel = newModel;
 484 
 485         if (newModel != null) {
 486             newModel.addChangeListener(changeListener);
 487         }


 533      */
 534     public void setValue(int n) {
 535         BoundedRangeModel m = getModel();
 536         int oldValue = m.getValue();
 537         if (oldValue == n) {
 538             return;
 539         }
 540         m.setValue(n);
 541 
 542         if (accessibleContext != null) {
 543             accessibleContext.firePropertyChange(
 544                                                 AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,
 545                                                 Integer.valueOf(oldValue),
 546                                                 Integer.valueOf(m.getValue()));
 547         }
 548     }
 549 
 550 
 551     /**
 552      * Returns the minimum value supported by the slider
 553      * from the {@code BoundedRangeModel}.
 554      *
 555      * @return the value of the model's minimum property
 556      * @see #setMinimum
 557      * @see     BoundedRangeModel#getMinimum
 558      */
 559     public int getMinimum() {
 560         return getModel().getMinimum();
 561     }
 562 
 563 
 564     /**
 565      * Sets the slider's minimum value to {@code minimum}.  This method
 566      * forwards the new minimum value to the model.
 567      * <p>
 568      * The data model (an instance of {@code BoundedRangeModel})
 569      * handles any mathematical
 570      * issues arising from assigning faulty values.  See the
 571      * {@code BoundedRangeModel} documentation for details.
 572      * <p>
 573      * If the new minimum value is different from the previous minimum value,
 574      * all change listeners are notified.
 575      *
 576      * @param minimum  the new minimum
 577      * @see #getMinimum
 578      * @see    #addChangeListener
 579      * @see BoundedRangeModel#setMinimum
 580      * @beaninfo
 581      *       bound: true
 582      *   preferred: true
 583      * description: The sliders minimum value.
 584      */
 585     public void setMinimum(int minimum) {
 586         int oldMin = getModel().getMinimum();
 587         getModel().setMinimum(minimum);
 588         firePropertyChange( "minimum", Integer.valueOf( oldMin ), Integer.valueOf( minimum ) );
 589     }
 590 
 591 
 592     /**
 593      * Returns the maximum value supported by the slider
 594      * from the {@code BoundedRangeModel}.
 595      *
 596      * @return the value of the model's maximum property
 597      * @see #setMaximum
 598      * @see BoundedRangeModel#getMaximum
 599      */
 600     public int getMaximum() {
 601         return getModel().getMaximum();
 602     }
 603 
 604 
 605     /**
 606      * Sets the slider's maximum value to {@code maximum}.  This method
 607      * forwards the new maximum value to the model.
 608      * <p>
 609      * The data model (an instance of {@code BoundedRangeModel})
 610      * handles any mathematical
 611      * issues arising from assigning faulty values.  See the
 612      * {@code BoundedRangeModel} documentation for details.
 613      * <p>
 614      * If the new maximum value is different from the previous maximum value,


 653      * @see   BoundedRangeModel#setValueIsAdjusting
 654      * @beaninfo
 655      *      expert: true
 656      * description: True if the slider knob is being dragged.
 657      */
 658     public void setValueIsAdjusting(boolean b) {
 659         BoundedRangeModel m = getModel();
 660         boolean oldValue = m.getValueIsAdjusting();
 661         m.setValueIsAdjusting(b);
 662 
 663         if ((oldValue != b) && (accessibleContext != null)) {
 664             accessibleContext.firePropertyChange(
 665                                                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
 666                                                 ((oldValue) ? AccessibleState.BUSY : null),
 667                                                 ((b) ? AccessibleState.BUSY : null));
 668         }
 669     }
 670 
 671 
 672     /**
 673      * Returns the "extent" from the {@code BoundedRangeModel}.
 674      * This represents the range of values "covered" by the knob.
 675      *
 676      * @return an int representing the extent
 677      * @see #setExtent
 678      * @see BoundedRangeModel#getExtent
 679      */
 680     public int getExtent() {
 681         return getModel().getExtent();
 682     }
 683 
 684 
 685     /**
 686      * Sets the size of the range "covered" by the knob.  Most look
 687      * and feel implementations will change the value by this amount
 688      * if the user clicks on either side of the knob.  This method just
 689      * forwards the new extent value to the model.
 690      * <p>
 691      * The data model (an instance of {@code BoundedRangeModel})
 692      * handles any mathematical
 693      * issues arising from assigning faulty values.  See the


 780 
 781         while (elements.hasMoreElements()) {
 782             Component component = (Component) elements.nextElement();
 783 
 784             if (component instanceof JLabel) {
 785                 JLabel label = (JLabel) component;
 786 
 787                 if (SwingUtilities.doesIconReferenceImage(label.getIcon(), img) ||
 788                         SwingUtilities.doesIconReferenceImage(label.getDisabledIcon(), img)) {
 789                     return super.imageUpdate(img, infoflags, x, y, w, h);
 790                 }
 791             }
 792         }
 793 
 794         return false;
 795     }
 796 
 797     /**
 798      * Returns the dictionary of what labels to draw at which values.
 799      *
 800      * @return the {@code Dictionary} containing labels and
 801      *    where to draw them
 802      */
 803     @SuppressWarnings("rawtypes")
 804     public Dictionary getLabelTable() {
 805 /*
 806         if ( labelTable == null && getMajorTickSpacing() > 0 ) {
 807             setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
 808         }
 809 */
 810         return labelTable;
 811     }
 812 
 813 
 814     /**
 815      * Used to specify what label will be drawn at any given value.
 816      * The key-value pairs are of this format:
 817      * {@code { Integer value, java.swing.JComponent label }}.
 818      * <p>
 819      * An easy way to generate a standard table of value labels is by using the
 820      * {@code createStandardLabels} method.
 821      * <p>
 822      * Once the labels have been set, this method calls {@link #updateLabelUIs}.
 823      * Note that the labels are only painted if the {@code paintLabels}
 824      * property is {@code true}.
 825      *
 826      * @param labels new {@code Dictionary} of labels, or {@code null} to
 827      *        remove all labels
 828      * @see #createStandardLabels(int)
 829      * @see #getLabelTable
 830      * @see #setPaintLabels
 831      * @beaninfo
 832      *       hidden: true
 833      *        bound: true
 834      *    attribute: visualUpdate true
 835      *  description: Specifies what labels will be drawn for any given value.
 836      */
 837     @SuppressWarnings("rawtypes")


 870             component.setSize(component.getPreferredSize());
 871         }
 872     }
 873 
 874     private void updateLabelSizes() {
 875         @SuppressWarnings("rawtypes")
 876         Dictionary labelTable = getLabelTable();
 877         if (labelTable != null) {
 878             Enumeration<?> labels = labelTable.elements();
 879             while (labels.hasMoreElements()) {
 880                 JComponent component = (JComponent) labels.nextElement();
 881                 component.setSize(component.getPreferredSize());
 882             }
 883         }
 884     }
 885 
 886 
 887     /**
 888      * Creates a {@code Hashtable} of numerical text labels, starting at the
 889      * slider minimum, and using the increment specified.
 890      * For example, if you call {@code createStandardLabels( 10 )}
 891      * and the slider minimum is zero,
 892      * then labels will be created for the values 0, 10, 20, 30, and so on.
 893      * <p>
 894      * For the labels to be drawn on the slider, the returned {@code Hashtable}
 895      * must be passed into {@code setLabelTable}, and {@code setPaintLabels}
 896      * must be set to {@code true}.
 897      * <p>
 898      * For further details on the makeup of the returned {@code Hashtable}, see
 899      * the {@code setLabelTable} documentation.
 900      *
 901      * @param  increment  distance between labels in the generated hashtable
 902      * @return a new {@code Hashtable} of labels
 903      * @see #setLabelTable
 904      * @see #setPaintLabels
 905      * @throws IllegalArgumentException if {@code increment} is less than or
 906      *          equal to zero
 907      */
 908     public Hashtable<Integer, JComponent> createStandardLabels( int increment ) {
 909         return createStandardLabels( increment, getMinimum() );
 910     }
 911 
 912 
 913     /**
 914      * Creates a {@code Hashtable} of numerical text labels, starting at the
 915      * starting point specified, and using the increment specified.
 916      * For example, if you call
 917      * {@code createStandardLabels( 10, 2 )},
 918      * then labels will be created for the values 2, 12, 22, 32, and so on.
 919      * <p>
 920      * For the labels to be drawn on the slider, the returned {@code Hashtable}
 921      * must be passed into {@code setLabelTable}, and {@code setPaintLabels}
 922      * must be set to {@code true}.
 923      * <p>
 924      * For further details on the makeup of the returned {@code Hashtable}, see
 925      * the {@code setLabelTable} documentation.
 926      *
 927      * @param  increment  distance between labels in the generated hashtable
 928      * @param  start      value at which the labels will begin
 929      * @return a new {@code Hashtable} of labels
 930      * @see #setLabelTable
 931      * @see #setPaintLabels
 932      * @exception IllegalArgumentException if {@code start} is
 933      *          out of range, or if {@code increment} is less than or equal
 934      *          to zero
 935      */
 936     public Hashtable<Integer, JComponent> createStandardLabels( int increment, int start ) {
 937         if ( start > getMaximum() || start < getMinimum() ) {


1034         addPropertyChangeListener( table );
1035 
1036         return table;
1037     }
1038 
1039 
1040     /**
1041      * Returns true if the value-range shown for the slider is reversed,
1042      *
1043      * @return true if the slider values are reversed from their normal order
1044      * @see #setInverted
1045      */
1046     public boolean getInverted() {
1047         return isInverted;
1048     }
1049 
1050 
1051     /**
1052      * Specify true to reverse the value-range shown for the slider and false to
1053      * put the value range in the normal order.  The order depends on the
1054      * slider's {@code ComponentOrientation} property.  Normal (non-inverted)
1055      * horizontal sliders with a {@code ComponentOrientation} value of
1056      * {@code LEFT_TO_RIGHT} have their maximum on the right.
1057      * Normal horizontal sliders with a {@code ComponentOrientation} value of
1058      * {@code RIGHT_TO_LEFT} have their maximum on the left.  Normal vertical
1059      * sliders have their maximum on the top.  These labels are reversed when the
1060      * slider is inverted.
1061      * <p>
1062      * By default, the value of this property is {@code false}.
1063      *
1064      * @param b  true to reverse the slider values from their normal order
1065      * @beaninfo
1066      *        bound: true
1067      *    attribute: visualUpdate true
1068      *  description: If true reverses the slider values from their normal order
1069      *
1070      */
1071     public void setInverted( boolean b ) {
1072         boolean oldValue = isInverted;
1073         isInverted = b;
1074         firePropertyChange("inverted", oldValue, isInverted);
1075         if (b != oldValue) {
1076             repaint();
1077         }
1078     }


1359      * See readObject() and writeObject() in JComponent for more
1360      * information about serialization in Swing.
1361      */
1362     private void writeObject(ObjectOutputStream s) throws IOException {
1363         s.defaultWriteObject();
1364         if (getUIClassID().equals(uiClassID)) {
1365             byte count = JComponent.getWriteObjCounter(this);
1366             JComponent.setWriteObjCounter(this, --count);
1367             if (count == 0 && ui != null) {
1368                 ui.installUI(this);
1369             }
1370         }
1371     }
1372 
1373 
1374     /**
1375      * Returns a string representation of this JSlider. This method
1376      * is intended to be used only for debugging purposes, and the
1377      * content and format of the returned string may vary between
1378      * implementations. The returned string may be empty but may not
1379      * be {@code null}.
1380      *
1381      * @return  a string representation of this JSlider.
1382      */
1383     protected String paramString() {
1384         String paintTicksString = (paintTicks ?
1385                                    "true" : "false");
1386         String paintTrackString = (paintTrack ?
1387                                    "true" : "false");
1388         String paintLabelsString = (paintLabels ?
1389                                     "true" : "false");
1390         String isInvertedString = (isInverted ?
1391                                    "true" : "false");
1392         String snapToTicksString = (snapToTicks ?
1393                                     "true" : "false");
1394         String snapToValueString = (snapToValue ?
1395                                     "true" : "false");
1396         String orientationString = (orientation == HORIZONTAL ?
1397                                     "HORIZONTAL" : "VERTICAL");
1398 
1399         return super.paramString() +


1414 ////////////////
1415 
1416     /**
1417      * Gets the AccessibleContext associated with this JSlider.
1418      * For sliders, the AccessibleContext takes the form of an
1419      * AccessibleJSlider.
1420      * A new AccessibleJSlider instance is created if necessary.
1421      *
1422      * @return an AccessibleJSlider that serves as the
1423      *         AccessibleContext of this JSlider
1424      */
1425     public AccessibleContext getAccessibleContext() {
1426         if (accessibleContext == null) {
1427             accessibleContext = new AccessibleJSlider();
1428         }
1429         return accessibleContext;
1430     }
1431 
1432     /**
1433      * This class implements accessibility support for the
1434      * {@code JSlider} class.  It provides an implementation of the
1435      * Java Accessibility API appropriate to slider user-interface elements.
1436      * <p>
1437      * <strong>Warning:</strong>
1438      * Serialized objects of this class will not be compatible with
1439      * future Swing releases. The current serialization support is
1440      * appropriate for short term storage or RMI between applications running
1441      * the same version of Swing.  As of 1.4, support for long term storage
1442      * of all JavaBeans&trade;
1443      * has been added to the {@code java.beans} package.
1444      * Please see {@link java.beans.XMLEncoder}.
1445      */
1446     @SuppressWarnings("serial") // Same-version serialization only
1447     protected class AccessibleJSlider extends AccessibleJComponent
1448     implements AccessibleValue {
1449 
1450         /**
1451          * Get the state set of this object.
1452          *
1453          * @return an instance of AccessibleState containing the current state
1454          * of the object
1455          * @see AccessibleState
1456          */
1457         public AccessibleStateSet getAccessibleStateSet() {
1458             AccessibleStateSet states = super.getAccessibleStateSet();
1459             if (getValueIsAdjusting()) {
1460                 states.add(AccessibleState.BUSY);
1461             }
1462             if (getOrientation() == VERTICAL) {
1463                 states.add(AccessibleState.VERTICAL);


< prev index next >