/* 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;
  }
}
