diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/javax/swing/JSlider.java | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/javax/swing/JSlider.java')
-rw-r--r-- | libjava/classpath/javax/swing/JSlider.java | 1144 |
1 files changed, 1144 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/JSlider.java b/libjava/classpath/javax/swing/JSlider.java new file mode 100644 index 000000000..a6f51138d --- /dev/null +++ b/libjava/classpath/javax/swing/JSlider.java @@ -0,0 +1,1144 @@ +/* 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 gnu.java.lang.CPStringBuilder; + +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; +import javax.swing.plaf.UIResource; + +/** + * 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 +{ + + /** + * A little testing shows that the reference implementation creates + * labels from a class named LabelUIResource. + */ + private class LabelUIResource + extends JLabel + implements UIResource + { + LabelUIResource(String text, int align) + { + super(text, align); + setName("Slider.label"); + } + } + + 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() + { + updateLabelUIs(); + 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); + revalidate(); + } + } + + /** + * 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; + updateLabelUIs(); + firePropertyChange("labelTable", oldTable, labelTable); + revalidate(); + repaint(); + } + } + + /** + * 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) + { + for (Enumeration list = labelTable.elements(); list.hasMoreElements();) + { + Object o = list.nextElement(); + if (o instanceof JComponent) + { + JComponent jc = (JComponent) o; + jc.updateUI(); + jc.setSize(jc.getPreferredSize()); + } + } + } + } + + /** + * 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(); + int max = getMaximum(); + for (int i = start; i <= max; i += increment) + { + LabelUIResource label = new LabelUIResource(String.valueOf(i), + JLabel.CENTER); + 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); + repaint(); + } + } + + /** + * 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; + if (labelTable == null && majorTickSpacing > 0 && getPaintLabels()) + setLabelTable(createStandardLabels(majorTickSpacing)); + firePropertyChange("majorTickSpacing", oldSpacing, majorTickSpacing); + if (getPaintTicks()) + repaint(); + } + } + + /** + * 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); + if (getPaintTicks()) + repaint(); + } + } + + /** + * 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); + revalidate(); + repaint(); + } + } + + /** + * 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); + repaint(); + } + } + + /** + * 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) + setLabelTable(createStandardLabels(majorTickSpacing)); + firePropertyChange("paintLabels", !paint, paint); + revalidate(); + repaint(); + } + } + + /** + * 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(); + CPStringBuilder sb = new CPStringBuilder(); + 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; + } +} |