Source for javax.swing.JSlider

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