From 0dbf126fc524bc029d9f5803d849b7c8f43fe389 Mon Sep 17 00:00:00 2001 From: Eduardo Pedroni Date: Thu, 3 Apr 2014 15:29:24 +0100 Subject: Visual feedback for parameters implemented. --- .../settings/parameters/GUIBooleanParameter.java | 63 ++++++++++----- .../settings/parameters/GUIDoubleParameter.java | 89 +++++++++++++++++----- .../settings/parameters/GUIIntegerParameter.java | 84 ++++++++++++++++---- src/jcgp/gui/settings/parameters/GUIParameter.java | 21 ++--- 4 files changed, 196 insertions(+), 61 deletions(-) (limited to 'src/jcgp/gui/settings/parameters') diff --git a/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java b/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java index 8acd6dd..da564f7 100644 --- a/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java @@ -1,46 +1,71 @@ package jcgp.gui.settings.parameters; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; import javafx.scene.control.CheckBox; import jcgp.backend.parameters.BooleanParameter; +import jcgp.backend.parameters.ParameterStatus; +import jcgp.gui.GUI; public class GUIBooleanParameter extends GUIParameter { - GUIBooleanParameter(BooleanParameter parameter) { + private boolean originalValue; + + GUIBooleanParameter(final BooleanParameter parameter) { super(); this.parameter = parameter; - value = new CheckBox(parameter.getName()); - ((CheckBox) value).setSelected(parameter.get()); + originalValue = parameter.get(); + + valueControl = new CheckBox(parameter.getName()); + ((CheckBox) valueControl).setSelected(parameter.get()); - value.setDisable(parameter.isMonitor()); + valueControl.setDisable(parameter.isMonitor()); if (parameter.isMonitor()) { makeLightBinding(); - System.out.println("light binding made for " + name); + } else { + ((CheckBox) valueControl).selectedProperty().addListener(new ChangeListener() { + @Override + public void changed( + ObservableValue observable, + Boolean oldValue, Boolean newValue) { + parameter.set(newValue); + if (parameter.getStatus() == ParameterStatus.INVALID) { + valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE); + valueControl.setTooltip(tooltip); + tooltip.setText(parameter.getStatus().getDetails()); + } else if (parameter.getStatus() == ParameterStatus.WARNING) { + valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE); + valueControl.setTooltip(tooltip); + tooltip.setText(parameter.getStatus().getDetails()); + } else { + valueControl.setStyle(GUI.VALID_PARAMETER_STYLE); + valueControl.setTooltip(null); + } + } + }); } - getChildren().add(value); + getChildren().add(valueControl); } @Override public void refreshValue() { - if (!((CheckBox) value).selectedProperty().isBound()) { - ((CheckBox) value).setSelected(((BooleanParameter) parameter).get()); + if (!((CheckBox) valueControl).selectedProperty().isBound()) { + ((CheckBox) valueControl).setSelected(((BooleanParameter) parameter).get()); } - } - + @Override - public boolean applyChange() { - if (((CheckBox) value).isSelected() != ((BooleanParameter) parameter).get() && (!parameter.isMonitor())) { - // apply value - ((BooleanParameter) parameter).set(((CheckBox) value).isSelected()); - if (parameter.isCritical()) { - return true; - } - } - return false; + public boolean requiresReset() { + return parameter.isCritical() && ((BooleanParameter) parameter).get() != originalValue; + } + + @Override + public void applyValue() { + originalValue = ((BooleanParameter) parameter).get(); } } diff --git a/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java b/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java index 4b74c6e..a1b4526 100644 --- a/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java @@ -1,51 +1,104 @@ 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.TextField; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.Priority; import javafx.scene.text.Text; import jcgp.backend.parameters.DoubleParameter; +import jcgp.backend.parameters.ParameterStatus; import jcgp.gui.GUI; public class GUIDoubleParameter extends GUIParameter { - GUIDoubleParameter(DoubleParameter parameter) { + private double originalValue; + + GUIDoubleParameter(final DoubleParameter parameter) { super(); this.parameter = parameter; + originalValue = parameter.get(); + name = new Text(parameter.getName()); - value = new TextField(String.valueOf(parameter.get())); + valueControl = new TextField(String.valueOf(parameter.get())); + valueControl.setStyle(GUI.VALID_PARAMETER_STYLE); - ((TextField) value).setAlignment(Pos.CENTER_RIGHT); + ((TextField) valueControl).setAlignment(Pos.CENTER_RIGHT); - setHgrow(value, Priority.ALWAYS); + setHgrow(valueControl, Priority.ALWAYS); name.setWrappingWidth(GUI.WRAP_WIDTH); - ((TextField) value).setEditable(!parameter.isMonitor()); + ((TextField) valueControl).setEditable(!parameter.isMonitor()); + // bind if monitor, else set changelistener if (parameter.isMonitor()) { makeLightBinding(); + } else { + valueControl.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler() { + public void handle( KeyEvent t ) { + char ch = t.getCharacter().toCharArray()[t.getCharacter().toCharArray().length - 1]; + if (!((ch >= '0' && ch <= '9') || (ch == '.' && !((TextField) valueControl).getText().contains(".")))) { + t.consume(); + } + } + }); + ((TextField) valueControl).textProperty().addListener(new ChangeListener() { + @Override + public void changed( + ObservableValue observable, + String oldValue, String newValue) { + if (!newValue.isEmpty()) { + parameter.set(Double.parseDouble(newValue)); + if (parameter.getStatus() == ParameterStatus.INVALID) { + valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE); + valueControl.setTooltip(tooltip); + tooltip.setText(parameter.getStatus().getDetails()); + } else if (parameter.getStatus() == ParameterStatus.WARNING) { + valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE); + valueControl.setTooltip(tooltip); + tooltip.setText(parameter.getStatus().getDetails()); + } else { + valueControl.setStyle(GUI.VALID_PARAMETER_STYLE); + valueControl.setTooltip(null); + } + } + + } + }); + valueControl.focusedProperty().addListener(new ChangeListener() { + @Override + public void changed( + ObservableValue observable, + Boolean oldValue, Boolean newValue) { + if (!newValue && ((TextField) valueControl).getText().isEmpty()) { + ((TextField) valueControl).setText(String.valueOf(parameter.get())); + } + } + }); } - getChildren().addAll(name, value); + + getChildren().addAll(name, valueControl); } @Override public void refreshValue() { - ((TextField) value).setText(String.valueOf(((DoubleParameter) parameter).get())); + ((TextField) valueControl).setText(String.valueOf(((DoubleParameter) parameter).get())); } - + @Override - public boolean applyChange() { - if (Double.valueOf(((TextField) value).getText()) != ((DoubleParameter) parameter).get() && (!parameter.isMonitor())) { - // apply value - ((DoubleParameter) parameter).set(Double.valueOf(((TextField) value).getText())); - if (parameter.isCritical()) { - return true; - } - } - return false; - } + public boolean requiresReset() { + return parameter.isCritical() && ((DoubleParameter) parameter).get() != originalValue; + } + + @Override + public void applyValue() { + originalValue = ((DoubleParameter) parameter).get(); + } + } diff --git a/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java b/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java index 70b78a6..bf1a61e 100644 --- a/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java @@ -1,49 +1,103 @@ 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.TextField; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.Priority; import javafx.scene.text.Text; import jcgp.backend.parameters.IntegerParameter; +import jcgp.backend.parameters.ParameterStatus; import jcgp.gui.GUI; public class GUIIntegerParameter extends GUIParameter { - GUIIntegerParameter(IntegerParameter parameter) { + private int originalValue; + + GUIIntegerParameter(final IntegerParameter parameter) { super(); this.parameter = parameter; + originalValue = parameter.get(); + name = new Text(parameter.getName()); - value = new TextField(String.valueOf(parameter.get())); + valueControl = new TextField(String.valueOf(parameter.get())); + valueControl.setStyle(GUI.VALID_PARAMETER_STYLE); - ((TextField) value).setAlignment(Pos.CENTER_RIGHT); + ((TextField) valueControl).setAlignment(Pos.CENTER_RIGHT); - setHgrow(value, Priority.ALWAYS); + setHgrow(valueControl, Priority.ALWAYS); name.setWrappingWidth(GUI.WRAP_WIDTH); - ((TextField) value).setEditable(!parameter.isMonitor()); - + ((TextField) valueControl).setEditable(!parameter.isMonitor()); + + // bind if monitor, else set listeners if (parameter.isMonitor()) { makeLightBinding(); + } else { + valueControl.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler() { + public void handle( KeyEvent t ) { + char ch = t.getCharacter().toCharArray()[t.getCharacter().toCharArray().length - 1]; + if (!(ch >= '0' && ch <= '9')) { + t.consume(); + } + } + }); + ((TextField) valueControl).textProperty().addListener(new ChangeListener() { + @Override + public void changed( + ObservableValue observable, + String oldValue, String newValue) { + if (!newValue.isEmpty()) { + parameter.set(Integer.parseInt(newValue)); + if (parameter.getStatus() == ParameterStatus.INVALID) { + valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE); + valueControl.setTooltip(tooltip); + tooltip.setText(parameter.getStatus().getDetails()); + } else if (parameter.getStatus() == ParameterStatus.WARNING) { + valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE); + valueControl.setTooltip(tooltip); + tooltip.setText(parameter.getStatus().getDetails()); + } else { + valueControl.setStyle(GUI.VALID_PARAMETER_STYLE); + valueControl.setTooltip(null); + } + } + + } + }); + valueControl.focusedProperty().addListener(new ChangeListener() { + @Override + public void changed( + ObservableValue observable, + Boolean oldValue, Boolean newValue) { + if (!newValue && ((TextField) valueControl).getText().isEmpty()) { + ((TextField) valueControl).setText(String.valueOf(parameter.get())); + } + } + }); } - getChildren().addAll(name, value); + getChildren().addAll(name, valueControl); } @Override public void refreshValue() { - ((TextField) value).setText(String.valueOf(((IntegerParameter) parameter).get())); + ((TextField) valueControl).setText(String.valueOf(((IntegerParameter) parameter).get())); } @Override - public boolean applyChange() { - if (Integer.valueOf(((TextField) value).getText()) != ((IntegerParameter) parameter).get() && (!parameter.isMonitor())) { - // apply value - ((IntegerParameter) parameter).set(Integer.valueOf(((TextField) value).getText())); - return parameter.isCritical(); - } - return false; + public boolean requiresReset() { + return parameter.isCritical() && ((IntegerParameter) parameter).get() != originalValue; + } + + @Override + public void applyValue() { + originalValue = ((IntegerParameter) parameter).get(); } + } diff --git a/src/jcgp/gui/settings/parameters/GUIParameter.java b/src/jcgp/gui/settings/parameters/GUIParameter.java index a783d71..9d6f07a 100644 --- a/src/jcgp/gui/settings/parameters/GUIParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIParameter.java @@ -7,6 +7,7 @@ import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.geometry.Pos; import javafx.scene.control.Control; +import javafx.scene.control.Tooltip; import javafx.scene.layout.HBox; import javafx.scene.text.Text; import jcgp.backend.parameters.BooleanParameter; @@ -18,13 +19,19 @@ public abstract class GUIParameter extends HBox { protected Parameter parameter; protected Text name; - protected Control value; + protected Control valueControl; + + protected Tooltip tooltip; protected AtomicBoolean updateCheck = new AtomicBoolean(true); protected GUIParameter() { setAlignment(Pos.CENTER_LEFT); setSpacing(5); + + tooltip = new Tooltip(); + tooltip.setStyle("-fx-background-color: white; -fx-border-color: black; .page-corner {-fx-background-color: transparent;}"); + tooltip.setSkin(null); } protected final void makeLightBinding() { @@ -48,6 +55,10 @@ public abstract class GUIParameter extends HBox { public abstract void refreshValue(); + public abstract boolean requiresReset(); + + public abstract void applyValue(); + public static GUIParameter create(Parameter parameter) { if (parameter instanceof IntegerParameter) { return new GUIIntegerParameter((IntegerParameter) parameter); @@ -59,12 +70,4 @@ public abstract class GUIParameter extends HBox { throw new ClassCastException("No GUIParameter subclass exists for argument of type " + parameter.getClass()); } } - - /** - * Writes the GUI parameter value back to the resources parameter, - * if any changes were made. - * - * @return true if the experiment needs to be reset, false otherwise. - */ - public abstract boolean applyChange(); } -- cgit v1.2.3