Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2015-2017 Petr Zelenka .
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sellcom.javafx.scene.control;
import static org.sellcom.javafx.scene.input.KeyEvents.is;
import org.sellcom.core.Contract;
import org.sellcom.core.Strings;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory.DoubleSpinnerValueFactory;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
/**
* {@code Spinner} for {@code Double}s.
*
* @since 1.0
*
* @see Spinner
*/
public final class DoubleSpinner extends Spinner {
private final double defaultValue;
private final DoubleSpinnerValueFactory valueFactory;
/**
* Creates a new spinner.
*
* @since 1.0
*/
public DoubleSpinner() {
this(-Double.MAX_VALUE, Double.MAX_VALUE, 0.0, 1.0);
}
/**
* Creates a new spinner with the given minimum and maximum.
*
* @throws IllegalArgumentException if {@code max} < {@code min}
*
* @since 1.0
*/
public DoubleSpinner(double min, double max) {
this(min, max, 0.0, 1.0);
}
/**
* Creates a new spinner with the given minimum, maximum, and initial value.
*
* @throws IllegalArgumentException if {@code max} < {@code min}
* @throws IllegalArgumentException if {@code initialValue} < {@code min}
* @throws IllegalArgumentException if {@code initialValue} > {@code max}
*
* @since 1.0
*/
public DoubleSpinner(double min, double max, double initialValue) {
this(min, max, initialValue, 1.0);
}
/**
* Creates a new spinner with the given minimum, maximum, initial value, and step size.
*
* @throws IllegalArgumentException if {@code max} < {@code min}
* @throws IllegalArgumentException if {@code initialValue} < {@code min}
* @throws IllegalArgumentException if {@code initialValue} > {@code max}
* @throws IllegalArgumentException if {@code stepSize} ≤ 0
*
* @since 1.0
*/
public DoubleSpinner(double min, double max, double initialValue, double stepSize) {
Contract.checkArgument(max >= min, "Maximum must be greater or equal to minimum: {0} < {1}", max, min);
Contract.checkArgument(initialValue >= min, "Initial value must be greater or equal to minimum: {0} < {1}", initialValue, min);
Contract.checkArgument(initialValue <= max, "Initial value must be less or equal to maximum: {0} > {1}", initialValue, max);
Contract.checkArgument(stepSize > 0, "Step size must be positive: {0}", stepSize);
defaultValue = initialValue;
valueFactory = new DoubleSpinnerValueFactory(min, max, initialValue, stepSize);
getEditor().focusedProperty().addListener(this::selectAllOnFocusGained);
getEditor().setOnKeyPressed(this::handleKeyPressed);
setEditable(true);
setValueFactory(valueFactory);
}
/**
* Returns the maximum allowable value of this spinner.
*
* @since 1.0
*/
public double getMax() {
return valueFactory.getMax();
}
/**
* Returns the minimum allowable value of this spinner.
*
* @since 1.0
*/
public double getMin() {
return valueFactory.getMin();
}
/**
* Returns the step size of this spinner.
*
* @since 1.0
*/
public double getStepSize() {
return valueFactory.getAmountToStepBy();
}
/**
* Checks whether the value of this spinner wraps around on reaching its allowable minimum or maximum value.
*
* @since 1.0
*/
public boolean isWrapAround() {
return valueFactory.isWrapAround();
}
/**
* Returns the property containing the maximum allowable value of this spinner.
*
* @since 1.0
*/
public DoubleProperty maxProperty() {
return valueFactory.maxProperty();
}
/**
* Returns the property containing the minimum allowable value of this spinner.
*
* @since 1.0
*/
public DoubleProperty minProperty() {
return valueFactory.minProperty();
}
/**
* Sets the maximum allowable value of this spinner.
*
* @throws IllegalArgumentException if {@code max} < {@code min}
*
* @since 1.0
*/
public void setMax(double max) {
Contract.checkArgument(max >= getMin(), "Maximum must be greater or equal to minimum: {0} < {1}", max, getMin());
valueFactory.setMax(max);
}
/**
* Sets the minimum allowable value of this spinner.
*
* @throws IllegalArgumentException if {@code min} > {@code max}
*
* @since 1.0
*/
public void setMin(double min) {
Contract.checkArgument(min <= getMax(), "Minimum must be less or equal to maximum: {0} > {1}", min, getMax());
valueFactory.setMin(min);
}
/**
* Sets the step size of this spinner.
*
* @throws IllegalArgumentException if {@code stepSize} ≤ 0
*
* @since 1.0
*/
public void setStepSize(double stepSize) {
Contract.checkArgument(stepSize > 0, "Step size must be positive: {0}", stepSize);
valueFactory.setAmountToStepBy(stepSize);
}
/**
* Sets the value of this spinner.
*
* @throws IllegalArgumentException if {@code value} < {@code min}
* @throws IllegalArgumentException if {@code value} > {@code max}
*
* @since 1.0
*/
public void setValue(double value) {
Contract.checkArgument(value >= getMin(), "Value must be greater or equal to minimum: {0} < {1}", value, getMin());
Contract.checkArgument(value <= getMax(), "Value must be less or equal to maximum: {0} > {1}", value, getMax());
valueFactory.setValue(value);
}
/**
* Sets whether the value of this spinner wraps around on reaching its allowable minimum or maximum value.
*
* @since 1.0
*/
public void setWrapAround(boolean wrapAround) {
valueFactory.setWrapAround(wrapAround);
}
/**
* Returns the property containing the step size of this spinner.
*
* @since 1.0
*/
public DoubleProperty stepSizeProperty() {
return valueFactory.amountToStepByProperty();
}
/**
* Returns the property containing whether the value of this spinner wraps around on reaching its allowable minimum or maximum value.
*
* @since 1.0
*/
public BooleanProperty wrapAroundProperty() {
return valueFactory.wrapAroundProperty();
}
/**
* Returns the writable property containing the value of this spinner.
*
* @since 1.0
*
* @see #valueProperty()
*/
public final ObjectProperty writableValueProperty() {
return valueFactory.valueProperty();
}
private void handleKeyPressed(KeyEvent event) {
if (is(event, KeyCode.DOWN)) {
event.consume();
valueFactory.decrement(1);
return;
}
if (is(event, KeyCode.UP)) {
event.consume();
valueFactory.increment(1);
return;
}
TextField editor = getEditor();
if (Strings.isNullOrEmpty(editor.getText())) {
editor.setText(valueFactory.getConverter().toString(defaultValue));
editor.selectAll();
}
}
private void selectAllOnFocusGained(ObservableValue extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue) {
Platform.runLater(() -> getEditor().selectAll());
}
}
}