Merge from the pain train
[official-gcc.git] / libjava / javax / swing / JSlider.java
blobcfe7880df6542cf7210293995985b27e3905744a
1 /* JSlider.java --
2 Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
39 package javax.swing;
41 import java.awt.Dimension;
42 import java.awt.MenuContainer;
43 import java.awt.image.ImageObserver;
44 import java.io.Serializable;
45 import java.util.Dictionary;
46 import java.util.Enumeration;
47 import java.util.Hashtable;
49 import javax.accessibility.Accessible;
50 import javax.accessibility.AccessibleContext;
51 import javax.accessibility.AccessibleRole;
52 import javax.accessibility.AccessibleStateSet;
53 import javax.accessibility.AccessibleValue;
54 import javax.swing.event.ChangeEvent;
55 import javax.swing.event.ChangeListener;
56 import javax.swing.plaf.SliderUI;
58 /**
59 * The JSlider is a Swing component that allows selection of a value within a
60 * range by adjusting a thumb in a track. The values for the minimum,
61 * maximum, extent and value are stored in a {@link
62 * DefaultBoundedRangeModel}.
64 * <p>
65 * JSliders have the following properties:
66 * </p>
68 * <table>
69 * <tr><th> Property </th><th> Stored in </th><th> Bound? </th></tr>
70 * <tr><td> extent </td><td> model </td><td> no </td></tr>
71 * <tr><td> inverted </td><td> slider </td><td> yes </td></tr>
72 * <tr><td> labelTable </td><td> slider </td><td> yes </td></tr>
73 * <tr><td> majorTickSpacing </td><td> slider </td><td> yes </td></tr>
74 * <tr><td> maximum </td><td> model </td><td> no </td></tr>
75 * <tr><td> minimum </td><td> model </td><td> no </td></tr>
76 * <tr><td> minorTickSpacing </td><td> slider </td><td> yes </td></tr>
77 * <tr><td> model </td><td> slider </td><td> yes </td></tr>
78 * <tr><td> orientation </td><td> slider </td><td> yes </td></tr>
79 * <tr><td> paintLabels </td><td> slider </td><td> yes </td></tr>
80 * <tr><td> paintTicks </td><td> slider </td><td> yes </td></tr>
81 * <tr><td> snapToTicks </td><td> slider </td><td> no </td></tr>
82 * <tr><td> value </td><td> model </td><td> no </td></tr>
83 * <tr><td> valueIsAdjusting </td><td> model </td><td> no </td></tr>
84 * </table>
86 * <p>
87 * The various behavioral aspects of these properties follows:
88 * </p>
90 * <ul>
91 * <li>
92 * When non-bound properties stored in the slider change, the slider fires
93 * ChangeEvents to its ChangeListeners.
94 * </li>
95 * <li>
96 * When bound properties stored in the slider change, the slider fires
97 * PropertyChangeEvents to its PropertyChangeListeners
98 * </li>
99 * <li>
100 * If any of the model's properties change, it fires a ChangeEvent to its
101 * ChangeListeners, which include the slider.
102 * </li>
103 * <li>
104 * If the slider receives a ChangeEvent from its model, it will propagate the
105 * ChangeEvent to its ChangeListeners, with the ChangeEvent's "source"
106 * property set to refer to the slider, rather than the model.
107 * </li>
108 * </ul>
110 public class JSlider extends JComponent implements SwingConstants, Accessible,
111 ImageObserver,
112 MenuContainer, Serializable
114 /** DOCUMENT ME! */
115 private static final long serialVersionUID = -1441275936141218479L;
118 * DOCUMENT ME!
120 protected class AccessibleJSlider extends JComponent.AccessibleJComponent
121 implements AccessibleValue
123 private static final long serialVersionUID = -6301740148041106789L;
126 * Creates a new AccessibleJSlider object.
128 * @param value0 DOCUMENT ME!
130 protected AccessibleJSlider()
135 * DOCUMENT ME!
137 * @return DOCUMENT ME!
139 public AccessibleStateSet getAccessibleStateSet()
141 return null;
145 * DOCUMENT ME!
147 * @return DOCUMENT ME!
149 public AccessibleRole getAccessibleRole()
151 return null;
155 * DOCUMENT ME!
157 * @return DOCUMENT ME!
159 public AccessibleValue getAccessibleValue()
161 return null;
165 * DOCUMENT ME!
167 * @return DOCUMENT ME!
169 public Number getCurrentAccessibleValue()
171 return null;
175 * setCurrentAccessibleValue
177 * @param value0 TODO
179 * @return boolean
181 public boolean setCurrentAccessibleValue(Number value0)
183 return false;
187 * getMinimumAccessibleValue
189 * @return Number
191 public Number getMinimumAccessibleValue()
193 return null;
197 * getMaximumAccessibleValue
199 * @return Number
201 public Number getMaximumAccessibleValue()
203 return null;
207 /** Whether or not this slider paints its ticks. */
208 private transient boolean paintTicks = false;
210 /** Whether or not this slider paints its track. */
211 private transient boolean paintTrack = true;
213 /** Whether or not this slider paints its labels. */
214 private transient boolean paintLabels = false;
217 * A dictionary of (Integer, Component) pairs where each Component is a
218 * JLabel and the Integer determines where the label will be painted.
220 private transient Dictionary labelTable;
222 /** The model used to describe the slider. */
223 protected BoundedRangeModel sliderModel;
225 /** The space between major ticks. */
226 protected int majorTickSpacing;
228 /** The space between minor ticks. */
229 protected int minorTickSpacing;
231 /** Whether the slider snaps its values to ticks. */
232 protected boolean snapToTicks = true;
234 /** The orientation of the slider. */
235 protected int orientation = HORIZONTAL;
237 /** Whether the slider is inverted. */
238 private transient boolean isInverted;
240 /** The ChangeListener that listens to the model. */
241 protected ChangeListener changeListener;
243 /** The ChangeEvent that is passed to all listeners of this slider. */
244 protected transient ChangeEvent changeEvent;
247 * Creates a new horizontal JSlider object with a minimum of 0, a maximum of
248 * 100, and a value of 50.
250 public JSlider()
252 this(HORIZONTAL, 0, 100, 50);
256 * Creates a new JSlider object with the given orientation and a minimum of
257 * 0, a maximum of 100, and a value of 50.
259 * @param orientation The orientation of the slider.
261 public JSlider(int orientation)
263 this(orientation, 0, 100, 50);
267 * Creates a new horizontal JSlider object with the given maximum and
268 * minimum and a value that is halfway between the minimum and the
269 * maximum.
271 * @param minimum The minimum value of the JSlider.
272 * @param maximum The maximum value of the JSlider.
274 public JSlider(int minimum, int maximum)
276 this(HORIZONTAL, minimum, maximum, (maximum + minimum) / 2);
280 * Creates a new horizontal JSlider object with the given minimum, maximum,
281 * and value.
283 * @param minimum The minimum value of the JSlider.
284 * @param maximum The maximum value of the JSlider.
285 * @param value The initial value of the JSlider.
287 public JSlider(int minimum, int maximum, int value)
289 this(HORIZONTAL, minimum, maximum, value);
293 * Creates a new JSlider object with the given orientation, minimum,
294 * maximum, and value.
296 * @param orientation The orientation of the JSlider.
297 * @param minimum The minimum value of the JSlider.
298 * @param maximum The maximum value of the JSlider.
299 * @param value The initial value of the JSlider.
301 public JSlider(int orientation, int minimum, int maximum, int value)
303 sliderModel = new DefaultBoundedRangeModel(value, 0, minimum, maximum);
304 if (orientation != HORIZONTAL && orientation != VERTICAL)
305 throw new IllegalArgumentException(orientation + " is not a legal orientation");
306 this.orientation = orientation;
307 changeListener = createChangeListener();
308 sliderModel.addChangeListener(changeListener);
309 updateUI();
313 * Creates a new horizontal JSlider object with the given model.
315 * @param model The model the slider will be created with.
317 public JSlider(BoundedRangeModel model)
319 if (model == null)
320 sliderModel = new DefaultBoundedRangeModel(50, 0, 0, 100);
321 else
322 sliderModel = model;
323 changeListener = createChangeListener();
324 sliderModel.addChangeListener(changeListener);
325 updateUI();
329 * This method returns the current value of the slider.
331 * @return The value of the slider stored in the model.
333 public int getValue()
335 return sliderModel.getValue();
339 * This method sets the value of the slider.
341 * @param value The slider's new value.
343 public void setValue(int value)
345 sliderModel.setValue(value);
349 * This method returns the slider's UI delegate.
351 * @return The slider's UI delegate.
353 public SliderUI getUI()
355 return (SliderUI) ui;
359 * This method sets the slider's UI delegate.
361 * @param ui A SliderUI object to use with this slider.
363 public void setUI(SliderUI ui)
365 super.setUI(ui);
369 * This method sets this slider's UI to the UIManager's default for the
370 * current look and feel.
372 public void updateUI()
374 setUI((SliderUI) UIManager.getUI(this));
375 invalidate();
376 repaint();
380 * This method returns a name to identify which look and feel class will be
381 * the UI delegate for the slider.
383 * @return The Look and Feel classID. "SliderUI"
385 public String getUIClassID()
387 return "SliderUI";
391 * Creates a ChangeListener for this Slider.
393 * @return A new ChangeListener.
395 protected ChangeListener createChangeListener()
397 return new ChangeListener()
399 public void stateChanged(ChangeEvent ce)
401 // No need to trigger a repaint since the UI listens to the model
402 // as well. All we need to do is pass on the stateChanged event
403 // to our listeners.
404 fireStateChanged();
410 * This method registers a listener to this slider. The listener will be
411 * informed of new ChangeEvents.
413 * @param listener The listener to register.
415 public void addChangeListener(ChangeListener listener)
417 listenerList.add(ChangeListener.class, listener);
421 * This method removes a listener from this slider.
423 * @param listener The listener to remove.
425 public void removeChangeListener(ChangeListener listener)
427 listenerList.remove(ChangeListener.class, listener);
431 * This method is called whenever the model fires a ChangeEvent. It should
432 * propagate the ChangeEvent to its listeners with a new ChangeEvent that
433 * identifies the slider as the source.
435 protected void fireStateChanged()
437 Object[] changeListeners = listenerList.getListenerList();
438 if (changeEvent == null)
439 changeEvent = new ChangeEvent(this);
440 for (int i = changeListeners.length - 2; i >= 0; i -= 2)
442 if (changeListeners[i] == ChangeListener.class)
443 ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
448 * This method returns an array of all ChangeListeners listening to this
449 * slider.
451 * @return An array of ChangeListeners listening to this slider.
453 public ChangeListener[] getChangeListeners()
455 return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
459 * This method returns the model of the slider.
461 * @return The slider's model.
463 public BoundedRangeModel getModel()
465 return sliderModel;
469 * This method changes the "model" property. It also needs to unregister
470 * any listeners to the old model and register any listeners to the new
471 * model.
473 * @param model The model to use with the slider.
475 public void setModel(BoundedRangeModel model)
477 // I didn't do the null pointer check on purpose.
478 // If you try it with Sun's, it'll go ahead and set it to null
479 // and bork the next time it tries to access the model.
480 if (model != sliderModel)
482 BoundedRangeModel oldModel = sliderModel;
483 sliderModel = model;
484 oldModel.removeChangeListener(changeListener);
485 sliderModel.addChangeListener(changeListener);
486 firePropertyChange("model", oldModel, sliderModel);
491 * This method returns the minimum value of the slider.
493 * @return The minimum value of the slider.
495 public int getMinimum()
497 return sliderModel.getMinimum();
501 * This method sets the minimum value of the slider.
503 * @param minimum The minimum value of the slider.
505 public void setMinimum(int minimum)
507 sliderModel.setMinimum(minimum);
511 * This method returns the maximum value of the slider.
513 * @return The maximum value of the slider.
515 public int getMaximum()
517 return sliderModel.getMaximum();
521 * This method sets the maximum value of the slider.
523 * @param maximum The maximum value of the slider.
525 public void setMaximum(int maximum)
527 sliderModel.setMaximum(maximum);
531 * This method returns this slider's isAdjusting value which is true if the
532 * thumb is being dragged.
534 * @return The slider's isAdjusting value.
536 public boolean getValueIsAdjusting()
538 return sliderModel.getValueIsAdjusting();
542 * This method sets the isAdjusting value for the slider.
544 * @param adjusting The slider's isAdjusting value.
546 public void setValueIsAdjusting(boolean adjusting)
548 sliderModel.setValueIsAdjusting(adjusting);
552 * This method returns the extent value for this slider.
554 * @return The extent value for this slider.
556 public int getExtent()
558 return sliderModel.getExtent();
562 * This method sets the extent value for this slider.
564 * @param extent The extent value for this slider.
566 public void setExtent(int extent)
568 sliderModel.setExtent(extent);
572 * This method returns the slider orientation.
574 * @return The orientation of the slider.
576 public int getOrientation()
578 return orientation;
582 * This method changes the "orientation" property of this slider. If the
583 * orientation is not VERTICAL or HORIZONTAL, this method does nothing.
585 * @param orientation The orientation of this slider.
587 public void setOrientation(int orientation)
589 if (orientation != VERTICAL && orientation != HORIZONTAL)
590 throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL");
591 if (orientation != this.orientation)
593 int oldOrientation = this.orientation;
594 this.orientation = orientation;
595 firePropertyChange("orientation", oldOrientation,
596 this.orientation);
601 * This method returns the label table for this slider.
603 * @return The label table for this slider.
605 public Dictionary getLabelTable()
607 return labelTable;
611 * This method changes the "labelTable" property of this slider.
613 * @param table The label table for this slider.
615 public void setLabelTable(Dictionary table)
617 if (table != labelTable)
619 Dictionary oldTable = labelTable;
620 labelTable = table;
621 firePropertyChange("labelTable", oldTable, labelTable);
626 * This method is called to reset UI delegates for the labels in the
627 * labelTable to a default for the current look and feel.
629 protected void updateLabelUIs()
631 if (labelTable == null)
632 return;
633 for (Enumeration list = labelTable.elements(); list.hasMoreElements();)
635 JLabel label = (JLabel) list.nextElement();
636 label.updateUI();
641 * Creates a hashtable of (Integer, JLabel) pairs that can be used as a
642 * label table for this slider. The labels will start from the sliders
643 * minimum and increase by the increment. Each label will have a text
644 * string indicating their integer value.
646 * @param increment The increment to between labels.
648 * @return A hashtable with the labels and their keys.
650 public Hashtable createStandardLabels(int increment)
652 return createStandardLabels(increment, sliderModel.getMinimum());
656 * Creates a hashtable of (Integer, JLabel) pairs that can be used as a
657 * label table for this slider. The labels will start from the given start
658 * value and increase by the increment. Each label will have a text string
659 * indicating their integer value.
661 * @param increment The increment to between labels.
662 * @param start The value to start from.
664 * @return A hashtable with the labels and their keys.
666 public Hashtable createStandardLabels(int increment, int start)
668 Hashtable table = new Hashtable();
669 JLabel label;
670 Dimension dim;
672 int max = sliderModel.getMaximum();
674 for (int i = start; i <= max; i += increment)
676 label = new JLabel(String.valueOf(i));
677 label.setVerticalAlignment(CENTER);
678 label.setHorizontalAlignment(CENTER);
680 // Make sure these labels have the width and height
681 // they want.
682 dim = label.getPreferredSize();
683 label.setBounds(label.getX(), label.getY(),
684 (int) dim.getWidth(),
685 (int) dim.getHeight());
686 table.put(new Integer(i), label);
688 return table;
692 * This method returns whether the slider is inverted. Horizontal sliders
693 * that are not inverted will have the minimums on the left. If they are
694 * inverted, the minimums will be on the right. Vertical sliders that are
695 * not inverted will have the minimums at the bottom. If they are inverted,
696 * the minimums will be at the top.
698 * @return Whether this slider is inverted.
700 public boolean getInverted()
702 return isInverted;
706 * This method changes the "inverted" property for this slider.Horizontal
707 * sliders that are not inverted will have the minimums on the left. If
708 * they are inverted, the minimums will be on the right. Vertical sliders
709 * that are not inverted will have the minimums at the bottom. If they are
710 * inverted, the minimums will be at the top. However, if the slider's
711 * componentOrientation is set to RIGHT_TO_LEFT, then everything gets
712 * reversed again.
714 * @param inverted Whether the slider should be inverted.
716 public void setInverted(boolean inverted)
718 if (isInverted != inverted)
720 boolean oldInverted = isInverted;
721 isInverted = inverted;
722 firePropertyChange("inverted", oldInverted, isInverted);
727 * This method returns the amount of units between each major tick mark.
729 * @return The amount of units between each major tick mark.
731 public int getMajorTickSpacing()
733 return majorTickSpacing;
737 * This method changes the "majorTickSpacing" property for this slider. The
738 * major tick spacing is the amount of units between each major tick mark.
740 * @param spacing The amount of units between each major tick mark.
742 public void setMajorTickSpacing(int spacing)
744 if (majorTickSpacing != spacing)
746 int oldSpacing = majorTickSpacing;
747 majorTickSpacing = spacing;
748 firePropertyChange("majorTickSpacing", oldSpacing,
749 majorTickSpacing);
754 * This method returns the amount of units between each minor tick mark.
756 * @return The amount of units between each minor tick mark.
758 public int getMinorTickSpacing()
760 return minorTickSpacing;
764 * This method changes the "minorTickSpacing" property for this slider. The
765 * minor tick spacing is the amount of units between each minor tick mark.
767 * @param spacing The amount of units between each minor tick mark.
769 public void setMinorTickSpacing(int spacing)
771 if (minorTickSpacing != spacing)
773 int oldSpacing = minorTickSpacing;
774 minorTickSpacing = spacing;
775 firePropertyChange("minorTickSpacing", oldSpacing,
776 minorTickSpacing);
781 * This method returns whether this slider is snapping to ticks. Sliders
782 * that snap to ticks will automatically move the thumb to the nearest tick
783 * mark.
785 * @return Whether this slider snaps to ticks.
787 public boolean getSnapToTicks()
789 return snapToTicks;
793 * This method sets whether this slider will snap to ticks. Sliders that
794 * snap to ticks will automatically move the thumb to the nearest tick
795 * mark.
797 * @param snap Whether this slider snaps to ticks.
799 public void setSnapToTicks(boolean snap)
801 if (snap != snapToTicks)
803 snapToTicks = snap;
804 fireStateChanged();
809 * This method returns whether the slider will paint its tick marks. In
810 * addition to setting this property to true, one of minor tick spacing or
811 * major tick spacing must be set to a value greater than 0 in order for
812 * ticks to be painted.
814 * @return Whether ticks will be painted.
816 public boolean getPaintTicks()
818 return paintTicks;
822 * This method changes the "paintTicks" property for this slider. In
823 * addition to setting this property to true, one of minor tick spacing or
824 * major tick spacing must be set to a value greater than 0 in order for
825 * ticks to be painted.
827 * @param paint Whether ticks will be painted.
829 public void setPaintTicks(boolean paint)
831 if (paint != paintTicks)
833 boolean oldPaintTicks = paintTicks;
834 paintTicks = paint;
835 firePropertyChange("paintTicks", oldPaintTicks, paintTicks);
840 * This method returns whether the track will be painted.
842 * @return Whether the track will be painted.
844 public boolean getPaintTrack()
846 return paintTrack;
850 * This method sets whether the track will be painted.
852 * @param paint Whether the track will be painted.
854 public void setPaintTrack(boolean paint)
856 paintTrack = paint;
860 * This method returns whether labels will be painted.
862 * @return Whether labels will be painted.
864 public boolean getPaintLabels()
866 return paintLabels;
870 * This method changes the "paintLabels" property.
872 * @param paint Whether labels will be painted.
874 public void setPaintLabels(boolean paint)
876 if (paint != paintLabels)
878 boolean oldPaintLabels = paintLabels;
879 paintLabels = paint;
880 firePropertyChange("paintLabels", oldPaintLabels, paintLabels);
885 * This method is used primarily for debugging purposes and returns a string
886 * that can be used to represent this slider.
888 * @return A string representing this slider.
890 protected String paramString()
892 return "JSlider";
896 * DOCUMENT ME!
898 * @return DOCUMENT ME!
900 public AccessibleContext getAccessibleContext()
902 if (accessibleContext == null)
903 accessibleContext = new AccessibleJSlider();
905 return accessibleContext;