All Downloads are FREE. Search and download functionalities are using the official Maven repository.

echopointng.Slider Maven / Gradle / Ivy

Go to download

Echo2 bundled with Echo2_Extras, Echo2_FileTransfer and echopointing and various improvements/bugfixes

There is a newer version: 2.0.4
Show newest version
/* 
 * This file is part of the Echo Point Project.  This project is a collection
 * of Components that have extended the Echo Web Application Framework.
 *
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 */
package echopointng;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.EventListener;

import nextapp.echo2.app.Style;
import nextapp.echo2.app.event.ChangeEvent;
import nextapp.echo2.app.event.ChangeListener;
import echopointng.model.BoundedRangeModel;
import echopointng.model.DefaultBoundedRangeModel;
import echopointng.util.ColorKit;

/**
 * Slider is a component the presents a handle that can be
 * dragged to move within a range of values.
 * 

* The BoundedRangeModel is used to contain the range of integer * values that the Slider can move between. *

* Since this is integer based, you can use a valueRatio to generate a double * value from the BoundedRangeModel value, thereby allowing * decimal numbers to be used within a Slider. * */ public class Slider extends AbleComponent { /* * We pass each Change event to the listeners with the the Slider as the * event source. We also update our image reference to reflect the change. */ private class InternalModelListener implements ChangeListener, Serializable { public void stateChanged(ChangeEvent e) { // fire an event to allow the property to be captured directly by // rendering peer Integer newValue = new Integer(getValue()); firePropertyChange(VALUE_CHANGED_PROPERTY, null, newValue); // inform all listeners fireStateChanged(); } } /** * DEFAULT_HORIZONTAL_STYLE contains a default Style for a horizontal Slider */ public static final Style DEFAULT_HORIZONTAL_STYLE; /** * DEFAULT_VERTICAL_STYLE contains a default Style for a vertical Slider */ public static final Style DEFAULT_VERTICAL_STYLE; /** * DEFAULT_STYLE is equal to DEFAULT_HORIZONTAL_STYLE */ public static final Style DEFAULT_STYLE; public static final int ORIENTATION_HORIZONTAL = 0; public static final int ORIENTATION_VERTICAL = 1; public static final String PROPERTY_MODEL = "model"; public static final String PROPERTY_ORIENTATION = "orientation"; public static final String PROPERTY_VALUE_DECIMAL_PLACES = "valueRatio"; public static final String PROPERTY_VALUE_RATIO = "valueRatio"; public static final String PROPERTY_IMMEDIATE_NOTIFICATION = "immediateNotification"; public static final String VALUE_CHANGED_PROPERTY = "value"; static { MutableStyleEx style = new MutableStyleEx(); // // horizontal // style.setProperty(PROPERTY_ORIENTATION, ORIENTATION_HORIZONTAL); style.setProperty(PROPERTY_HEIGHT, new ExtentEx("5px")); style.setProperty(PROPERTY_WIDTH, new ExtentEx("100px")); // made to look like a drop shadow area BorderEx railBorder = new BorderEx(1, ColorKit.clr("#9d9c99"), BorderEx.STYLE_SOLID, 1, ColorKit.clr("#eeefff"), BorderEx.STYLE_SOLID, 1, ColorKit.clr("#9d9c99"), BorderEx.STYLE_SOLID, 1, ColorKit.clr("#eeefff"), BorderEx.STYLE_SOLID); style.setProperty(PROPERTY_BORDER, railBorder); style.setProperty(PROPERTY_BACKGROUND, ColorKit.clr("#f0ede0")); DEFAULT_HORIZONTAL_STYLE = style; DEFAULT_STYLE = DEFAULT_HORIZONTAL_STYLE; // // vertical // style = new MutableStyleEx(DEFAULT_HORIZONTAL_STYLE); style.setProperty(PROPERTY_ORIENTATION, ORIENTATION_VERTICAL); style.setProperty(PROPERTY_WIDTH, new ExtentEx("5px")); style.setProperty(PROPERTY_HEIGHT, new ExtentEx("100px")); DEFAULT_VERTICAL_STYLE = style; } /** * Only one ChangeEvent is needed per instance since the event's only * interesting property is the immutable source, which is the Slider. */ protected transient ChangeEvent changeEvent = null; protected ChangeListener changeListener = null; /** * Constructs a Slider with a * DefaultBoundedRangeModel set to zero. */ public Slider() { this(new DefaultBoundedRangeModel()); } /** * Constructs a Slider with the specified * BoundedRangeModel * * @param model - * the new BoundedRangeModel */ public Slider(BoundedRangeModel model) { setModel(model); } /** * Constructs a Slider with a * DefaultBoundedRangeModel and uses the specified Style. * Typically you might use this constructor like this * *

	 * Slider slider = new Slider(Slider.DEFAULT_VERTICAL_STYLE);
	 * 
* * @param style - * the Style to use */ public Slider(Style style) { this(); setStyle(style); } /** * @see nextapp.echo2.app.Component#processInput(java.lang.String, * java.lang.Object) */ public void processInput(String inputName, Object inputValue) { super.processInput(inputName, inputValue); if (VALUE_CHANGED_PROPERTY.equals(inputName)) { setValue(((Integer) inputValue).intValue()); } } /** * Adds a ChangeListener to the Slider. * * @param l * the ChangeListener to add */ public void addChangeListener(ChangeListener l) { getEventListenerList().addListener(ChangeListener.class, l); } /** * Subclasses that want to handle ChangeEvents differently can override this * to return a subclass of ModelListener or another ChangeListener * implementation. */ protected ChangeListener createChangeListener() { return new InternalModelListener(); } /** * Notify all listeners that have registered interest for notification on * this event type. */ protected void fireStateChanged() { EventListener[] listeners = getEventListenerList().getListeners(ChangeListener.class); for (int index = 0; index < listeners.length; ++index) { if (changeEvent == null) changeEvent = new ChangeEvent(this); ((ChangeListener) listeners[index]).stateChanged(changeEvent); } } /** * Returns the model's maximum value. By default, this is 100. * * @return an int -- the model's maximum */ public int getMaximum() { return getModel().getMaximum(); } /** * Returns the model's minimum value. By default, this is 0. * */ public int getMinimum() { return getModel().getMinimum(); } /** * Returns the data model used by the Slider. * */ public BoundedRangeModel getModel() { return (BoundedRangeModel) getProperty(PROPERTY_MODEL); } /** * Returns Slider.ORIENTATION_VERTICAL or * Slider.ORIENTATION_HORIZONTAL, depending on the * orientation of the Slider. The default orientation is * ORIENTATION_HORIZONTAL. * */ public int getOrientation() { return getProperty(PROPERTY_ORIENTATION, ORIENTATION_HORIZONTAL); } /** * Returns the model's current value. The value is always between the * model's minimum and maximum values, inclusive. By default, the value * equals the minimum. * */ public int getValue() { return getModel().getValue(); } /** * The getDoubleValue() method allows a decimal number to be returned by the * Slider when the backing model only supports integers. The number is the * current getValue() * getValueRatio(), which is then rounded to * getValueDecimalPlaces() * * @return - getValue() * getValueRatio() rounded to getValueDecimalPlaces() */ public double getDoubleValue() { int value = getModel().getValue(); double d = value * getValueRatio(); int powersOfTen = 10 * getValueDecimalPlaces(); if (powersOfTen != 0) { BigDecimal decimal = new BigDecimal(d * powersOfTen); BigDecimal powersOfTenDecimal = new BigDecimal(powersOfTen); BigDecimal result = decimal.divide(powersOfTenDecimal, BigDecimal.ROUND_HALF_DOWN); return result.doubleValue(); } else { return new Double(d).intValue(); } } /** * @return - the value decimal places in use, which is by default 0 */ public int getValueDecimalPlaces() { return getProperty(PROPERTY_VALUE_DECIMAL_PLACES, 0); } /** * @return - the value ratio in use, which is by default 1 */ public double getValueRatio() { return getProperty(PROPERTY_VALUE_RATIO, 1); } /** * Sets the number of decimal places that will be returned in the value of * the getDoubleValue() method and when displayed on the client. * * @param newValue - * the number of decimal places to use */ public void setValueDecimalPlaces(int newValue) { setProperty(PROPERTY_VALUE_DECIMAL_PLACES, newValue); } /** * Sets the ratio that will be multiplied by the current model value when * its is returned by the getDoubleValue() and when displayed on the client. * * @param newValue - * a new ratio to multiply the value by such as 0.01. */ public void setValueRatio(double newValue) { setProperty(PROPERTY_VALUE_DECIMAL_PLACES, newValue); } /** * Removes a ChangeListener from the Slider. * * @param l * the ChangeListener to remove */ public void removeChangeListener(ChangeListener l) { getEventListenerList().removeListener(ChangeListener.class, l); } /** * Sets the model's maximum to n . * * The underlying BoundedRangeModel will handle any mathematical issues * arrising from assigning faulty values. *

* Notifies any listeners if the data changes. * */ public void setMaximum(int n) { getModel().setMaximum(n); } /** * Sets the model's minimum to n . *

* The underlying BoundedRangeModel will handle any mathematical issues * arrising from assigning faulty values. *

* Notifies any listeners if the data changes. * */ public void setMinimum(int n) { getModel().setMinimum(n); } /** * Sets the data model used by the Slider. * * @param newModel - * the new BoundedRangeModel to use * * @throws IllegalArgumentException * is the model is null * */ public void setModel(BoundedRangeModel newModel) { if (newModel == null) { throw new IllegalArgumentException("The model must not be null"); } BoundedRangeModel oldModel = getModel(); setProperty(PROPERTY_MODEL, newModel); if (newModel != oldModel) { if (oldModel != null) { oldModel.removeChangeListener(changeListener); changeListener = null; } if (newModel != null) { changeListener = createChangeListener(); newModel.addChangeListener(changeListener); } newModel.setExtent(0); } } /** * Sets the Slider's orientation to newOrientation , which must be * Slider.ORIENTATION_VERTICAL or * Slider.ORIENTATION_HORIZONTAL. The default orientation is * ORIENTATION_HORIZONTAL. */ public void setOrientation(int newOrientation) { if (newOrientation != ORIENTATION_HORIZONTAL && newOrientation != ORIENTATION_VERTICAL) { throw new IllegalArgumentException("The orientation must be either ORIENTATION_HORIZONTAL or ORIENTATION_VERTICAL"); } setProperty(PROPERTY_ORIENTATION, newOrientation); } /** * Sets the model's value to n . *

* The underlying BoundedRangeModel will handle any mathematical issues * arrising from assigning faulty values. *

* Notifies any listeners if the data changes. * */ public void setValue(int n) { getModel().setValue(n); } /** * @return true if the component will raise a change event immediately once * the the slider value changes. Set this to false if you want it to * delay the notification until another server interaction event * such as a button press. */ public boolean isImmediateNotification() { return getProperty(PROPERTY_IMMEDIATE_NOTIFICATION, false); } /** * Set to true if the component will raise a change event immediately once * the the slider value changes. Set this to false if you want it to delay * the notification until another server interaction event such as a button * press. * * @param newValue - * true if the component will raise a change event immediately * once the the slider value changes. Set this to false if you * want it to delay the notification until another server * interaction event such as a button press. */ public void setImmediateNotification(boolean newValue) { setProperty(PROPERTY_IMMEDIATE_NOTIFICATION, newValue); } /** * @see java.lang.Object#toString() */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("w="); sb.append(getWidth()); sb.append(" h="); sb.append(getHeight()); sb.append(" orient="); sb.append((getOrientation() == ORIENTATION_HORIZONTAL ? "horz" : "vert")); sb.append(" val="); sb.append(getValue()); sb.append(" dblval="); sb.append(getDoubleValue()); return sb.toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy