| /* JSlider.java -- |
| Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| package javax.swing; |
| |
| import java.awt.Dimension; |
| import java.awt.MenuContainer; |
| import java.awt.image.ImageObserver; |
| import java.beans.PropertyChangeEvent; |
| import java.io.Serializable; |
| import java.util.Dictionary; |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| |
| import javax.accessibility.Accessible; |
| import javax.accessibility.AccessibleContext; |
| import javax.accessibility.AccessibleRole; |
| import javax.accessibility.AccessibleState; |
| import javax.accessibility.AccessibleStateSet; |
| import javax.accessibility.AccessibleValue; |
| import javax.swing.event.ChangeEvent; |
| import javax.swing.event.ChangeListener; |
| import javax.swing.plaf.SliderUI; |
| |
| /** |
| * A visual component that allows selection of a value within a |
| * range by adjusting a thumb in a track. The values for the minimum, |
| * maximum, extent and value are stored in a {@link |
| * DefaultBoundedRangeModel}. |
| * <p> |
| * A <code>JSlider</code> component has the following properties: |
| * </p> |
| * |
| * <table> |
| * <tr><th> Property </th><th> Stored in </th><th> Bound? </th></tr> |
| * <tr><td> extent </td><td> model </td><td> no </td></tr> |
| * <tr><td> inverted </td><td> slider </td><td> yes </td></tr> |
| * <tr><td> labelTable </td><td> slider </td><td> yes </td></tr> |
| * <tr><td> majorTickSpacing </td><td> slider </td><td> yes </td></tr> |
| * <tr><td> maximum </td><td> model </td><td> yes </td></tr> |
| * <tr><td> minimum </td><td> model </td><td> yes </td></tr> |
| * <tr><td> minorTickSpacing </td><td> slider </td><td> yes </td></tr> |
| * <tr><td> model </td><td> slider </td><td> yes </td></tr> |
| * <tr><td> orientation </td><td> slider </td><td> yes </td></tr> |
| * <tr><td> paintLabels </td><td> slider </td><td> yes </td></tr> |
| * <tr><td> paintTicks </td><td> slider </td><td> yes </td></tr> |
| * <tr><td> snapToTicks </td><td> slider </td><td> yes </td></tr> |
| * <tr><td> value </td><td> model </td><td> no </td></tr> |
| * <tr><td> valueIsAdjusting </td><td> model </td><td> no </td></tr> |
| * </table> |
| * |
| * <p> |
| * The various behavioural aspects of these properties follows: |
| * </p> |
| * |
| * <ul> |
| * <li> |
| * When a non-bound property stored in the slider changes, the slider fires |
| * a {@link ChangeEvent} to its change listeners. |
| * </li> |
| * <li> |
| * When a bound property stored in the slider changes, the slider fires a |
| * {@link PropertyChangeEvent} to its property change listeners. |
| * </li> |
| * <li> |
| * If any of the model's properties change, it fires a {@link ChangeEvent} to |
| * its listeners, which include the slider. |
| * </li> |
| * <li> |
| * If the slider receives a {@link ChangeEvent} from its model, it will |
| * propagate the event to its own change listeners, with the event's "source" |
| * property set to refer to the slider, rather than the model. |
| * </li> |
| * </ul> |
| */ |
| public class JSlider extends JComponent implements SwingConstants, Accessible, |
| ImageObserver, |
| MenuContainer, Serializable |
| { |
| private static final long serialVersionUID = -1441275936141218479L; |
| |
| /** |
| * Provides the accessibility features for the <code>JSlider</code> |
| * component. |
| */ |
| protected class AccessibleJSlider extends JComponent.AccessibleJComponent |
| implements AccessibleValue |
| { |
| private static final long serialVersionUID = -6301740148041106789L; |
| |
| /** |
| * Creates a new <code>AccessibleJSlider</code> instance. |
| */ |
| protected AccessibleJSlider() |
| { |
| // Nothing to do here. |
| } |
| |
| /** |
| * Returns a set containing the current state of the {@link JSlider} |
| * component. |
| * |
| * @return The accessible state set. |
| */ |
| public AccessibleStateSet getAccessibleStateSet() |
| { |
| AccessibleStateSet result = super.getAccessibleStateSet(); |
| if (orientation == JSlider.HORIZONTAL) |
| result.add(AccessibleState.HORIZONTAL); |
| else if (orientation == JSlider.VERTICAL) |
| result.add(AccessibleState.VERTICAL); |
| return result; |
| } |
| |
| /** |
| * Returns the accessible role for the <code>JSlider</code> component. |
| * |
| * @return {@link AccessibleRole#SLIDER}. |
| */ |
| public AccessibleRole getAccessibleRole() |
| { |
| return AccessibleRole.SLIDER; |
| } |
| |
| /** |
| * Returns an object that provides access to the current, minimum and |
| * maximum values for the {@link JSlider}. Since this class implements |
| * {@link AccessibleValue}, it returns itself. |
| * |
| * @return The accessible value. |
| */ |
| public AccessibleValue getAccessibleValue() |
| { |
| return this; |
| } |
| |
| /** |
| * Returns the current value of the {@link JSlider} component, as an |
| * {@link Integer}. |
| * |
| * @return The current value of the {@link JSlider} component. |
| */ |
| public Number getCurrentAccessibleValue() |
| { |
| return new Integer(getValue()); |
| } |
| |
| /** |
| * Sets the current value of the {@link JSlider} component and sends a |
| * {@link PropertyChangeEvent} (with the property name |
| * {@link AccessibleContext#ACCESSIBLE_VALUE_PROPERTY}) to all registered |
| * listeners. If the supplied value is <code>null</code>, this method |
| * does nothing and returns <code>false</code>. |
| * |
| * @param value the new slider value (<code>null</code> permitted). |
| * |
| * @return <code>true</code> if the slider value is updated, and |
| * <code>false</code> otherwise. |
| */ |
| public boolean setCurrentAccessibleValue(Number value) |
| { |
| if (value == null) |
| return false; |
| Number oldValue = getCurrentAccessibleValue(); |
| setValue(value.intValue()); |
| firePropertyChange(AccessibleContext.ACCESSIBLE_VALUE_PROPERTY, oldValue, |
| new Integer(getValue())); |
| return true; |
| } |
| |
| /** |
| * Returns the minimum value of the {@link JSlider} component, as an |
| * {@link Integer}. |
| * |
| * @return The minimum value of the {@link JSlider} component. |
| */ |
| public Number getMinimumAccessibleValue() |
| { |
| return new Integer(getMinimum()); |
| } |
| |
| /** |
| * Returns the maximum value of the {@link JSlider} component, as an |
| * {@link Integer}. |
| * |
| * @return The maximum value of the {@link JSlider} component. |
| */ |
| public Number getMaximumAccessibleValue() |
| { |
| return new Integer(getMaximum()); |
| } |
| } |
| |
| /** Whether or not this slider paints its ticks. */ |
| private transient boolean paintTicks; |
| |
| /** Whether or not this slider paints its track. */ |
| private transient boolean paintTrack = true; |
| |
| /** Whether or not this slider paints its labels. */ |
| private transient boolean paintLabels; |
| |
| /** |
| * A dictionary of (Integer, Component) pairs where each Component is a |
| * JLabel and the Integer determines where the label will be painted. |
| */ |
| private transient Dictionary labelTable; |
| |
| /** The model used to store the slider's range and current value. */ |
| protected BoundedRangeModel sliderModel; |
| |
| /** The space/distance between major ticks. */ |
| protected int majorTickSpacing; |
| |
| /** The space/distance between minor ticks. */ |
| protected int minorTickSpacing; |
| |
| /** Whether the slider snaps its values to ticks. */ |
| protected boolean snapToTicks; |
| |
| /** The orientation (horizontal or vertical) of the slider. */ |
| protected int orientation = HORIZONTAL; |
| |
| /** Whether the slider is inverted. */ |
| private transient boolean isInverted; |
| |
| /** |
| * The listener that monitors the slider's model and forwards events to the |
| * slider's listeners (see <code>createChangeListener()</code>). |
| */ |
| protected ChangeListener changeListener; |
| |
| /** The change event that is passed to all listeners of this slider. */ |
| protected transient ChangeEvent changeEvent; |
| |
| /** |
| * Creates a new horizontal <code>JSlider</code> instance with a minimum of |
| * 0, a maximum of 100, and a value of 50. |
| */ |
| public JSlider() |
| { |
| this(HORIZONTAL, 0, 100, 50); |
| } |
| |
| /** |
| * Creates a new <code>JSlider</code> instance with the given orientation |
| * and a minimum of 0, a maximum of 100, and a value of 50. |
| * |
| * @param orientation The orientation of the slider ({@link #HORIZONTAL} or |
| * {@link #VERTICAL}). |
| * |
| * @throws IllegalArgumentException if <code>orientation</code> is not one of |
| * the specified values. |
| */ |
| public JSlider(int orientation) |
| { |
| this(orientation, 0, 100, 50); |
| } |
| |
| /** |
| * Creates a new horizontal <code>JSlider</code> instance with the given |
| * maximum and minimum and a value that is halfway between the minimum and the |
| * maximum. |
| * |
| * @param minimum The minimum value. |
| * @param maximum The maximum value. |
| * |
| * @throws IllegalArgumentException if <code>minimum</code> is greater than |
| * <code>maximum</code>. |
| */ |
| public JSlider(int minimum, int maximum) |
| { |
| this(HORIZONTAL, minimum, maximum, (maximum + minimum) / 2); |
| } |
| |
| /** |
| * Creates a new horizontal <code>JSlider</code> instance with the given |
| * minimum, maximum, and value. |
| * |
| * @param minimum The minimum value. |
| * @param maximum The maximum value. |
| * @param value The initial value. |
| * |
| * @throws IllegalArgumentException if <code>value</code> is not in the |
| * specified range. |
| * @throws IllegalArgumentException if <code>minimum</code> is greater than |
| * <code>maximum</code>. |
| */ |
| public JSlider(int minimum, int maximum, int value) |
| { |
| this(HORIZONTAL, minimum, maximum, value); |
| } |
| |
| /** |
| * Creates a new <code>JSlider</code> instance with the given orientation, |
| * minimum, maximum, and value. |
| * |
| * @param orientation The orientation of the slider ({@link #HORIZONTAL} or |
| * {@link #VERTICAL}). |
| * @param minimum The minimum value of the JSlider. |
| * @param maximum The maximum value of the JSlider. |
| * @param value The initial value of the JSlider. |
| * |
| * @throws IllegalArgumentException if <code>orientation</code> is not one of |
| * the specified values. |
| * @throws IllegalArgumentException if <code>value</code> is not in the |
| * specified range. |
| * @throws IllegalArgumentException if <code>minimum</code> is greater than |
| * <code>maximum</code>. |
| */ |
| public JSlider(int orientation, int minimum, int maximum, int value) |
| { |
| sliderModel = new DefaultBoundedRangeModel(value, 0, minimum, maximum); |
| if (orientation != HORIZONTAL && orientation != VERTICAL) |
| throw new IllegalArgumentException(orientation |
| + " is not a legal orientation"); |
| this.orientation = orientation; |
| changeListener = createChangeListener(); |
| sliderModel.addChangeListener(changeListener); |
| updateUI(); |
| } |
| |
| /** |
| * Creates a new horizontal <code>JSlider</code> instance with the given |
| * model. |
| * |
| * @param model The model (<code>null</code> not permitted). |
| * |
| * @throws NullPointerException if <code>model</code> is <code>null</code>. |
| */ |
| public JSlider(BoundedRangeModel model) |
| { |
| sliderModel = model; |
| changeListener = createChangeListener(); |
| sliderModel.addChangeListener(changeListener); |
| updateUI(); |
| } |
| |
| /** |
| * Returns the slider's value (from the slider's model). |
| * |
| * @return The value of the slider. |
| * |
| * @see #setValue(int) |
| */ |
| public int getValue() |
| { |
| return sliderModel.getValue(); |
| } |
| |
| /** |
| * Sets the slider's value and sends a {@link ChangeEvent} to all |
| * registered listeners. Note that the model will fire a change event to all |
| * of its registered listeners first (with the model as the event source) and |
| * then the slider will fire another change event to all of its registered |
| * listeners (this time with the slider as the event source). |
| * |
| * @param value the new value. |
| * |
| * @see #getValue() |
| */ |
| public void setValue(int value) |
| { |
| sliderModel.setValue(value); |
| } |
| |
| /** |
| * Returns the slider's UI delegate. |
| * |
| * @return The slider's UI delegate. |
| */ |
| public SliderUI getUI() |
| { |
| return (SliderUI) ui; |
| } |
| |
| /** |
| * Sets the slider's UI delegate. |
| * |
| * @param ui the UI delegate. |
| */ |
| public void setUI(SliderUI ui) |
| { |
| super.setUI(ui); |
| } |
| |
| /** |
| * Sets this slider's UI delegate to the default (obtained from the |
| * {@link UIManager}) for the current look and feel. |
| */ |
| public void updateUI() |
| { |
| setUI((SliderUI) UIManager.getUI(this)); |
| } |
| |
| /** |
| * Returns the suffix (<code>"SliderUI"</code> in this case) used to |
| * determine the class name for a UI delegate that can provide the look and |
| * feel for a <code>JSlider</code>. |
| * |
| * @return <code>"SliderUI"</code>. |
| */ |
| public String getUIClassID() |
| { |
| return "SliderUI"; |
| } |
| |
| /** |
| * Creates a {@link ChangeListener} that is added to the slider's model and |
| * forwards change events generated by the model to the listeners that are |
| * registered with the <code>JSlider</code> (by calling the |
| * {@link #fireStateChanged} method). |
| * |
| * @return A new listener. |
| */ |
| protected ChangeListener createChangeListener() |
| { |
| return new ChangeListener() |
| { |
| public void stateChanged(ChangeEvent ce) |
| { |
| // No need to trigger a repaint since the UI listens to the model |
| // as well. All we need to do is pass on the stateChanged event |
| // to our listeners. |
| fireStateChanged(); |
| } |
| }; |
| } |
| |
| /** |
| * Registers a listener with the slider so that it will receive |
| * {@link ChangeEvent} notifications. Note that change events generated |
| * by the slider's model will be forwarded automatically to the slider's |
| * listeners. |
| * |
| * @param listener the listener to register. |
| * |
| * @see #removeChangeListener(ChangeListener) |
| */ |
| public void addChangeListener(ChangeListener listener) |
| { |
| listenerList.add(ChangeListener.class, listener); |
| } |
| |
| /** |
| * Removes a listener from this slider so that it will no longer receive |
| * {@link ChangeEvent} notifications from the slider. |
| * |
| * @param listener The listener to remove. |
| * |
| * @see #addChangeListener(ChangeListener) |
| */ |
| public void removeChangeListener(ChangeListener listener) |
| { |
| listenerList.remove(ChangeListener.class, listener); |
| } |
| |
| /** |
| * Sends a {@link ChangeEvent} to all registered listeners, with this slider |
| * as the source. |
| */ |
| protected void fireStateChanged() |
| { |
| Object[] changeListeners = listenerList.getListenerList(); |
| if (changeEvent == null) |
| changeEvent = new ChangeEvent(this); |
| for (int i = changeListeners.length - 2; i >= 0; i -= 2) |
| { |
| if (changeListeners[i] == ChangeListener.class) |
| ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent); |
| } |
| } |
| |
| /** |
| * Returns an array containing all the {@link ChangeListener} instances |
| * registered with this slider. If no listeners are registered, this method |
| * returns an empty array. |
| * |
| * @return An array array containing all the {@link ChangeListener} instances |
| * registered with this slider (possibly empty, but never |
| * <code>null</code>). |
| */ |
| public ChangeListener[] getChangeListeners() |
| { |
| return (ChangeListener[]) listenerList.getListeners(ChangeListener.class); |
| } |
| |
| /** |
| * Returns the slider's model, which stores the minimum, maximum and current |
| * values. |
| * |
| * @return The slider's model. |
| * |
| * @see #setModel(BoundedRangeModel) |
| */ |
| public BoundedRangeModel getModel() |
| { |
| return sliderModel; |
| } |
| |
| /** |
| * Sets the slider's model and sends a {@link PropertyChangeEvent} (with the |
| * property name "model") to all registered listeners. The change listener |
| * that the slider registered with the original model is removed and added |
| * to the new model (this ensures that {@link ChangeEvent} notifications |
| * generated by the model are automatically forwarded to listeners that are |
| * registered with the slider). |
| * |
| * @param model The model to use with the slider. |
| * |
| * @see #getModel() |
| */ |
| public void setModel(BoundedRangeModel model) |
| { |
| // I didn't do the null pointer check on purpose. |
| // If you try it with Sun's, it'll go ahead and set it to null |
| // and bork the next time it tries to access the model. |
| if (model != sliderModel) |
| { |
| BoundedRangeModel oldModel = sliderModel; |
| sliderModel = model; |
| oldModel.removeChangeListener(changeListener); |
| sliderModel.addChangeListener(changeListener); |
| firePropertyChange("model", oldModel, sliderModel); |
| } |
| } |
| |
| /** |
| * Returns the minimum value of the slider (from the slider's model). |
| * |
| * @return The minimum value of the slider. |
| * |
| * @see #setMinimum(int) |
| */ |
| public int getMinimum() |
| { |
| return sliderModel.getMinimum(); |
| } |
| |
| /** |
| * Sets the minimum value of the slider and fires a |
| * {@link PropertyChangeEvent} (with the property name "minimum") to all |
| * registered listeners. Note that: |
| * <p> |
| * <ul> |
| * <li>the minimum value is stored in the slider's model (see |
| * {@link #getModel()});</li> |
| * <li>in addition to the property change event, the slider also fires a |
| * {@link ChangeEvent}.</li> |
| * </ul> |
| * |
| * @param minimum The minimum value of the slider. |
| * |
| * @see #getMinimum() |
| */ |
| public void setMinimum(int minimum) |
| { |
| int old = sliderModel.getMinimum(); |
| sliderModel.setMinimum(minimum); |
| if (minimum != old) |
| firePropertyChange("minimum", old, minimum); |
| } |
| |
| /** |
| * Returns the slider's maximum value (obtained from the slider's model). |
| * |
| * @return The maximum value of the slider. |
| * |
| * @see #setMaximum(int) |
| */ |
| public int getMaximum() |
| { |
| return sliderModel.getMaximum(); |
| } |
| |
| /** |
| * Sets the maximum value of the slider and fires a |
| * {@link PropertyChangeEvent} (with the property name "maximum") to all |
| * registered listeners. Note that: |
| * <p> |
| * <ul> |
| * <li>the maximum value is stored in the slider's model (see |
| * {@link #getModel()});</li> |
| * <li>in addition to the property change event, the slider also fires a |
| * {@link ChangeEvent}.</li> |
| * </ul> |
| * |
| * @param maximum The maximum value of the slider. |
| * |
| * @see #getMaximum() |
| */ |
| public void setMaximum(int maximum) |
| { |
| int old = sliderModel.getMaximum(); |
| sliderModel.setMaximum(maximum); |
| if (maximum != old) |
| firePropertyChange("maximum", old, maximum); |
| } |
| |
| /** |
| * Returns the <code>valueIsAdjusting</code> flag from the slider's model. |
| * |
| * @return The <code>valueIsAdjusting</code> flag from the slider's model. |
| * |
| * @see #setValueIsAdjusting(boolean) |
| */ |
| public boolean getValueIsAdjusting() |
| { |
| return sliderModel.getValueIsAdjusting(); |
| } |
| |
| /** |
| * Sets the <code>valueIsAdjusting</code> flag in the slider's model, and |
| * sends a {@link ChangeEvent} to all registered listeners. |
| * |
| * @param adjusting the new flag value. |
| * |
| * @see #getValueIsAdjusting() |
| */ |
| public void setValueIsAdjusting(boolean adjusting) |
| { |
| sliderModel.setValueIsAdjusting(adjusting); |
| } |
| |
| /** |
| * Returns the slider's extent value, obtained from the slider's model. |
| * |
| * @return The extent value. |
| * |
| * @see #setExtent(int) |
| */ |
| public int getExtent() |
| { |
| return sliderModel.getExtent(); |
| } |
| |
| /** |
| * Sets the slider's extent value and sends a {@link ChangeEvent} to all |
| * registered listeners. Note that the model will fire a change event to all |
| * of its registered listeners first (with the model as the event source) and |
| * then the slider will fire another change event to all of its registered |
| * listeners (this time with the slider as the event source). |
| * |
| * @param extent The extent value for this slider. |
| * |
| * @see #getExtent() |
| */ |
| public void setExtent(int extent) |
| { |
| sliderModel.setExtent(extent); |
| } |
| |
| /** |
| * Returns the orientation of the slider, either {@link JSlider#HORIZONTAL} |
| * or {@link JSlider#VERTICAL}. |
| * |
| * @return The orientation of the slider. |
| * |
| * @see #setOrientation(int) |
| */ |
| public int getOrientation() |
| { |
| return orientation; |
| } |
| |
| /** |
| * Sets the orientation for the slider and sends a |
| * {@link PropertyChangeEvent} (with the property name "orientation") to all |
| * registered listeners. |
| * |
| * @param orientation the orientation (one of {@link JSlider#HORIZONTAL} or |
| * {@link JSlider#VERTICAL}). |
| * |
| * @throws IllegalArgumentException if <code>orientation</code> is not one of |
| * the permitted values. |
| * |
| * @see #getOrientation() |
| */ |
| public void setOrientation(int orientation) |
| { |
| if (orientation != VERTICAL && orientation != HORIZONTAL) |
| throw new IllegalArgumentException( |
| "orientation must be one of: VERTICAL, HORIZONTAL"); |
| if (orientation != this.orientation) |
| { |
| int oldOrientation = this.orientation; |
| this.orientation = orientation; |
| firePropertyChange("orientation", oldOrientation, this.orientation); |
| } |
| } |
| |
| /** |
| * Returns the label table for the slider. |
| * |
| * @return The label table for the slider (possibly <code>null</code>). |
| * |
| * @see #setLabelTable(Dictionary) |
| */ |
| public Dictionary getLabelTable() |
| { |
| return labelTable; |
| } |
| |
| /** |
| * Sets the table of labels for the slider and sends a |
| * {@link PropertyChangeEvent} (with the property name "labelTable") to all |
| * registered listeners. |
| * |
| * @param table the table of labels (<code>null</code> permitted). |
| * |
| * @see #getLabelTable() |
| */ |
| public void setLabelTable(Dictionary table) |
| { |
| if (table != labelTable) |
| { |
| Dictionary oldTable = labelTable; |
| labelTable = table; |
| firePropertyChange("labelTable", oldTable, labelTable); |
| } |
| } |
| |
| /** |
| * Resets the UI delegates for the labels in the <code>labelTable</code> to |
| * the default for the current look and feel. |
| */ |
| protected void updateLabelUIs() |
| { |
| if (labelTable == null) |
| return; |
| for (Enumeration list = labelTable.elements(); list.hasMoreElements();) |
| { |
| JLabel label = (JLabel) list.nextElement(); |
| label.updateUI(); |
| } |
| } |
| |
| /** |
| * Creates a hashtable of <code>(Integer, JLabel)</code> pairs that can be |
| * used as a label table for this slider. The labels will start from the |
| * slider's minimum and increase by the increment. Each label will have a text |
| * string indicating its integer value. |
| * |
| * @param increment The increment between labels (must be > 0). |
| * |
| * @return A hashtable containing the labels. |
| * |
| * @throws IllegalArgumentException if <code>increment</code> is not greater |
| * than zero. |
| */ |
| public Hashtable createStandardLabels(int increment) |
| { |
| return createStandardLabels(increment, sliderModel.getMinimum()); |
| } |
| |
| /** |
| * Creates a hashtable of <code>(Integer, JLabel)</code> pairs that can be |
| * used as a label table for this slider. The labels will start from the |
| * given start value and increase by the increment. Each label will have a |
| * text string indicating its integer value. |
| * |
| * @param increment The increment between labels (must be > 0). |
| * @param start The value to start from. |
| * |
| * @return A hashtable with the labels and their keys. |
| * |
| * @throws IllegalArgumentException if <code>increment</code> is not greater |
| * than zero, or <code>start</code> is not within the range of the |
| * model. |
| */ |
| public Hashtable createStandardLabels(int increment, int start) |
| { |
| if (increment <= 0) |
| throw new IllegalArgumentException("Requires 'increment' > 0."); |
| if (start < getMinimum() || start > getMaximum()) |
| throw new IllegalArgumentException("The 'start' value is out of range."); |
| Hashtable table = new Hashtable(); |
| JLabel label; |
| Dimension dim; |
| |
| int max = sliderModel.getMaximum(); |
| |
| for (int i = start; i <= max; i += increment) |
| { |
| label = new JLabel(String.valueOf(i)); |
| label.setVerticalAlignment(CENTER); |
| label.setHorizontalAlignment(CENTER); |
| |
| // Make sure these labels have the width and height |
| // they want. |
| dim = label.getPreferredSize(); |
| label.setBounds(label.getX(), label.getY(), |
| (int) dim.getWidth(), |
| (int) dim.getHeight()); |
| table.put(new Integer(i), label); |
| } |
| return table; |
| } |
| |
| /** |
| * Returns the flag that controls whether or not the value scale for the |
| * slider is inverted (the default value is <code>false</code>). |
| * |
| * @return The flag that controls whether or not the value scale for the |
| * slider is inverted. |
| * |
| * @see #setInverted(boolean) |
| */ |
| public boolean getInverted() |
| { |
| return isInverted; |
| } |
| |
| /** |
| * Sets the flag that controls whether or not the value scale for the |
| * slider is inverted and, if the new flag value is different to the old flag |
| * value, sends a {@link PropertyChangeEvent} to all registered listeners. |
| * Typically, a horizontal slider will display a scale that increases from |
| * left to right, but this is reversed if the 'inverted' flag is set to |
| * <code>true</code>. Similarly, a vertical slider will display a scale that |
| * increases from bottom to top, and this is reversed if the 'inverted' flag |
| * is set to <code>true</code>. |
| * |
| * @param inverted the new flag value. |
| * |
| * @see #getInverted() |
| */ |
| public void setInverted(boolean inverted) |
| { |
| if (isInverted != inverted) |
| { |
| boolean oldInverted = isInverted; |
| isInverted = inverted; |
| firePropertyChange("inverted", oldInverted, isInverted); |
| } |
| } |
| |
| /** |
| * Returns the distance between major tick marks along the slider's value |
| * scale. |
| * |
| * @return The amount of units between each major tick mark. |
| * |
| * @see #setMajorTickSpacing(int) |
| */ |
| public int getMajorTickSpacing() |
| { |
| return majorTickSpacing; |
| } |
| |
| /** |
| * Sets the distance between major tick marks along the slider's value scale, |
| * and sends a {@link PropertyChangeEvent} (with the property name |
| * "majorTickSpacing") to all registered listeners. |
| * |
| * @param spacing the distance between major tick marks. |
| * |
| * @see #getMajorTickSpacing() |
| */ |
| public void setMajorTickSpacing(int spacing) |
| { |
| if (majorTickSpacing != spacing) |
| { |
| int oldSpacing = majorTickSpacing; |
| majorTickSpacing = spacing; |
| firePropertyChange("majorTickSpacing", oldSpacing, majorTickSpacing); |
| } |
| } |
| |
| /** |
| * Returns the distance between minor tick marks along the slider's value |
| * scale. |
| * |
| * @return The distance between minor tick marks along the slider's value |
| * scale. |
| * |
| * @see #setMinorTickSpacing(int) |
| */ |
| public int getMinorTickSpacing() |
| { |
| return minorTickSpacing; |
| } |
| |
| /** |
| * Sets the distance between minor tick marks along the slider's value scale, |
| * and sends a {@link PropertyChangeEvent} (with the property name |
| * "minorTickSpacing") to all registered listeners. |
| * |
| * @param spacing the distance between minor tick marks. |
| * |
| * @see #getMinorTickSpacing() |
| */ |
| public void setMinorTickSpacing(int spacing) |
| { |
| if (minorTickSpacing != spacing) |
| { |
| int oldSpacing = minorTickSpacing; |
| minorTickSpacing = spacing; |
| firePropertyChange("minorTickSpacing", oldSpacing, minorTickSpacing); |
| } |
| } |
| |
| /** |
| * Returns the flag that controls whether the slider thumb will snap to ticks. |
| * Sliders that snap to ticks will automatically move the thumb to the |
| * nearest tick mark. |
| * |
| * @return <code>true</code> if the slider thumb automatically. |
| * |
| * @see #setSnapToTicks(boolean) |
| */ |
| public boolean getSnapToTicks() |
| { |
| return snapToTicks; |
| } |
| |
| /** |
| * Sets the flag that controls whether the slider thumb will snap to ticks |
| * and sends a {@link PropertyChangeEvent} (with the property name |
| * 'snapToTicks') to all registered listeners. Sliders that snap to ticks |
| * will automatically move the thumb to the nearest tick mark. |
| * |
| * @param snap the new flag value. |
| * |
| * @see #getSnapToTicks() |
| */ |
| public void setSnapToTicks(boolean snap) |
| { |
| if (snap != snapToTicks) |
| { |
| snapToTicks = snap; |
| firePropertyChange("snapToTicks", !snap, snap); |
| } |
| } |
| |
| /** |
| * Returns the flag that controls whether or not tick marks are painted along |
| * the slider's value scale. |
| * |
| * @return <code>true</code> if tick marks should be painted, and |
| * <code>false</code> if tick marks should not be painted. |
| * |
| * @see #setPaintTicks(boolean) |
| */ |
| public boolean getPaintTicks() |
| { |
| return paintTicks; |
| } |
| |
| /** |
| * Sets the flag that controls whether or not tick marks are painted along |
| * the slider's value scale, and sends a {@link PropertyChangeEvent} (with |
| * the property name "paintTicks") to all registered listeners. In |
| * addition to setting this property to <code>true</code>, one or both of the |
| * minor tick spacing and major tick spacing attributes must be set to a |
| * value greater than 0 in order for ticks to be painted. |
| * |
| * @param paint Whether ticks will be painted. |
| * |
| * @see #getPaintTicks() |
| */ |
| public void setPaintTicks(boolean paint) |
| { |
| if (paint != paintTicks) |
| { |
| boolean oldPaintTicks = paintTicks; |
| paintTicks = paint; |
| firePropertyChange("paintTicks", oldPaintTicks, paintTicks); |
| } |
| } |
| |
| /** |
| * Returns the flag that controls whether or not the track is painted. |
| * |
| * @return Whether the track will be painted. |
| * |
| * @see #setPaintTrack(boolean) |
| */ |
| public boolean getPaintTrack() |
| { |
| return paintTrack; |
| } |
| |
| /** |
| * Sets the flag that controls whether or not the track is painted, and |
| * sends a {@link PropertyChangeEvent} (for the "paintTrack" property) to all |
| * registered listeners. |
| * |
| * @param paint Whether the track will be painted. |
| * |
| * @see #getPaintTrack() |
| */ |
| public void setPaintTrack(boolean paint) |
| { |
| if (paintTrack != paint) |
| { |
| paintTrack = paint; |
| firePropertyChange("paintTrack", !paint, paint); |
| } |
| } |
| |
| /** |
| * Returns the flag that controls whether or not labels are painted for the |
| * tick marks along the slider. |
| * |
| * @return Whether labels will be painted. |
| * |
| * @see #setPaintLabels(boolean) |
| */ |
| public boolean getPaintLabels() |
| { |
| return paintLabels; |
| } |
| |
| /** |
| * Sets the flag that controls whether or not labels are painted for the |
| * tick marks along the slider and sends a {@link PropertyChangeEvent} (with |
| * the property name "paintLabels") to all registered listeners. |
| * |
| * @param paint Whether labels will be painted. |
| * |
| * @see #getPaintLabels() |
| */ |
| public void setPaintLabels(boolean paint) |
| { |
| if (paint != paintLabels) |
| { |
| paintLabels = paint; |
| if (paint && majorTickSpacing > 0 && labelTable == null) |
| labelTable = createStandardLabels(majorTickSpacing); |
| firePropertyChange("paintLabels", !paint, paint); |
| } |
| } |
| |
| /** |
| * Returns an implementation-dependent string describing the attributes of |
| * this <code>JSlider</code>. |
| * |
| * @return A string describing the attributes of this <code>JSlider</code> |
| * (never <code>null</code>). |
| */ |
| protected String paramString() |
| { |
| String superParamStr = super.paramString(); |
| StringBuffer sb = new StringBuffer(); |
| sb.append(",isInverted=").append(getInverted()); |
| sb.append(",majorTickSpacing=").append(getMajorTickSpacing()); |
| sb.append(",minorTickSpacing=").append(getMinorTickSpacing()); |
| sb.append(",orientation="); |
| if (orientation == HORIZONTAL) |
| sb.append("HORIZONTAL"); |
| else |
| sb.append("VERTICAL"); |
| sb.append(",paintLabels=").append(getPaintLabels()); |
| sb.append(",paintTicks=").append(getPaintTicks()); |
| sb.append(",paintTrack=").append(getPaintTrack()); |
| sb.append(",snapToTicks=").append(getSnapToTicks()); |
| |
| // the following is output by the reference implementation. We don't |
| // strictly need to replicate this. Perhaps it has some meaning, but |
| // I couldn't determine it yet... |
| sb.append(",snapToValue=true"); |
| |
| return superParamStr + sb.toString(); |
| } |
| |
| /** |
| * Returns the object that provides accessibility features for this |
| * <code>JSlider</code> component. |
| * |
| * @return The accessible context (an instance of {@link AccessibleJSlider}). |
| */ |
| public AccessibleContext getAccessibleContext() |
| { |
| if (accessibleContext == null) |
| accessibleContext = new AccessibleJSlider(); |
| |
| return accessibleContext; |
| } |
| } |