package jcgp.gui.settings.parameters; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.control.Control; import javafx.scene.control.TextField; import javafx.scene.input.KeyEvent; import jcgp.backend.resources.parameters.Parameter; import jcgp.backend.resources.parameters.ParameterStatus; import jcgp.gui.settings.SettingsPane; /** * This extension of GUIParameter uses a TextField to display * the value of a DoubleParameter. It cannot be constructed * directly - instead, use GUIParameter.create(). *

* See {@link GUIParameter} for more information. * * @author Eduardo Pedroni */ public class GUIDoubleParameter extends GUIParameter { private TextField textField; /** * This default-visibility constructor is intended for use * by the factory method only. * */ GUIDoubleParameter(Parameter parameter, SettingsPane sp) { super(parameter, sp); } @Override protected Control makeControl() { textField = new TextField(String.valueOf(parameter.get())); textField.setStyle(VALID_PARAMETER_STYLE); textField.setAlignment(Pos.CENTER_RIGHT); return textField; } @Override protected void setControlListeners() { /* filter keypresses and ignore anything that is not a number * and any decimal point beyond the first ones */ textField.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler() { @Override public void handle( KeyEvent t ) { char ch = t.getCharacter().toCharArray()[t.getCharacter().toCharArray().length - 1]; if (!((ch >= '0' && ch <= '9') || (ch == '.' && !textField.getText().contains(".")))) { t.consume(); } } }); /* pass the TextField value back to the parameter whenever it gets * modified, provided it is not empty and the experiment isn't running */ textField.textProperty().addListener(new ChangeListener() { @Override public void changed( ObservableValue observable, String oldValue, String newValue) { if (!newValue.isEmpty() && !settingsPane.isExperimentRunning()) { parameter.set(Double.parseDouble(newValue)); settingsPane.revalidateParameters(); } } }); /* if the TextField loses focus and is empty, set it to the current * value of the parameter */ textField.focusedProperty().addListener(new ChangeListener() { @Override public void changed( ObservableValue observable, Boolean oldValue, Boolean newValue) { if (!newValue && textField.getText().isEmpty()) { textField.setText(String.valueOf(parameter.get())); } } }); } @Override protected void setValidityStyle() { // update the Control's style and tooltip based on the status of the parameter if (parameter.getStatus() == ParameterStatus.INVALID) { textField.setStyle(BASE_TEXT_STYLE + INVALID_PARAMETER_STYLE); textField.setTooltip(tooltip); tooltip.setText(parameter.getStatus().getDetails()); } else if (parameter.getStatus() == ParameterStatus.WARNING || parameter.getStatus() == ParameterStatus.WARNING_RESET) { textField.setStyle(BASE_TEXT_STYLE + WARNING_PARAMETER_STYLE); textField.setTooltip(tooltip); tooltip.setText(parameter.getStatus().getDetails()); } else { textField.setStyle(BASE_TEXT_STYLE + VALID_PARAMETER_STYLE); textField.setTooltip(null); } } @Override public void refreshValue() { textField.setText(String.valueOf((parameter).get())); } }