aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/gui/settings
diff options
context:
space:
mode:
Diffstat (limited to 'src/jcgp/gui/settings')
-rw-r--r--src/jcgp/gui/settings/SettingsPane.java595
-rw-r--r--src/jcgp/gui/settings/parameters/GUIBooleanParameter.java82
-rw-r--r--src/jcgp/gui/settings/parameters/GUIDoubleParameter.java110
-rw-r--r--src/jcgp/gui/settings/parameters/GUIIntegerParameter.java107
-rw-r--r--src/jcgp/gui/settings/parameters/GUIParameter.java235
-rw-r--r--src/jcgp/gui/settings/testcase/TestCaseTable.java124
6 files changed, 0 insertions, 1253 deletions
diff --git a/src/jcgp/gui/settings/SettingsPane.java b/src/jcgp/gui/settings/SettingsPane.java
deleted file mode 100644
index bad42cd..0000000
--- a/src/jcgp/gui/settings/SettingsPane.java
+++ /dev/null
@@ -1,595 +0,0 @@
-package jcgp.gui.settings;
-
-import java.io.File;
-import java.util.ArrayList;
-
-import javafx.event.ActionEvent;
-import javafx.event.EventHandler;
-import javafx.geometry.Insets;
-import javafx.scene.control.Button;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.ComboBox;
-import javafx.scene.control.ScrollPane;
-import javafx.scene.layout.AnchorPane;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.VBox;
-import javafx.scene.text.Font;
-import javafx.scene.text.Text;
-import javafx.stage.FileChooser;
-import javafx.stage.FileChooser.ExtensionFilter;
-import jcgp.JCGP;
-import jcgp.backend.function.FunctionSet;
-import jcgp.backend.modules.es.EvolutionaryStrategy;
-import jcgp.backend.modules.mutator.Mutator;
-import jcgp.backend.modules.problem.Problem;
-import jcgp.backend.modules.problem.TestCaseProblem;
-import jcgp.backend.parameters.Parameter;
-import jcgp.gui.GUI;
-import jcgp.gui.constants.Constants;
-import jcgp.gui.settings.parameters.GUIParameter;
-import jcgp.gui.settings.testcase.TestCaseTable;
-
-/**
- * This is a fairly hefty class which encapsulates the entire right-hand
- * control pane. It contains base parameters, module selectors and their
- * associated parameters, flow controls and file loading/saving buttons.
- * <br><br>
- * A single instance of this class is used in {@code GUI}.
- *
- *
- * @author Eduardo Pedroni
- *
- */
-public class SettingsPane extends AnchorPane {
-
- /*
- * The primary containers, these make up each section of the settings pane.
- */
- private VBox mainContainer;
- private VBox baseParameterPane, eaPane, mutatorPane, problemPane;
- private VBox nodeFunctions;
-
- // all buttons
- private Button runPause = new Button("Run"), step = new Button("Step"), reset = new Button("Reset");
- private Button loadParameters = new Button("Load parameters"), loadChromosome = new Button("Load chromosome"), saveChromosome = new Button("Save chromosome");
-
- // this is a list of parameters used for parameter validity checks
- private ArrayList<GUIParameter<?>> parameters = new ArrayList<GUIParameter<?>>();
-
- // the test case table stage
- private TestCaseTable testCaseTable;
-
- // a reference to the parent GUI
- private GUI gui;
-
- private int currentArity;
-
- /**
- * Create a new instance of {@code SettingsPane} associated
- * with the specified {@code GUI} object.
- *
- * @param gui a reference to this object's parent.
- */
- public SettingsPane(GUI gui) {
- super();
- this.gui = gui;
-
- // acquire a reference to jcgp, for convenience
- final JCGP jcgp = gui.getExperiment();
-
- // make the overarching container
- mainContainer = new VBox(8);
- mainContainer.setPadding(new Insets(5, Constants.RESIZE_MARGIN, 0, 2));
-
- setMinWidth(Constants.SETTINGS_MIN_WIDTH);
- setPrefWidth(Constants.SETTINGS_MIN_WIDTH);
-
- // initialise all sub-divisions
- initialiseBaseParameters(jcgp);
-
- initialiseEAParameters(jcgp);
-
- initialiseMutatorParameters(jcgp);
-
- initialiseProblemTypeParameters(jcgp, gui);
-
- createControls(gui);
-
- // prepare the scroll pane
- ScrollPane scroll = new ScrollPane();
- scroll.setFitToWidth(true);
- scroll.setContent(mainContainer);
- scroll.setStyle("-fx-background-color: #FFFFFF");
-
- // anchor the scroll pane to itself, bearing in mind the resize margin
- AnchorPane.setTopAnchor(scroll, 0.0);
- AnchorPane.setBottomAnchor(scroll, 0.0);
- AnchorPane.setRightAnchor(scroll, 0.0);
- AnchorPane.setLeftAnchor(scroll, Constants.RESIZE_MARGIN);
-
- // add the scroll pane, all done!
- getChildren().add(scroll);
- }
-
- /**
- * Creates the base parameters pane
- *
- * @param jcgp
- */
- private void initialiseBaseParameters(JCGP jcgp) {
- baseParameterPane = new VBox(2);
-
- Text header = new Text("Base Parameters");
- header.setFont(Font.font("Arial", 14));
- header.setUnderline(true);
-
- baseParameterPane.getChildren().add(header);
-
- parameters.add(GUIParameter.create(jcgp.getResources().getRowsParameter(), this));
- parameters.add(GUIParameter.create(jcgp.getResources().getColumnsParameter(), this));
- parameters.add(GUIParameter.create(jcgp.getResources().getInputsParameter(), this));
- parameters.add(GUIParameter.create(jcgp.getResources().getOutputsParameter(), this));
- parameters.add(GUIParameter.create(jcgp.getResources().getLevelsBackParameter(), this));
-
- GUIParameter<?> gp = GUIParameter.create(jcgp.getResources().getPopulationSizeParameter(), this);
- gp.setPadding(new Insets(0, 0, 10, 0));
- parameters.add(gp);
-
- parameters.add(GUIParameter.create(jcgp.getResources().getCurrentGenerationParameter(), this));
- parameters.add(GUIParameter.create(jcgp.getResources().getGenerationsParameter(), this));
- parameters.add(GUIParameter.create(jcgp.getResources().getCurrentRunParameter(), this));
-
- gp = GUIParameter.create(jcgp.getResources().getRunsParameter(), this);
- gp.setPadding(new Insets(0, 0, 10, 0));
- parameters.add(gp);
-
- parameters.add(GUIParameter.create(jcgp.getResources().getSeedParameter(), this));
- parameters.add(GUIParameter.create(jcgp.getResources().getReportIntervalParameter(), this));
-
- baseParameterPane.getChildren().addAll(parameters);
- mainContainer.getChildren().add(baseParameterPane);
- }
-
- private void initialiseEAParameters(final JCGP jcgp) {
- eaPane = new VBox(2);
-
- Text header = new Text("Evolutionary Strategy");
- header.setFont(Font.font("Arial", 14));
- header.setUnderline(true);
-
- final ComboBox<EvolutionaryStrategy> esCBox = new ComboBox<EvolutionaryStrategy>();
- esCBox.getItems().addAll(jcgp.getEvolutionaryStrategies());
- esCBox.getSelectionModel().select(jcgp.getEvolutionaryStrategy());
- esCBox.prefWidthProperty().bind(mainContainer.widthProperty());
-
- final VBox eaParameters = new VBox(2);
-
- refreshParameters(jcgp.getEvolutionaryStrategy().getLocalParameters(), eaParameters);
-
- esCBox.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- jcgp.setEvolutionaryStrategy(esCBox.getSelectionModel().getSelectedIndex());
- refreshParameters(esCBox.getSelectionModel().getSelectedItem().getLocalParameters(), eaParameters);
- gui.flushConsole();
- }
- });
-
- eaPane.getChildren().addAll(header, esCBox, eaParameters);
- mainContainer.getChildren().add(eaPane);
- }
-
- private void initialiseMutatorParameters(final JCGP jcgp) {
- mutatorPane = new VBox(2);
-
- Text header = new Text("Mutator");
- header.setFont(Font.font("Arial", 14));
- header.setUnderline(true);
-
- final ComboBox<Mutator> mutatorCBox = new ComboBox<Mutator>();
- mutatorCBox.getItems().addAll(jcgp.getMutators());
- mutatorCBox.getSelectionModel().select(jcgp.getMutator());
- mutatorCBox.prefWidthProperty().bind(mainContainer.widthProperty());
-
- final VBox mutatorParameters = new VBox(2);
- refreshParameters(jcgp.getMutator().getLocalParameters(), mutatorParameters);
-
- mutatorCBox.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- jcgp.setMutator(mutatorCBox.getSelectionModel().getSelectedIndex());
- refreshParameters(mutatorCBox.getSelectionModel().getSelectedItem().getLocalParameters(), mutatorParameters);
- gui.flushConsole();
- }
- });
-
- mutatorPane.getChildren().addAll(header, mutatorCBox, mutatorParameters);
- mainContainer.getChildren().add(mutatorPane);
- }
-
- private void initialiseProblemTypeParameters(final JCGP jcgp, final GUI gui) {
- updateArity();
-
- problemPane= new VBox(2);
-
- Text header = new Text("Problem Type");
- header.setFont(Font.font("Arial", 14));
- header.setUnderline(true);
-
- final ComboBox<Problem> problemCBox = new ComboBox<Problem>();
- problemCBox.getItems().addAll(jcgp.getProblems());
- problemCBox.getSelectionModel().select(jcgp.getProblem());
- problemCBox.prefWidthProperty().bind(mainContainer.widthProperty());
-
- final VBox problemParameters = new VBox(2);
- problemParameters.setPadding(new Insets(0, 0, 4, 0));
- refreshParameters(jcgp.getProblem().getLocalParameters(), problemParameters);
-
- final HBox testCaseControlContainer = new HBox(2);
-
- final Button showTestCaseButton = makeTestCaseButton();
- final Button loadProblemDataButton = makeLoadTestCaseButton();
- HBox.setHgrow(showTestCaseButton, Priority.ALWAYS);
- showTestCaseButton.setMaxWidth(Double.MAX_VALUE);
- HBox.setHgrow(loadProblemDataButton, Priority.ALWAYS);
- loadProblemDataButton.setMaxWidth(Double.MAX_VALUE);
-
- if (jcgp.getProblem() instanceof TestCaseProblem<?>) {
- testCaseControlContainer.getChildren().addAll(showTestCaseButton, loadProblemDataButton);
- remakeTestCaseTable();
- } else {
- testCaseControlContainer.getChildren().add(loadProblemDataButton);
- }
-
- nodeFunctions = new VBox(2);
- nodeFunctions.setPadding(new Insets(0, 0, 4, 0));
- refreshFunctions();
-
- problemCBox.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- jcgp.setProblem(problemCBox.getSelectionModel().getSelectedIndex());
- updateArity();
- refreshParameters(jcgp.getProblem().getLocalParameters(), problemParameters);
- if (testCaseTable != null) {
- testCaseTable.close();
- }
- gui.setEvaluating(false);
- refreshFunctions();
- testCaseControlContainer.getChildren().clear();
- if (jcgp.getProblem() instanceof TestCaseProblem) {
- testCaseControlContainer.getChildren().addAll(showTestCaseButton, loadProblemDataButton);
- remakeTestCaseTable();
- } else {
- testCaseControlContainer.getChildren().add(loadProblemDataButton);
- }
- gui.reset();
- }
- });
-
- problemPane.getChildren().addAll(header, problemCBox, problemParameters, nodeFunctions, testCaseControlContainer);
- mainContainer.getChildren().add(problemPane);
-
- }
-
- private Button makeLoadTestCaseButton() {
- Button b = new Button("Load data");
- b.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- FileChooser fc = new FileChooser();
- fc.setTitle("Open problem file...");
- fc.getExtensionFilters().add(new ExtensionFilter("CGP " + gui.getExperiment().getProblem() + " files", "*" + ((TestCaseProblem<?>) gui.getExperiment().getProblem()).getFileExtension()));
- fc.getExtensionFilters().add(new ExtensionFilter("All files", "*.*"));
- File chrFile = fc.showOpenDialog(gui.getStage());
- if (chrFile != null) {
- gui.getExperiment().loadProblemData(chrFile);
- remakeTestCaseTable();
- gui.reDraw();
- }
- }
- });
- return b;
- }
-
- private Button makeTestCaseButton() {
- Button b = new Button("Show data");
- b.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- testCaseTable.show();
- }
- });
- return b;
- }
-
- private void createControls(final GUI gui) {
- Text header = new Text("Experiment controls");
- header.setFont(Font.font("Arial", 14));
- header.setUnderline(true);
-
- final VBox controls = new VBox(2);
- controls.setFillWidth(true);
-
- final HBox flowButtons = new HBox(2);
- runPause.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- gui.runPause();
- }
- });
-
- step.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- gui.step();
- }
- });
-
- reset.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- gui.reset();
- }
- });
-
- HBox.setHgrow(runPause, Priority.ALWAYS);
- runPause.setMaxWidth(Double.MAX_VALUE);
- HBox.setHgrow(step, Priority.ALWAYS);
- step.setMaxWidth(Double.MAX_VALUE);
- HBox.setHgrow(reset, Priority.ALWAYS);
- reset.setMaxWidth(Double.MAX_VALUE);
-
- flowButtons.getChildren().addAll(runPause, step, reset);
- flowButtons.setPadding(new Insets(0, 0, 10, 0));
-
- loadParameters.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- FileChooser fc = new FileChooser();
- fc.setTitle("Open .par file...");
- fc.getExtensionFilters().add(new ExtensionFilter("CGP parameter files", "*.par"));
- fc.getExtensionFilters().add(new ExtensionFilter("All files", "*.*"));
- File parFile = fc.showOpenDialog(gui.getStage());
- if (parFile != null) {
- gui.getExperiment().loadParameters(parFile);
- gui.reDraw();
- refreshFunctions();
- }
- gui.flushConsole();
- }
- });
-
- loadChromosome.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- FileChooser fc = new FileChooser();
- fc.setTitle("Load .chr file...");
- fc.getExtensionFilters().add(new ExtensionFilter("CGP chromosome files", "*.chr"));
- fc.getExtensionFilters().add(new ExtensionFilter("All files", "*.*"));
- File chrFile = fc.showOpenDialog(gui.getStage());
- if (chrFile != null) {
- gui.getExperiment().loadChromosome(chrFile, gui.getChromosomeIndex());
- gui.reDraw();
- }
- gui.flushConsole();
- }
- });
- saveChromosome.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- FileChooser fc = new FileChooser();
- fc.setTitle("Save .chr file...");
- fc.getExtensionFilters().add(new ExtensionFilter("CGP chromosome files", "*.chr"));
- fc.getExtensionFilters().add(new ExtensionFilter("All files", "*.*"));
- File chrFile = fc.showSaveDialog(gui.getStage());
- if (chrFile != null) {
- gui.getExperiment().saveChromosome(chrFile, gui.getChromosomeIndex());
- }
- gui.flushConsole();
- }
- });
-
- HBox.setHgrow(loadParameters, Priority.ALWAYS);
- loadParameters.setMaxWidth(Double.MAX_VALUE);
- HBox.setHgrow(loadChromosome, Priority.ALWAYS);
- loadChromosome.setMaxWidth(Double.MAX_VALUE);
- HBox.setHgrow(saveChromosome, Priority.ALWAYS);
- saveChromosome.setMaxWidth(Double.MAX_VALUE);
-
- controls.getChildren().addAll(header, flowButtons, loadParameters, loadChromosome, saveChromosome);
-
- mainContainer.getChildren().add(controls);
- }
-
- /**
- * Builds {@code GUIParameter}s and adds them to the provided {@code VBox}.
- * The parameters built are taken from the specified list.
- *
- * @param newParameters the list of parameters to add.
- * @param container the container to add the parameters to.
- */
- private void refreshParameters(ArrayList<Parameter<?>> newParameters, VBox container) {
- // remove what is currently in the container from the parameter list
- parameters.removeAll(container.getChildren());
- // remove everything in the container
- container.getChildren().clear();
- // if there are parameters to add, add them all
- if (newParameters != null) {
- for (int i = 0; i < newParameters.size(); i++) {
- // factory method returns the right subtype of GUIParameter
- GUIParameter<?> guiParameter = GUIParameter.create(newParameters.get(i), this);
- // make sure to add it to the parameter list as well
- parameters.add(guiParameter);
- container.getChildren().add(guiParameter);
- }
- }
- // do a quick refresh just in case something is invalid
- revalidateParameters();
- }
-
- /**
- * This method handles a problem type change by updating the list of allowed
- * node functions.
- * <br><br>
- * It does so by creating new checkboxes for each function in the function set.
- */
- private void refreshFunctions() {
- // remove all current functions
- nodeFunctions.getChildren().clear();
- CheckBox checkBox;
- // get a reference to the function set
- final FunctionSet functionSet = gui.getExperiment().getResources().getFunctionSet();
- for (int i = 0; i < functionSet.getTotalFunctionCount(); i++) {
- // add a checkbox for each function
- checkBox = new CheckBox(functionSet.getFunction(i).toString());
- checkBox.setId(String.valueOf(i));
- // make sure the selection matches the function set
- checkBox.setSelected(functionSet.isEnabled(functionSet.getFunction(i)));
- final int index = i;
- // set listener so function set gets updated if the checkboxes change
- checkBox.setOnAction(new EventHandler<ActionEvent>() {
- @Override
- public void handle(ActionEvent event) {
- if (((CheckBox) event.getSource()).isSelected()) {
- functionSet.enableFunction(index);
- } else {
- functionSet.disableFunction(index);
- }
- gui.updateFunctionSelector();
- revalidateParameters();
- }
- });
- // add the new checkbox
- nodeFunctions.getChildren().add(checkBox);
- }
- // make sure function selector has all functions
- gui.updateFunctionSelector();
- }
-
- /**
- * @return true if the experiment is currently evolving something, false otherwise.
- */
- public boolean isExperimentRunning() {
- return gui.isWorking();
- }
-
- /**
- *
- * @return true if the experiment needs to be reset, false if otherwise.
- */
- public boolean isResetRequired() {
- for (GUIParameter<?> parameter : parameters) {
- if (parameter.requiresReset()) {
- return true;
- }
- }
- if (arityChanged()) {
- return true;
- }
- return false;
- }
-
- /**
- * @return true if no parameters have their status set to ParameterStatus.INVALID.
- */
- public boolean areParametersValid() {
- for (GUIParameter<?> parameter : parameters) {
- if (!parameter.isValid()) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Calls validate() on every parameter. This is called whenever a parameter changes,
- * so that other parameters update their status in case they were dependent on the
- * changed parameter.
- * <br><br>
- * This also disables the controls if a reset is necessary, preventing the experiment
- * from running until it has happened.
- */
- public void revalidateParameters() {
- boolean disableControls = false;
- for (GUIParameter<?> parameter : parameters) {
- parameter.validate();
- if (parameter.requiresReset()) {
- disableControls = true;
- }
- }
- if (arityChanged()) {
- disableControls = true;
- }
-
- runPause.setDisable(disableControls);
- step.setDisable(disableControls);
- }
-
- /**
- * Calls applyValue() on every parameter. This is called when a reset occurs, so that
- * the new value will be used as a reference instead of the old reference value.
- * <br><br>
- * It also closes the test case table, just in case.
- */
- public void applyParameters() {
- for (GUIParameter<?> parameter : parameters) {
- parameter.applyValue();
- }
- updateArity();
- if (testCaseTable != null) {
- testCaseTable.close();
- }
- }
-
- /**
- * Updates all of the controls to their appropriate state based on the status of the
- * experiment, in order to prevent inappropriate operations if the experiment is
- * running or finished.
- *
- * @param running true if the experiment is running.
- * @param finished true if the experiment is finished.
- */
- public void updateControls(boolean running, boolean finished) {
- baseParameterPane.setDisable(running);
- eaPane.setDisable(running);
- mutatorPane.setDisable(running);
- problemPane.setDisable(running);
-
- runPause.setText(running ? "Pause" : "Run");
- runPause.setDisable(finished);
- step.setDisable(running || finished);
- reset.setDisable(running);
-
- loadParameters.setDisable(running);
- loadChromosome.setDisable(running);
- saveChromosome.setDisable(running);
-
- testCaseTable.getTable().setDisable(running);
- }
-
- private void remakeTestCaseTable() {
- boolean wasShowing = false;
- if (testCaseTable != null) {
- wasShowing = testCaseTable.isShowing();
- testCaseTable.close();
- }
- testCaseTable = new TestCaseTable((TestCaseProblem<Object>) gui.getExperiment().getProblem(), gui);
- if (wasShowing) {
- testCaseTable.show();
- }
- }
-
- public TestCaseTable getTestCaseTable() {
- return testCaseTable;
- }
-
- private void updateArity() {
- currentArity = gui.getExperiment().getProblem().getFunctionSet().getMaxArity();
- }
-
- private boolean arityChanged() {
- return currentArity != gui.getExperiment().getProblem().getFunctionSet().getMaxArity();
- }
-}
diff --git a/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java b/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java
deleted file mode 100644
index a1f03fe..0000000
--- a/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package jcgp.gui.settings.parameters;
-
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.scene.control.CheckBox;
-import javafx.scene.control.Control;
-import jcgp.backend.parameters.BooleanParameter;
-import jcgp.backend.parameters.ParameterStatus;
-import jcgp.gui.constants.Constants;
-import jcgp.gui.settings.SettingsPane;
-
-/**
- * This extension of @code{GUIParameter} uses a @code{CheckBox} to display
- * the value of a @code{BooleanParameter}. It cannot be constructed
- * directly - instead, use @code{GUIParameter.create()}.
- * <br><br>
- * See {@link GUIParameter} for more information.
- *
- * @author Eduardo Pedroni
- */
-public class GUIBooleanParameter extends GUIParameter<Boolean> {
-
- private CheckBox checkBox;
-
- /**
- * This protected constructor is intended for use
- * by the factory method only.
- *
- */
- protected GUIBooleanParameter(BooleanParameter parameter, SettingsPane sp) {
- super(parameter, sp);
- }
-
- @Override
- protected Control makeControl() {
- checkBox = new CheckBox();
- checkBox.setSelected(parameter.get());
-
- return checkBox;
- }
-
- @Override
- protected void setControlListeners() {
- /* pass the CheckBox value back to the parameter whenever it gets
- * modified, provided the experiment isn't running */
- checkBox.selectedProperty().addListener(new ChangeListener<Boolean>() {
- @Override
- public void changed(
- ObservableValue<? extends Boolean> observable,
- Boolean oldValue, Boolean newValue) {
- if (!settingsPane.isExperimentRunning()) {
- parameter.set(newValue);
- settingsPane.revalidateParameters();
- }
- }
- });
- }
-
- @Override
- protected void setValidityStyle() {
- // update the Control's style and tooltip based on the status of the parameter
- if (parameter.getStatus() == ParameterStatus.INVALID) {
- checkBox.setStyle(Constants.BASE_CHECKBOX_STYLE + Constants.INVALID_PARAMETER_STYLE);
- checkBox.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else if (parameter.getStatus() == ParameterStatus.WARNING
- || parameter.getStatus() == ParameterStatus.WARNING_RESET) {
- checkBox.setStyle(Constants.BASE_CHECKBOX_STYLE + Constants.WARNING_PARAMETER_STYLE);
- checkBox.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else {
- checkBox.setStyle(Constants.BASE_CHECKBOX_STYLE + Constants.VALID_PARAMETER_STYLE);
- checkBox.setTooltip(null);
- }
- }
-
- @Override
- public void refreshValue() {
- checkBox.setSelected(parameter.get());
- }
-
-}
diff --git a/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java b/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java
deleted file mode 100644
index feee34c..0000000
--- a/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package jcgp.gui.settings.parameters;
-
-import java.text.DecimalFormat;
-
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.geometry.Pos;
-import javafx.scene.control.Control;
-import javafx.scene.control.TextField;
-import jcgp.backend.parameters.DoubleParameter;
-import jcgp.backend.parameters.ParameterStatus;
-import jcgp.gui.constants.Constants;
-import jcgp.gui.settings.SettingsPane;
-
-/**
- * This extension of @code{GUIParameter} uses a @code{TextField} to display
- * the value of a @code{DoubleParameter}. It cannot be constructed
- * directly - instead, use @code{GUIParameter.create()}.
- * <br><br>
- * See {@link GUIParameter} for more information.
- *
- * @author Eduardo Pedroni
- */
-public class GUIDoubleParameter extends GUIParameter<Number> {
-
- private TextField textField;
- private DecimalFormat decimalFormat;
-
- /**
- * This protected constructor is intended for use
- * by the factory method only.
- *
- */
- protected GUIDoubleParameter(DoubleParameter parameter, SettingsPane sp) {
- super(parameter, sp);
- }
-
- @Override
- protected Control makeControl() {
- // we use a text field, and a formatting class to enforce decimals
- decimalFormat = new DecimalFormat();
- decimalFormat.setMaximumFractionDigits(10);
- textField = new TextField(decimalFormat.format(parameter.get().doubleValue()));
- textField.setStyle(Constants.VALID_PARAMETER_STYLE);
- textField.setAlignment(Pos.CENTER_RIGHT);
- textField.prefWidthProperty().bind(widthProperty().divide(2));
- return textField;
- }
-
- @Override
- protected void setControlListeners() {
- /* pass the TextField value back to the parameter whenever it gets
- * modified, provided it is not empty, the experiment isn't running
- * and it matches the double-precision regex filter */
- textField.textProperty().addListener(new ChangeListener<String>() {
- @Override
- public void changed(
- ObservableValue<? extends String> observable,
- String oldValue, String newValue) {
- if (!settingsPane.isExperimentRunning()) {
- if (newValue.matches("^[-+]?[0-9]*\\.?[0-9]+$")) {
- if (!newValue.isEmpty()) {
- double value = Double.parseDouble(newValue);
- parameter.set(value);
- settingsPane.revalidateParameters();
- }
- } else {
- refreshValue();
- }
- }
- }
- });
- /* if the TextField loses focus and is empty, set it to the current
- * value of the parameter */
- textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
- @Override
- public void changed(
- ObservableValue<? extends Boolean> observable,
- Boolean oldValue, Boolean newValue) {
- if (!newValue) {
- refreshValue();
- }
- }
- });
- }
-
- @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(Constants.BASE_TEXT_STYLE + Constants.INVALID_PARAMETER_STYLE);
- textField.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else if (parameter.getStatus() == ParameterStatus.WARNING || parameter.getStatus() == ParameterStatus.WARNING_RESET) {
- textField.setStyle(Constants.BASE_TEXT_STYLE + Constants.WARNING_PARAMETER_STYLE);
- textField.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else {
- textField.setStyle(Constants.BASE_TEXT_STYLE + Constants.VALID_PARAMETER_STYLE);
- textField.setTooltip(null);
- }
- }
-
- @Override
- public void refreshValue() {
- if (!textField.isFocused()) {
- textField.setText(decimalFormat.format(parameter.get().doubleValue()));
- }
- }
-}
diff --git a/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java b/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java
deleted file mode 100644
index bcfbe50..0000000
--- a/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package jcgp.gui.settings.parameters;
-
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.geometry.Pos;
-import javafx.scene.control.Control;
-import javafx.scene.control.TextField;
-import jcgp.backend.parameters.IntegerParameter;
-import jcgp.backend.parameters.ParameterStatus;
-import jcgp.gui.constants.Constants;
-import jcgp.gui.settings.SettingsPane;
-
-/**
- * This extension of @code{GUIParameter} uses a @code{TextField} to display
- * the value of a @code{IntegerParameter}. It cannot be constructed
- * directly - instead, use @code{GUIParameter.create()}.
- * <br><br>
- * See {@link GUIParameter} for more information.
- *
- * @author Eduardo Pedroni
- */
-public class GUIIntegerParameter extends GUIParameter<Number> {
-
- private TextField textField;
-
- /**
- * This protected constructor is intended for use
- * by the factory method only.
- *
- */
- protected GUIIntegerParameter(IntegerParameter parameter, SettingsPane sp) {
- super(parameter, sp);
- }
-
- @Override
- protected Control makeControl() {
- // this uses a text field
- textField = new TextField(String.valueOf(parameter.get()));
- textField.setStyle(Constants.VALID_PARAMETER_STYLE);
- textField.setAlignment(Pos.CENTER_RIGHT);
- textField.prefWidthProperty().bind(widthProperty().divide(2));
-
- return textField;
- }
-
- @Override
- protected void setControlListeners() {
- /* pass the TextField value back to the parameter whenever it gets
- * modified, provided it is not empty, the experiment isn't running
- * and it matches the integer regex pattern */
- textField.textProperty().addListener(new ChangeListener<String>() {
- @Override
- public void changed(
- ObservableValue<? extends String> observable,
- String oldValue, String newValue) {
- if (!settingsPane.isExperimentRunning()) {
- if (newValue.matches("[0-9]*")) {
- if (!newValue.isEmpty()) {
- int value = Integer.parseInt(newValue);
- parameter.set(value);
- settingsPane.revalidateParameters();
- }
- } else {
- refreshValue();
- }
- }
- }
- });
- /* if the TextField loses focus and is empty, set it to the current
- * value of the parameter */
- textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
- @Override
- public void changed(
- ObservableValue<? extends Boolean> observable,
- Boolean oldValue, Boolean newValue) {
- if (!newValue) {
- refreshValue();
- }
- }
- });
- }
-
- @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(Constants.BASE_TEXT_STYLE + Constants.INVALID_PARAMETER_STYLE);
- textField.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else if (parameter.getStatus() == ParameterStatus.WARNING
- || parameter.getStatus() == ParameterStatus.WARNING_RESET) {
- textField.setStyle(Constants.BASE_TEXT_STYLE + Constants.WARNING_PARAMETER_STYLE);
- textField.setTooltip(tooltip);
- tooltip.setText(parameter.getStatus().getDetails());
- } else {
- textField.setStyle(Constants.BASE_TEXT_STYLE + Constants.VALID_PARAMETER_STYLE);
- textField.setTooltip(null);
- }
- }
-
- @Override
- public void refreshValue() {
- if (!textField.isFocused()) {
- textField.setText(parameter.get().toString());
- }
- }
-}
diff --git a/src/jcgp/gui/settings/parameters/GUIParameter.java b/src/jcgp/gui/settings/parameters/GUIParameter.java
deleted file mode 100644
index 59aecf6..0000000
--- a/src/jcgp/gui/settings/parameters/GUIParameter.java
+++ /dev/null
@@ -1,235 +0,0 @@
-package jcgp.gui.settings.parameters;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javafx.application.Platform;
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.geometry.Pos;
-import javafx.scene.control.Control;
-import javafx.scene.control.Label;
-import javafx.scene.control.Tooltip;
-import javafx.scene.layout.HBox;
-import jcgp.backend.parameters.BooleanParameter;
-import jcgp.backend.parameters.DoubleParameter;
-import jcgp.backend.parameters.IntegerParameter;
-import jcgp.backend.parameters.Parameter;
-import jcgp.backend.parameters.ParameterStatus;
-import jcgp.gui.settings.SettingsPane;
-
-/**
- *
- * This is the base class for all @code{GUIParameter}s. Using the factory method @code{GUIParameter.create()}
- * generates an appropriate instance of this class for the specified parameter.
- * <br><br>
- * A @code{GUIParameter} is an @code{HBox} containing a @code{Text} for the parameter name
- * and a @code{Control} for interaction.
- * It stores an instance of its associated @code{Parameter} object and also contains a @code{Tooltip} for
- * displaying status information.
- * <br><br>
- * Monitor parameters are updated automatically and have their @code{Control} disabled so
- * that no changes can be made via the GUI.
- * Non-monitor parameters are updated automatically as well, but may be changed by the user
- * if the program is not evolving.
- *
- * @see Parameter
- * @author Eduardo Pedroni
- * @param <T> the parameter data type
- */
-public abstract class GUIParameter<T> extends HBox {
-
- private Label name;
- private Control valueControl;
-
- protected SettingsPane settingsPane;
- protected Tooltip tooltip;
- protected Parameter<T> parameter;
-
- /** This is the lock used to prevent more than one update task to be scheduled
- * at the same time on the same GUIParameter. */
- private AtomicBoolean updateLock = new AtomicBoolean(false);
-
- /**
- * This value is used to assert whether the control has changed values since
- * the program last ran. Therefore, it is updated whenever a generation occurs
- * or the experiment is reset.
- */
- private T referenceValue;
-
- /**
- * This protected template constructor contains the common elements to all
- * @code{GUIParameter}s and should be invoked by any subclasses using @code{super()}. It
- * defers the creation of the parameter {@code Control} object to the subclass
- * currently being built (which in turn is defined by the factory method).
- *
- * @param parameter a @code{Parameter} for which to generate a @code{GUIParameter}.
- * @param sp a reference to the @code{SettingsPane}.
- */
- protected GUIParameter(Parameter<T> parameter, final SettingsPane settingsPane) {
- this.parameter = parameter;
- this.referenceValue = parameter.get();
-
- this.settingsPane = settingsPane;
-
- setAlignment(Pos.CENTER_LEFT);
- setSpacing(5);
-
- name = new Label(parameter.toString());
- // set text width to half of the total width of the GUIParameter
- name.prefWidthProperty().bind(widthProperty().divide(2));
-
- // the tooltip is the hover-over label containing status information, when appropriate
- tooltip = new Tooltip();
- tooltip.setSkin(null);
-
- valueControl = makeControl();
-
- // if the parameter is a monitor, it should be permanently disabled
- valueControl.setDisable(parameter.isMonitor());
-
- // bind to parameter value property in a thread-safe way
- makeThreadSafeBinding();
-
- // if parameter is not a monitor, make sure the control is constrained appropriately
- if (!parameter.isMonitor()) {
- setControlListeners();
- }
-
- getChildren().addAll(name, valueControl);
- }
-
- /**
- * Factory method to create @code{GUIParameter}s from @code{Parameter}s.
- * Use this to create an appropriate @code{GUIParameter} from any instance of @code{Parameter},
- * rather than manually downcasting the @code{Parameter} object every time.
- *
- * @param parameter a parameter for which to generate a @code{GUIParameter}.
- * @param sp a reference to the @code{SettingsPane}.
- * @return an appropriate instance of @code{GUIParameter}.
- */
- public static GUIParameter<?> create(Parameter<?> parameter, SettingsPane sp) {
- if (parameter instanceof IntegerParameter) {
- return new GUIIntegerParameter((IntegerParameter) parameter, sp);
- } else if (parameter instanceof DoubleParameter) {
- return new GUIDoubleParameter((DoubleParameter) parameter, sp);
- } else if (parameter instanceof BooleanParameter) {
- return new GUIBooleanParameter((BooleanParameter) parameter, sp);
- } else {
- throw new ClassCastException("No GUIParameter subclass exists for argument of type " + parameter.getClass());
- }
- }
-
- /**
- * Parameters are intended to communicate information from the experiment
- * to the GUI. Since the experiment runs on a separate threads and it is illegal
- * to modify JavaFX objects from outside the JavaFX Application thread, this
- * special ChangeListener updates the GUIParameter in a safe way.
- * <br><br>
- * Note that this is applied to all parameters regardless of whether they are
- * monitors or not; the only difference between monitor and non-monitor parameters
- * is that monitor parameters cannot be modified from the GUI.
- */
- private void makeThreadSafeBinding() {
- parameter.valueProperty().addListener(new ChangeListener<Object>() {
- @Override
- public void changed(
- ObservableValue<? extends Object> observable,
- Object oldValue, Object newValue) {
- // only do this if the experiment is running
- if (settingsPane.isExperimentRunning() || !isFocused()) {
- /* here's the catch - atomically get the lock state and set it to true
- * the lock will only be false again when the runnable is finished executing,
- * preventing multiple runnables to concurrently update the same GUIParameter
- */
- if (!updateLock.getAndSet(true)) {
- Platform.runLater(new Runnable() {
- @Override
- public void run() {
- refreshValue();
- updateLock.set(false);
- }
- });
- }
- }
- }
- });
- }
-
- /**
- * @return true if the current value of the parameter does not prevent the
- * experiment from running.
- */
- public boolean isValid() {
- return parameter.getStatus() != ParameterStatus.INVALID;
- }
-
- /**
- * Force the parameter to validate its current value, and apply the associated
- * style to the @code{GUIParameter}.
- */
- public void validate() {
- parameter.validate(parameter.get());
- setValidityStyle();
- }
-
- /**
- * Certain parameter changes might require the experiment to be reset, either
- * because the parameter is critical or because its status requires a reset.
- *
- * @return true if an experiment reset is required due to this parameter changing.
- */
- public boolean requiresReset() {
- return (parameter.isCritical() && !parameter.get().equals(referenceValue))
- || parameter.getStatus() == ParameterStatus.WARNING_RESET;
- }
-
- /**
- * Set the current parameter value as the reference value of the @code{GUIParameter}.
- * The new reference value will be used to determine the validity of the parameter,
- * should its value change.
- */
- public void applyValue() {
- referenceValue = parameter.get();
- }
-
- /*
- * The following prototypes are instance-dependent and are called from
- * GUIParameter() as necessary.
- */
- /**
- * This method returns the @code{Control} object used to control the parameter.
- * <br><br>
- * Implementations of @code{GUIParameter} must override this method and return
- * a @code{Control} appropriate to the type of parameter. This will typically be
- * done by referencing the protected field @code{GUIParameter.parameter}.
- *
- * @return the Control object to be added to the GUIParameter.
- */
- protected abstract Control makeControl();
-
- /**
- * Adds the necessary handlers to the @code{Control} object in order to modify
- * the underlying parameter. This will typically consist of filtering key
- * presses to ensure no invalid characters are inserted, applying the new
- * value to the underlying parameter and revalidating the parameters to
- * reflect the changes made.
- */
- protected abstract void setControlListeners();
-
- /**
- * This method is called to style the @code{GUIParameter} according to the status of
- * the parameter, which can be obtained with @code{parameter.getStatus()}. While the
- * subclass is free to style itself in any way, the CSS strings defined here
- * (INVALID_PARAMETER_STYLE, WARNING_PARAMETER_STYLE, VALID_PARAMETER_STYLE)
- * provide a way to keep the GUI consistent.
- *
- * @see ParameterStatus
- */
- protected abstract void setValidityStyle();
-
- /**
- * Update the control so it shows the correct value of the parameter. This method
- * is used exclusively by the thread-safe binding created if the module is a monitor.
- */
- protected abstract void refreshValue();
-}
diff --git a/src/jcgp/gui/settings/testcase/TestCaseTable.java b/src/jcgp/gui/settings/testcase/TestCaseTable.java
deleted file mode 100644
index 605b75e..0000000
--- a/src/jcgp/gui/settings/testcase/TestCaseTable.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package jcgp.gui.settings.testcase;
-
-import java.util.ArrayList;
-
-import javafx.beans.property.SimpleStringProperty;
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.collections.ObservableList;
-import javafx.event.EventHandler;
-import javafx.scene.Scene;
-import javafx.scene.control.TableColumn;
-import javafx.scene.control.TableColumn.CellDataFeatures;
-import javafx.scene.control.TableView;
-import javafx.stage.Stage;
-import javafx.stage.WindowEvent;
-import javafx.util.Callback;
-import jcgp.backend.modules.problem.TestCaseProblem;
-import jcgp.backend.modules.problem.TestCaseProblem.TestCase;
-import jcgp.backend.resources.Resources;
-import jcgp.gui.GUI;
-
-/**
- * This is a test case table. For problems that have test cases,
- * this table shows the test case inputs and outputs. Clicking on
- * a test case (one is shown per row) applies the values to all
- * chromosome inputs shows the calculated values throughout the chromosome.
- *
- * @author Eduardo Pedroni
- *
- */
-public class TestCaseTable extends Stage {
-
- private TableView<TestCase<Object>> table;
-
- /**
- * Make a new instance of {@code TestCaseTable}.
- *
- * @param testCaseProblem the {@code TestCaseProblem} whose data must be displayed.
- * @param gui a reference to the GUI.
- */
- public TestCaseTable(final TestCaseProblem<Object> testCaseProblem, final GUI gui) {
- super();
-
- Resources resources = gui.getExperiment().getResources();
-
- // create the actual table view
- table = new TableView<TestCase<Object>>();
- // get test cases from problem
- ObservableList<TestCase<Object>> testCaseList = testCaseProblem.getTestCases();
-
- // prepare input and output columns
- ArrayList<TableColumn<TestCase<Object>, String>> inputs = new ArrayList<TableColumn<TestCase<Object>, String>>(resources.inputs());
- ArrayList<TableColumn<TestCase<Object>, String>> outputs = new ArrayList<TableColumn<TestCase<Object>, String>>(resources.outputs());
-
- // create input columns
- TableColumn<TestCase<Object>, String> tc;
- for (int i = 0; i < resources.inputs(); i++) {
- tc = new TableColumn<TestCase<Object>, String>("I: " + i);
- inputs.add(tc);
- final int index = i;
- tc.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<TestCase<Object>,String>, ObservableValue<String>>() {
- @Override
- public ObservableValue<String> call(CellDataFeatures<TestCase<Object>, String> param) {
- // create a new string property and give it the test case value, no need for dynamic binding - this wont change often
- return new SimpleStringProperty(param.getValue().getInputs()[index].toString());
- }
- });
- tc.setSortable(false);
- // set column width so all columns are distributed across the width of the stage
- tc.prefWidthProperty().bind(table.widthProperty().divide(resources.inputs() + resources.outputs()));
- }
-
- // create output columns
- for (int o = 0; o < resources.outputs(); o++) {
- tc = new TableColumn<TestCase<Object>, String>("O: " + o);
- outputs.add(tc);
- final int index = o;
- tc.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<TestCase<Object>,String>, ObservableValue<String>>() {
- @Override
- public ObservableValue<String> call(CellDataFeatures<TestCase<Object>, String> param) {
- // create a new string property and give it the test case value, no need for dynamic binding - this wont change often
- return new SimpleStringProperty(param.getValue().getOutputs()[index].toString());
- }
- });
- tc.setSortable(false);
- // set column width so all columns are distributed across the width of the stage
- tc.prefWidthProperty().bind(table.widthProperty().divide(resources.inputs() + resources.outputs()));
- }
-
- // add created columns
- table.getColumns().addAll(inputs);
- table.getColumns().addAll(outputs);
-
- // populate table with actual data
- table.setItems(testCaseList);
-
- // apply test case values when a new test case is selected
- table.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TestCase<Object>>() {
- @Override
- public void changed(ObservableValue<? extends TestCase<Object>> observable, TestCase<Object> oldValue, TestCase<Object> newValue) {
- gui.evaluateTestCase(newValue);
- }
- });
-
- // when the stage is closed, clear the selection
- // this doesn't work if the stage is closed by the program for some reason...
- setOnCloseRequest(new EventHandler<WindowEvent>() {
- @Override
- public void handle(WindowEvent event) {
- gui.hideGeneValues();
- table.getSelectionModel().clearSelection();
- }
- });
-
- setScene(new Scene(table));
- }
-
- /**
- * @return a reference to the actual table of test cases.
- */
- public TableView<TestCase<Object>> getTable() {
- return table;
- }
-}