ca.phon.ui.JRangeSlider.java Source code

Java tutorial

Introduction

Here is the source code for ca.phon.ui.JRangeSlider.java

Source

/*
 * Phon - An open source tool for research in phonology.
 * Copyright (C) 2005 - 2015, Gregory Hedlund <ghedlund@mun.ca> and Yvan Rose <yrose@mun.ca>
 * Dept of Linguistics, Memorial University <https://phon.ca>
 * 
 * This program 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 3 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package ca.phon.ui;

import java.text.Format;

import javax.swing.BoundedRangeModel;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import ca.phon.util.MsFormat;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

/**
 * A component that lets the user graphically select a contiguous range of values by
 * sliding knobs withing a bounded interval.  Like the regular swing JSlider,
 * the component can show both major ticks marks and minor tick marks between
 * them.
 * 
 * @beaninfo
 *       attribute: isContainer false
 *      description: A component that supports selecting a range of values from within a range.
 *
 * @version 1.0 2007-04-22
 *
 */
public class JRangeSlider extends JComponent implements SwingConstants {

    private static final long serialVersionUID = -2447438292052903645L;

    /** uiClassID */
    private static final String uiClassID = "RangeSliderUI";

    //   private boolean paintTicks = false;
    //   private boolean paintTrack = true;
    //   private boolean paintLabels = false;
    //   private boolean isInverted = false;

    /** The model */
    private BoundedRangeModel _model;

    /** The number of values between major ticks. */
    protected int majorTickSpacing;

    /** The number of values between minor ticks. */
    protected int minorTickSpacing;

    /** Snap to ticks? */
    protected boolean snapToTicks = false;

    /** Snap to value? */
    protected boolean snapToValue = true;

    /** Paint the sliding value label? */
    protected boolean paintSlidingLabel = false;

    /** Component orientation */
    protected int orientation;

    /** The default change listener for the model. */
    protected ChangeListener changeListener = makeChangeListener();

    /** The formatter */
    protected Format labelFormat;

    /** Keep one <CODE>ChangeEvent</CODE> per instance */
    protected transient ChangeEvent changeEvent = null;

    /** 
     * Default Constructor.
     * 
     * Creates a horizontal slider with range[0-100] and selected
     * range [20-80].
     */
    public JRangeSlider() {
        this(HORIZONTAL, 0, 100, 20, 60);
    }

    /**
     * Creates a slider with the specified orientation with range [0-100]
     * and selected range [20-80].
     */
    public JRangeSlider(int orientation) {
        this(orientation, 0, 100, 20, 60);
    }

    /**
     * Creates a horizontal slider with the specified range 
     * and selected range.
     * 
     * @param min
     * @param max
     * @param start
     * @param length
     */
    public JRangeSlider(int min, int max, int start, int length) {
        this(HORIZONTAL, min, max, start, length);
    }

    /**
     * Creates a slider with the spectified orientation, range, 
     * and selected range.
     * 
     * @param orientation
     * @param min
     * @param max
     * @param start
     * @param length
     */
    public JRangeSlider(int orientation, int min, int max, int start, int length) {
        super();
        checkOrientation(orientation);
        this.orientation = orientation;
        _model = new DefaultBoundedRangeModel(start, length, min, max);
        _model.addChangeListener(changeListener);
        updateUI();
    }

    /**
     * Get the UI object.
     */
    public RangeSliderUI getUI() {
        return (RangeSliderUI) ui;
    }

    /**
     * Set the component UI.
     */
    public void setUI(RangeSliderUI ui) {
        super.setUI(ui);
    }

    /**
     * Update UI
     */
    @Override
    public void updateUI() {
        setUI(new DefaultRangeSliderUI(this));
    }

    /**
     * Get UI classname.
     */
    @Override
    public String getUIClassID() {
        return uiClassID;
    }

    private void checkOrientation(int orientation) {
        if (orientation != HORIZONTAL && orientation != VERTICAL) {
            throw new IllegalArgumentException("Orientation must be either HORIZONTAL or VERTICAL");
        }
    }

    private ChangeListener makeChangeListener() {
        return new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                fireStateChange();
            }

        };
    }

    /**
     * Add a change listener.
     */
    public void addChangeListener(ChangeListener listener) {
        listenerList.add(ChangeListener.class, listener);
    }

    /**
     * Remote a change listener.
     */
    public void removeChangeListener(ChangeListener listener) {
        listenerList.remove(ChangeListener.class, listener);
    }

    /**
     * Get the change listeners.
     */
    public ChangeListener[] getChangeListeners() {
        return listenerList.getListeners(ChangeListener.class);
    }

    /**
     * Fire state change.
     */
    protected void fireStateChange() {
        if (changeEvent == null)
            changeEvent = new ChangeEvent(this);

        for (ChangeListener changeListener : getChangeListeners()) {
            changeListener.stateChanged(changeEvent);
        }
    }

    /**
     * The data model that handles the components four main attributes:
     * min, max, start, length
     * 
     */
    public BoundedRangeModel getModel() {
        return _model;
    }

    /**
     * Set the model.
     */
    public void setModel(BoundedRangeModel model) {
        BoundedRangeModel oldModel = _model;

        if (oldModel != null)
            oldModel.removeChangeListener(changeListener);

        _model = model;

        if (_model != null)
            _model.addChangeListener(changeListener);

        firePropertyChange("model", oldModel, model);
    }

    /**
     * Return the start value
     */
    public int getStart() {
        return getModel().getValue();
    }

    /**
     * Set the start value
     * @param value
     */
    public void setStart(int value) {
        int oldValue = getModel().getValue();
        if (getModel().getValue() == value)
            return;

        getModel().setValue(value);
        firePropertyChange("value", oldValue, value);
    }

    /**
     * Return the length value.
     */
    public int getLength() {
        return getModel().getExtent();
    }

    /**
     * Set the length
     * @param length
     */
    public void setLength(int length) {
        int oldValue = getModel().getExtent();
        if (getModel().getExtent() == length)
            return;

        getModel().setExtent(length);
        firePropertyChange("extent", oldValue, length);
    }

    /**
     * Return the minimum
     */
    public int getMinimum() {
        return getModel().getMinimum();
    }

    /**
     * Set the minimum.
     * 
     * @param min
     */
    public void setMinimum(int min) {
        int oldValue = getModel().getMinimum();
        if (getModel().getMinimum() == min)
            return;

        getModel().setMinimum(min);
        firePropertyChange("minimum", oldValue, min);
    }

    /**
     * Return the maximum.
     */
    public int getMaximum() {
        return getModel().getMaximum();
    }

    /**
     * Set the maximum
     */
    public void setMaximum(int max) {
        int oldValue = getModel().getMaximum();
        if (getModel().getMaximum() == max)
            return;

        getModel().setMaximum(max);
        firePropertyChange("maximum", oldValue, max);
    }

    /**
     * Is one of the knobs being dragged?
     */
    public boolean getValueIsAdjusting() {
        return getModel().getValueIsAdjusting();
    }

    /**
     * Sets the valueIsAdjusting property.
     */
    public void setValueIsAdjusting(boolean adjusting) {
        boolean oldValue = getModel().getValueIsAdjusting();
        if (getModel().getValueIsAdjusting() == adjusting)
            return;
        getModel().setValueIsAdjusting(adjusting);
        firePropertyChange("valueIsAdjusting", oldValue, adjusting);
    }

    /**
     * The component orientation.
     */
    public int getOrientation() {
        return orientation;
    }

    /**
     * Set the component orientaiton.
     */
    public void setOrientation(int orientation) {
        checkOrientation(orientation);

        int oldValue = this.orientation;
        if (oldValue == orientation)
            return;

        this.orientation = orientation;
        firePropertyChange("orientation", oldValue, orientation);
        revalidate();
    }

    public static void main(String[] args) {
        JRangeSlider slider = new JRangeSlider(1000, 10000, 1000, 3000);
        slider.setLabelFormat(new MsFormat());
        slider.setPaintSlidingLabel(true);
        //      slider.setPreferredSize(new Dimension(100, 30));
        //      slider.setFont(new Font("Charis SIL", Font.PLAIN, 10));

        JFrame f = new JFrame("Test Slider");

        FormLayout layout = new FormLayout("3dlu, fill:pref:grow, 3dlu", "3dlu, pref, 3dlu");
        //      f.getContentPane().setLayout(layout);

        CellConstraints cc = new CellConstraints();
        //      f.getContentPane().add(slider, cc.xy(2,2));
        f.add(slider);
        f.pack();
        f.setVisible(true);
    }

    public Format getLabelFormat() {
        return labelFormat;
    }

    public void setLabelFormat(Format labelFormat) {
        Format oldValue = this.labelFormat;
        if (this.labelFormat == labelFormat)
            return;

        this.labelFormat = labelFormat;
        firePropertyChange("labelformat", oldValue, labelFormat);
    }

    public boolean isPaintSlidingLabel() {
        return paintSlidingLabel;
    }

    public void setPaintSlidingLabel(boolean paintSlidingLabel) {
        this.paintSlidingLabel = paintSlidingLabel;
    }
}