1520 lines · 50.4 KB · Java
RawDownload
/* * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing; import javax.swing.event.*;import javax.swing.plaf.*;import javax.accessibility.*; import java.io.Serializable;import java.io.ObjectOutputStream;import java.io.IOException; import java.awt.*;import java.util.*;import java.beans.*;  /** * A component that lets the user graphically select a value by sliding * a knob within a bounded interval. The knob is always positioned * at the points that match integer values within the specified interval. * <p> * The slider can show both * major tick marks, and minor tick marks between the major ones.  The number of * values between the tick marks is controlled with * <code>setMajorTickSpacing</code> and <code>setMinorTickSpacing</code>. * Painting of tick marks is controlled by {@code setPaintTicks}. * <p> * Sliders can also print text labels at regular intervals (or at * arbitrary locations) along the slider track.  Painting of labels is * controlled by {@code setLabelTable} and {@code setPaintLabels}. * <p> * For further information and examples see * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/slider.html">How to Use Sliders</a>, * a section in <em>The Java Tutorial.</em> * <p> * <strong>Warning:</strong> Swing is not thread safe. For more * information see <a * href="package-summary.html#threading">Swing's Threading * Policy</a>. * <p> * <strong>Warning:</strong> * Serialized objects of this class will not be compatible with * future Swing releases. The current serialization support is * appropriate for short term storage or RMI between applications running * the same version of Swing.  As of 1.4, support for long term storage * of all JavaBeans<sup><font size="-2">TM</font></sup> * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. * * @beaninfo *      attribute: isContainer false *    description: A component that supports selecting a integer value from a range. * * @author David Kloba */public class JSlider extends JComponent implements SwingConstants, Accessible {    /**     * @see #getUIClassID     * @see #readObject     */    private static final String uiClassID = "SliderUI";     private boolean paintTicks = false;    private boolean paintTrack = true;    private boolean paintLabels = false;    private boolean isInverted = false;     /**     * The data model that handles the numeric maximum value,     * minimum value, and current-position value for the slider.     */    protected BoundedRangeModel sliderModel;     /**     * The number of values between the major tick marks -- the     * larger marks that break up the minor tick marks.     */    protected int majorTickSpacing;     /**     * The number of values between the minor tick marks -- the     * smaller marks that occur between the major tick marks.     * @see #setMinorTickSpacing     */    protected int minorTickSpacing;     /**     * If true, the knob (and the data value it represents)     * resolve to the closest tick mark next to where the user     * positioned the knob.  The default is false.     * @see #setSnapToTicks     */    protected boolean snapToTicks = false;     /**     * If true, the knob (and the data value it represents)     * resolve to the closest slider value next to where the user     * positioned the knob.     */    boolean snapToValue = true;     /**     * Whether the slider is horizontal or vertical     * The default is horizontal.     *     * @see #setOrientation     */    protected int orientation;      /**     * {@code Dictionary} of what labels to draw at which values     */    private Dictionary labelTable;      /**     * The changeListener (no suffix) is the listener we add to the     * slider's model.  This listener is initialized to the     * {@code ChangeListener} returned from {@code createChangeListener},     * which by default just forwards events     * to {@code ChangeListener}s (if any) added directly to the slider.     *     * @see #addChangeListener     * @see #createChangeListener     */    protected ChangeListener changeListener = createChangeListener();      /**     * Only one <code>ChangeEvent</code> is needed per slider instance since the     * event's only (read-only) state is the source property.  The source     * of events generated here is always "this". The event is lazily     * created the first time that an event notification is fired.     *     * @see #fireStateChanged     */    protected transient ChangeEvent changeEvent = null;      private void checkOrientation(int orientation) {        switch (orientation) {        case VERTICAL:        case HORIZONTAL:            break;        default:            throw new IllegalArgumentException("orientation must be one of: VERTICAL, HORIZONTAL");        }    }      /**     * Creates a horizontal slider with the range 0 to 100 and     * an initial value of 50.     */    public JSlider() {        this(HORIZONTAL, 0, 100, 50);    }      /**     * Creates a slider using the specified orientation with the     * range {@code 0} to {@code 100} and an initial value of {@code 50}.     * The orientation can be     * either <code>SwingConstants.VERTICAL</code> or     * <code>SwingConstants.HORIZONTAL</code>.     *     * @param  orientation  the orientation of the slider     * @throws IllegalArgumentException if orientation is not one of {@code VERTICAL}, {@code HORIZONTAL}     * @see #setOrientation     */    public JSlider(int orientation) {        this(orientation, 0, 100, 50);    }      /**     * Creates a horizontal slider using the specified min and max     * with an initial value equal to the average of the min plus max.     * <p>     * The <code>BoundedRangeModel</code> that holds the slider's data     * handles any issues that may arise from improperly setting the     * minimum and maximum values on the slider.  See the     * {@code BoundedRangeModel} documentation for details.     *     * @param min  the minimum value of the slider     * @param max  the maximum value of the slider     *     * @see BoundedRangeModel     * @see #setMinimum     * @see #setMaximum     */    public JSlider(int min, int max) {        this(HORIZONTAL, min, max, (min + max) / 2);    }      /**     * Creates a horizontal slider using the specified min, max and value.     * <p>     * The <code>BoundedRangeModel</code> that holds the slider's data     * handles any issues that may arise from improperly setting the     * minimum, initial, and maximum values on the slider.  See the     * {@code BoundedRangeModel} documentation for details.     *     * @param min  the minimum value of the slider     * @param max  the maximum value of the slider     * @param value  the initial value of the slider     *     * @see BoundedRangeModel     * @see #setMinimum     * @see #setMaximum     * @see #setValue     */    public JSlider(int min, int max, int value) {        this(HORIZONTAL, min, max, value);    }      /**     * Creates a slider with the specified orientation and the     * specified minimum, maximum, and initial values.     * The orientation can be     * either <code>SwingConstants.VERTICAL</code> or     * <code>SwingConstants.HORIZONTAL</code>.     * <p>     * The <code>BoundedRangeModel</code> that holds the slider's data     * handles any issues that may arise from improperly setting the     * minimum, initial, and maximum values on the slider.  See the     * {@code BoundedRangeModel} documentation for details.     *     * @param orientation  the orientation of the slider     * @param min  the minimum value of the slider     * @param max  the maximum value of the slider     * @param value  the initial value of the slider     *     * @throws IllegalArgumentException if orientation is not one of {@code VERTICAL}, {@code HORIZONTAL}     *     * @see BoundedRangeModel     * @see #setOrientation     * @see #setMinimum     * @see #setMaximum     * @see #setValue     */    public JSlider(int orientation, int min, int max, int value)    {        checkOrientation(orientation);        this.orientation = orientation;        setModel(new DefaultBoundedRangeModel(value, 0, min, max));        updateUI();    }      /**     * Creates a horizontal slider using the specified     * BoundedRangeModel.     */    public JSlider(BoundedRangeModel brm)    {        this.orientation = JSlider.HORIZONTAL;        setModel(brm);        updateUI();    }      /**     * Gets the UI object which implements the L&F for this component.     *     * @return the SliderUI object that implements the Slider L&F     */    public SliderUI getUI() {        return(SliderUI)ui;    }      /**     * Sets the UI object which implements the L&F for this component.     *     * @param ui the SliderUI L&F object     * @see UIDefaults#getUI     * @beaninfo     *        bound: true     *       hidden: true     *    attribute: visualUpdate true     *  description: The UI object that implements the slider's LookAndFeel.     */    public void setUI(SliderUI ui) {        super.setUI(ui);    }      /**     * Resets the UI property to a value from the current look and feel.     *     * @see JComponent#updateUI     */    public void updateUI() {        setUI((SliderUI)UIManager.getUI(this));        // The labels preferred size may be derived from the font        // of the slider, so we must update the UI of the slider first, then        // that of labels.  This way when setSize is called the right        // font is used.        updateLabelUIs();    }      /**     * Returns the name of the L&F class that renders this component.     *     * @return "SliderUI"     * @see JComponent#getUIClassID     * @see UIDefaults#getUI     */    public String getUIClassID() {        return uiClassID;    }      /**     * We pass Change events along to the listeners with the     * the slider (instead of the model itself) as the event source.     */    private class ModelListener implements ChangeListener, Serializable {        public void stateChanged(ChangeEvent e) {            fireStateChanged();        }    }      /**     * Subclasses that want to handle {@code ChangeEvent}s     * from the model differently     * can override this to return     * an instance of a custom <code>ChangeListener</code> implementation.     * The default {@code ChangeListener} simply calls the     * {@code fireStateChanged} method to forward {@code ChangeEvent}s     * to the {@code ChangeListener}s that have been added directly to the     * slider.     * @see #changeListener     * @see #fireStateChanged     * @see javax.swing.event.ChangeListener     * @see javax.swing.BoundedRangeModel     */    protected ChangeListener createChangeListener() {        return new ModelListener();    }      /**     * Adds a ChangeListener to the slider.     *     * @param l the ChangeListener to add     * @see #fireStateChanged     * @see #removeChangeListener     */    public void addChangeListener(ChangeListener l) {        listenerList.add(ChangeListener.class, l);    }      /**     * Removes a ChangeListener from the slider.     *     * @param l the ChangeListener to remove     * @see #fireStateChanged     * @see #addChangeListener      */    public void removeChangeListener(ChangeListener l) {        listenerList.remove(ChangeListener.class, l);    }      /**     * Returns an array of all the <code>ChangeListener</code>s added     * to this JSlider with addChangeListener().     *     * @return all of the <code>ChangeListener</code>s added or an empty     *         array if no listeners have been added     * @since 1.4     */    public ChangeListener[] getChangeListeners() {        return listenerList.getListeners(ChangeListener.class);    }      /**     * Send a {@code ChangeEvent}, whose source is this {@code JSlider}, to     * all {@code ChangeListener}s that have registered interest in     * {@code ChangeEvent}s.     * This method is called each time a {@code ChangeEvent} is received from     * the model.     * <p>     * The event instance is created if necessary, and stored in     * {@code changeEvent}.     *     * @see #addChangeListener     * @see EventListenerList     */    protected void fireStateChanged() {        Object[] listeners = listenerList.getListenerList();        for (int i = listeners.length - 2; i >= 0; i -= 2) {            if (listeners[i]==ChangeListener.class) {                if (changeEvent == null) {                    changeEvent = new ChangeEvent(this);                }                ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);            }        }    }      /**     * Returns the {@code BoundedRangeModel} that handles the slider's three     * fundamental properties: minimum, maximum, value.     *     * @return the data model for this component     * @see #setModel     * @see    BoundedRangeModel     */    public BoundedRangeModel getModel() {        return sliderModel;    }      /**     * Sets the {@code BoundedRangeModel} that handles the slider's three     * fundamental properties: minimum, maximum, value.     *<p>     * Attempts to pass a {@code null} model to this method result in     * undefined behavior, and, most likely, exceptions.     *     * @param  newModel the new, {@code non-null} <code>BoundedRangeModel</code> to use     *     * @see #getModel     * @see    BoundedRangeModel     * @beaninfo     *       bound: true     * description: The sliders BoundedRangeModel.     */    public void setModel(BoundedRangeModel newModel)    {        BoundedRangeModel oldModel = getModel();         if (oldModel != null) {            oldModel.removeChangeListener(changeListener);        }         sliderModel = newModel;         if (newModel != null) {            newModel.addChangeListener(changeListener);        }         if (accessibleContext != null) {            accessibleContext.firePropertyChange(                                                AccessibleContext.ACCESSIBLE_VALUE_PROPERTY,                                                (oldModel == null                                                 ? null : Integer.valueOf(oldModel.getValue())),                                                (newModel == null                                                 ? null : Integer.valueOf(newModel.getValue())));        }         firePropertyChange("model", oldModel, sliderModel);    }      /**     * Returns the slider's current value     * from the {@code BoundedRangeModel}.     *     * @return  the current value of the slider     * @see     #setValue     * @see     BoundedRangeModel#getValue     */

Lines 1–500 of 1520.