/* * Copyright (c) 2002-2015, JIDE Software Inc. 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. */ package jidefx.scene.control.field; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.scene.control.Slider; import javafx.scene.layout.VBox; import javafx.util.Callback; import javafx.util.StringConverter; import jidefx.scene.control.field.popup.PopupContent; import jidefx.scene.control.field.verifier.IntegerDigitsPatternVerifier; import java.text.NumberFormat; /** * A {@code PopupField} for Integers. It allows you to specify the min and max value. The slider is used as the * popup to choose an integer value. */ public class IntegerField extends PopupField<Integer> { private IntegerProperty _maxProperty; private IntegerProperty _minProperty; public IntegerField() { this(0, 100, 0); } public IntegerField(int min, int max) { this(min, max, min); } public IntegerField(int min, int max, int value) { setMin(min); setMax(max); setValue(value); } private static final String STYLE_CLASS_DEFAULT = "integer-field"; //NON-NLS @Override protected void initializeStyle() { super.initializeStyle(); getStyleClass().addAll(STYLE_CLASS_DEFAULT); } private void initializePatternVerifiers(final int min, final int max) { getPatternVerifiers().put("n", new IntegerDigitsPatternVerifier<Integer>(min, max) { //NON-NLS @Override public Number toTargetValue(Integer fieldValue) { return fieldValue; } @Override public Integer fromTargetValue(Integer previousFieldValue, Number targetValue) { return targetValue.intValue(); } }); } public IntegerProperty maxProperty() { if (_maxProperty == null) { _maxProperty = new SimpleIntegerProperty(this, "max") { //NON-NLS @Override protected void invalidated() { super.invalidated(); initializePatternVerifiers(getMin(), get()); } }; } return _maxProperty; } public int getMax() { return maxProperty().get(); } public void setMax(int maxValue) { maxProperty().set(maxValue); } public IntegerProperty minProperty() { if (_minProperty == null) { _minProperty = new SimpleIntegerProperty(this, "min") { //NON-NLS @Override protected void invalidated() { super.invalidated(); initializePatternVerifiers(get(), getMax()); } }; } return _minProperty; } public int getMin() { return minProperty().get(); } public void setMin(int min) { minProperty().set(min); } @Override protected void initializePattern() { super.initializePattern(); NumberFormat format = NumberFormat.getIntegerInstance(); format.setGroupingUsed(false); setStringConverter(new StringConverter<Integer>() { @Override public String toString(Integer object) { return object != null ? format.format(object) : null; } @Override public Integer fromString(String string) { try { return Integer.parseInt(string); } catch (NumberFormatException e) { return null; } } }); initializePatternVerifiers(getMin(), getMax()); setPattern("n"); //NON-NLS } @Override protected void initializeTextField() { super.initializeTextField(); setPopupContentFactory(new Callback<Integer, PopupContent<Integer>>() { @Override public PopupContent<Integer> call(Integer param) { return new IntegerSliderPopupContent(getValue()); } }); } public class IntegerSliderPopupContent extends VBox implements PopupContent<Integer> { private static final String STYLE_CLASS_DEFAULT = "popup-content"; //NON-NLS private final Slider _slider; private ObjectProperty<Integer> _value; public IntegerSliderPopupContent(int value) { getStylesheets().add(PopupContent.class.getResource("PopupContent.css").toExternalForm()); //NON-NLS getStyleClass().add(STYLE_CLASS_DEFAULT); _slider = new Slider(0, 100, value); _slider.maxProperty().bind(maxProperty()); _slider.minProperty().bind(minProperty()); getChildren().add(_slider); _value = new SimpleObjectProperty<>(); _slider.valueProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { _value.set(newValue.intValue()); } }); } @Override public ObservableValue<Integer> valueProperty() { return _value; } @Override public Integer getValue() { return (int) _slider.getValue(); } @Override public void setValue(Integer value) { _slider.setValue(value); } } }