diff options
Diffstat (limited to 'src/jcgp/gui/settings')
6 files changed, 240 insertions, 79 deletions
diff --git a/src/jcgp/gui/settings/SettingsPane.java b/src/jcgp/gui/settings/SettingsPane.java index e455846..9fcee8f 100644 --- a/src/jcgp/gui/settings/SettingsPane.java +++ b/src/jcgp/gui/settings/SettingsPane.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; +import javafx.scene.Group; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; @@ -18,11 +19,13 @@ import javafx.scene.text.Text; import jcgp.JCGP; import jcgp.backend.function.FunctionSet; import jcgp.backend.modules.es.EvolutionaryStrategy; -import jcgp.backend.modules.fitness.Problem; import jcgp.backend.modules.mutator.Mutator; +import jcgp.backend.modules.problem.Problem; +import jcgp.backend.modules.problem.TestCaseProblem; import jcgp.backend.resources.parameters.Parameter; import jcgp.gui.GUI; import jcgp.gui.settings.parameters.GUIParameter; +import jcgp.gui.settings.testcase.TestCaseTable; public class SettingsPane extends AnchorPane { @@ -33,23 +36,29 @@ public class SettingsPane extends AnchorPane { private Button loadParameters = new Button("Load parameters"), loadChromosome = new Button("Load chromosome"), saveChromosome = new Button("Save chromosome"); private ArrayList<GUIParameter<?>> parameters = new ArrayList<GUIParameter<?>>(); + + private TestCaseTable testCaseTable; + + private GUI gui; - public SettingsPane(JCGP cgp, GUI gui) { + public SettingsPane(GUI gui) { super(); + this.gui = gui; + final JCGP jcgp = gui.getExperiment(); mainContainer = new VBox(8); mainContainer.setPadding(new Insets(5, GUI.RESIZE_MARGIN, 0, 2)); - setMinWidth(GUI.SETTINGS_WIDTH); - setPrefWidth(GUI.SETTINGS_WIDTH); + setMinWidth(GUI.SETTINGS_MIN_WIDTH); + setPrefWidth(GUI.SETTINGS_MIN_WIDTH); - initialiseBaseParameters(cgp); + initialiseBaseParameters(jcgp); - initialiseEAParameters(cgp); + initialiseEAParameters(jcgp); - initialiseMutatorParameters(cgp); + initialiseMutatorParameters(jcgp); - initialiseProblemTypeParameters(cgp, gui); + initialiseProblemTypeParameters(jcgp, gui); createControls(gui); @@ -66,7 +75,7 @@ public class SettingsPane extends AnchorPane { getChildren().add(scroll); } - private void initialiseBaseParameters(JCGP cgp) { + private void initialiseBaseParameters(JCGP jcgp) { baseParameterPane = new VBox(2); Text header = new Text("Base Parameters"); @@ -75,32 +84,32 @@ public class SettingsPane extends AnchorPane { baseParameterPane.getChildren().add(header); - parameters.add(GUIParameter.create(cgp.getResources().getRowsParameter(), this)); - parameters.add(GUIParameter.create(cgp.getResources().getColumnsParameter(), this)); - parameters.add(GUIParameter.create(cgp.getResources().getInputsParameter(), this)); - parameters.add(GUIParameter.create(cgp.getResources().getOutputsParameter(), this)); - parameters.add(GUIParameter.create(cgp.getResources().getLevelsBackParameter(), this)); + 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(cgp.getResources().getPopulationSizeParameter(), this); + GUIParameter<?> gp = GUIParameter.create(jcgp.getResources().getPopulationSizeParameter(), this); gp.setPadding(new Insets(0, 0, 10, 0)); parameters.add(gp); - parameters.add(GUIParameter.create(cgp.getResources().getCurrentGenerationParameter(), this)); - parameters.add(GUIParameter.create(cgp.getResources().getGenerationsParameter(), this)); - parameters.add(GUIParameter.create(cgp.getResources().getCurrentRunParameter(), this)); + 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(cgp.getResources().getRunsParameter(), this); + gp = GUIParameter.create(jcgp.getResources().getRunsParameter(), this); gp.setPadding(new Insets(0, 0, 10, 0)); parameters.add(gp); - parameters.add(GUIParameter.create(cgp.getResources().getSeedParameter(), this)); - parameters.add(GUIParameter.create(cgp.getResources().getReportParameter(), this)); + parameters.add(GUIParameter.create(jcgp.getResources().getSeedParameter(), this)); + parameters.add(GUIParameter.create(jcgp.getResources().getReportParameter(), this)); baseParameterPane.getChildren().addAll(parameters); mainContainer.getChildren().add(baseParameterPane); } - private void initialiseEAParameters(final JCGP cgp) { + private void initialiseEAParameters(final JCGP jcgp) { eaPane = new VBox(2); Text header = new Text("Evolutionary Strategy"); @@ -108,21 +117,21 @@ public class SettingsPane extends AnchorPane { header.setUnderline(true); final ComboBox<EvolutionaryStrategy> eaCBox = new ComboBox<EvolutionaryStrategy>(); - eaCBox.getItems().addAll(cgp.getEvolutionaryStrategies()); - eaCBox.getSelectionModel().select(cgp.getEvolutionaryStrategy()); + eaCBox.getItems().addAll(jcgp.getEvolutionaryStrategies()); + eaCBox.getSelectionModel().select(jcgp.getEvolutionaryStrategy()); eaCBox.prefWidthProperty().bind(mainContainer.widthProperty()); final VBox eaParameters = new VBox(); eaParameters.setSpacing(2); - if (cgp.getEvolutionaryStrategy().getLocalParameters() != null) { - refreshParameters(cgp.getEvolutionaryStrategy().getLocalParameters(), eaParameters); + if (jcgp.getEvolutionaryStrategy().getLocalParameters() != null) { + refreshParameters(jcgp.getEvolutionaryStrategy().getLocalParameters(), eaParameters); } eaCBox.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { - cgp.setEvolutionaryStrategy(eaCBox.getSelectionModel().getSelectedIndex()); + jcgp.setEvolutionaryStrategy(eaCBox.getSelectionModel().getSelectedIndex()); if (eaCBox.getSelectionModel().getSelectedItem().getLocalParameters() != null) { refreshParameters(eaCBox.getSelectionModel().getSelectedItem().getLocalParameters(), eaParameters); } @@ -133,7 +142,7 @@ public class SettingsPane extends AnchorPane { mainContainer.getChildren().add(eaPane); } - private void initialiseMutatorParameters(final JCGP cgp) { + private void initialiseMutatorParameters(final JCGP jcgp) { mutatorPane = new VBox(2); Text header = new Text("Mutator"); @@ -141,20 +150,20 @@ public class SettingsPane extends AnchorPane { header.setUnderline(true); final ComboBox<Mutator> mutatorCBox = new ComboBox<Mutator>(); - mutatorCBox.getItems().addAll(cgp.getMutators()); - mutatorCBox.getSelectionModel().select(cgp.getMutator()); + mutatorCBox.getItems().addAll(jcgp.getMutators()); + mutatorCBox.getSelectionModel().select(jcgp.getMutator()); mutatorCBox.prefWidthProperty().bind(mainContainer.widthProperty()); final VBox mutatorParameters = new VBox(); mutatorParameters.setSpacing(2); - if (cgp.getEvolutionaryStrategy().getLocalParameters() != null) { - refreshParameters(cgp.getMutator().getLocalParameters(), mutatorParameters); + if (jcgp.getEvolutionaryStrategy().getLocalParameters() != null) { + refreshParameters(jcgp.getMutator().getLocalParameters(), mutatorParameters); } mutatorCBox.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { - cgp.setMutator(mutatorCBox.getSelectionModel().getSelectedIndex()); + jcgp.setMutator(mutatorCBox.getSelectionModel().getSelectedIndex()); if (mutatorCBox.getSelectionModel().getSelectedItem().getLocalParameters() != null) { refreshParameters(mutatorCBox.getSelectionModel().getSelectedItem().getLocalParameters(), mutatorParameters); } @@ -165,45 +174,72 @@ public class SettingsPane extends AnchorPane { mainContainer.getChildren().add(mutatorPane); } - private void initialiseProblemTypeParameters(final JCGP cgp, final GUI gui) { + private void initialiseProblemTypeParameters(final JCGP jcgp, final GUI gui) { problemPane= new VBox(2); Text header = new Text("Problem Type"); header.setFont(Font.font("Arial", 14)); header.setUnderline(true); - final ComboBox<Problem> ffCBox = new ComboBox<Problem>(); - ffCBox.getItems().addAll(cgp.getProblems()); - ffCBox.getSelectionModel().select(cgp.getProblem()); - ffCBox.prefWidthProperty().bind(mainContainer.widthProperty()); + 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(); + problemParameters.setSpacing(2); + problemParameters.setPadding(new Insets(0, 0, 4, 0)); + if (jcgp.getProblem().getLocalParameters() != null) { + refreshParameters(jcgp.getProblem().getLocalParameters(), problemParameters); + } - final VBox ffParameters = new VBox(); - ffParameters.setSpacing(2); - if (cgp.getProblem().getLocalParameters() != null) { - refreshParameters(cgp.getProblem().getLocalParameters(), ffParameters); + final Group showTestCaseContainer = new Group(); + final Button showTestCaseButton = makeTestCaseButton(); + if (jcgp.getProblem() instanceof TestCaseProblem<?>) { + showTestCaseContainer.getChildren().add(showTestCaseButton); + + testCaseTable = new TestCaseTable((TestCaseProblem<Object>) jcgp.getProblem(), gui); } final VBox nodeFunctions = new VBox(); nodeFunctions.setSpacing(2); - refreshFunctions(cgp.getResources().getFunctionSet(), nodeFunctions, gui); + nodeFunctions.setPadding(new Insets(0, 0, 4, 0)); + refreshFunctions(jcgp.getResources().getFunctionSet(), nodeFunctions, gui); - ffCBox.setOnAction(new EventHandler<ActionEvent>() { + problemCBox.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { - cgp.setProblem(ffCBox.getSelectionModel().getSelectedIndex()); - if (ffCBox.getSelectionModel().getSelectedItem().getLocalParameters() != null) { - refreshParameters(cgp.getProblem().getLocalParameters(), ffParameters); - refreshFunctions(cgp.getProblem().getFunctionSet(), nodeFunctions, gui); + jcgp.setProblem(problemCBox.getSelectionModel().getSelectedIndex()); + if (jcgp.getProblem().getLocalParameters() != null) { + showTestCaseContainer.getChildren().clear(); + refreshParameters(jcgp.getProblem().getLocalParameters(), problemParameters); + refreshFunctions(jcgp.getProblem().getFunctionSet(), nodeFunctions, gui); + testCaseTable.close(); + if (jcgp.getProblem() instanceof TestCaseProblem) { + showTestCaseContainer.getChildren().add(showTestCaseButton); + testCaseTable = new TestCaseTable((TestCaseProblem<Object>) jcgp.getProblem(), gui); + } } gui.reset(); } }); - problemPane.getChildren().addAll(header, ffCBox, ffParameters, nodeFunctions); + problemPane.getChildren().addAll(header, problemCBox, problemParameters, nodeFunctions, showTestCaseContainer); mainContainer.getChildren().add(problemPane); } + private Button makeTestCaseButton() { + Button b = new Button("Show test cases"); + 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)); @@ -291,31 +327,43 @@ public class SettingsPane extends AnchorPane { revalidateParameters(); } - private void refreshFunctions(final FunctionSet fs, VBox vb, final GUI gui) { - vb.getChildren().clear(); + /** + * This method handles a problem type change by updating the list of allowed + * node functions. + * + * @param functionSet + * @param container + * @param gui + */ + private void refreshFunctions(final FunctionSet functionSet, VBox container, final GUI gui) { + container.getChildren().clear(); CheckBox cb; - for (int i = 0; i < fs.getTotalFunctionCount(); i++) { - cb = new CheckBox(fs.getFunction(i).getName()); + for (int i = 0; i < functionSet.getTotalFunctionCount(); i++) { + cb = new CheckBox(functionSet.getFunction(i).getName()); cb.setId(String.valueOf(i)); - cb.setSelected(fs.isEnabled(fs.getFunction(i))); + cb.setSelected(functionSet.isEnabled(functionSet.getFunction(i))); final int index = i; cb.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { if (((CheckBox) event.getSource()).isSelected()) { - fs.enableFunction(index); + functionSet.enableFunction(index); } else { - fs.disableFunction(index); + functionSet.disableFunction(index); } - GUI.updateFunctionSelector(); + gui.updateFunctionSelector(); } }); - vb.getChildren().add(cb); + container.getChildren().add(cb); - GUI.updateFunctionSelector(); + gui.updateFunctionSelector(); } } + public boolean isExperimentRunning() { + return gui.isWorking(); + } + /** * * @return true if the experiment needs to be reset, false otherwise. @@ -329,6 +377,9 @@ public class SettingsPane extends AnchorPane { return false; } + /** + * @return true if no parameters have their status set to ParameterStatus.INVALID. + */ public boolean areParametersValid() { for (GUIParameter<?> parameter : parameters) { if (!parameter.isValid()) { @@ -338,6 +389,11 @@ public class SettingsPane extends AnchorPane { 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. + */ public void revalidateParameters() { runPause.setDisable(false); for (GUIParameter<?> parameter : parameters) { @@ -348,12 +404,24 @@ public class SettingsPane extends AnchorPane { } } + /** + * 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. + */ public void applyParameters() { for (GUIParameter<?> parameter : parameters) { parameter.applyValue(); } } + /** + * 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); @@ -361,8 +429,13 @@ public class SettingsPane extends AnchorPane { problemPane.setDisable(running); runPause.setText(running ? "Pause" : "Run"); + System.out.println("[updateControls] run pause disable: " + finished); runPause.setDisable(finished); step.setDisable(running || finished); reset.setDisable(running); } + + public TestCaseTable getTestCaseTable() { + return testCaseTable; + } } diff --git a/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java b/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java index bada5d4..e708c53 100644 --- a/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java @@ -6,7 +6,6 @@ import javafx.scene.control.CheckBox; import javafx.scene.control.Control; import jcgp.backend.resources.parameters.BooleanParameter; import jcgp.backend.resources.parameters.ParameterStatus; -import jcgp.gui.GUI; import jcgp.gui.settings.SettingsPane; /** @@ -40,7 +39,7 @@ public class GUIBooleanParameter extends GUIParameter<Boolean> { } @Override - protected void setControlListeners(final SettingsPane sp) { + 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>() { @@ -48,9 +47,9 @@ public class GUIBooleanParameter extends GUIParameter<Boolean> { public void changed( ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { - if (!GUI.isWorking()) { + if (!settingsPane.isExperimentRunning()) { parameter.set(newValue); - sp.revalidateParameters(); + settingsPane.revalidateParameters(); } } }); diff --git a/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java b/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java index 87e7b69..29648ca 100644 --- a/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java @@ -9,7 +9,6 @@ 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.GUI; import jcgp.gui.settings.SettingsPane; /** @@ -44,7 +43,7 @@ public class GUIDoubleParameter extends GUIParameter<Number> { } @Override - protected void setControlListeners(final SettingsPane sp) { + 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<KeyEvent>() { @@ -63,9 +62,9 @@ public class GUIDoubleParameter extends GUIParameter<Number> { public void changed( ObservableValue<? extends String> observable, String oldValue, String newValue) { - if (!newValue.isEmpty() && !GUI.isWorking()) { + if (!newValue.isEmpty() && !settingsPane.isExperimentRunning()) { parameter.set(Double.parseDouble(newValue)); - sp.revalidateParameters(); + settingsPane.revalidateParameters(); } } diff --git a/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java b/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java index 6927f26..da2c11f 100644 --- a/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java @@ -9,7 +9,6 @@ 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.GUI; import jcgp.gui.settings.SettingsPane; /** @@ -44,7 +43,7 @@ public class GUIIntegerParameter extends GUIParameter<Number> { } @Override - protected void setControlListeners(final SettingsPane settingsPane) { + protected void setControlListeners() { /* filter keypresses and ignore anything that is not a number */ textField.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler<KeyEvent>() { @Override @@ -62,7 +61,7 @@ public class GUIIntegerParameter extends GUIParameter<Number> { public void changed( ObservableValue<? extends String> observable, String oldValue, String newValue) { - if (!newValue.isEmpty() && !GUI.isWorking()) { + if (!newValue.isEmpty() && !settingsPane.isExperimentRunning()) { parameter.set(Double.parseDouble(newValue)); settingsPane.revalidateParameters(); } diff --git a/src/jcgp/gui/settings/parameters/GUIParameter.java b/src/jcgp/gui/settings/parameters/GUIParameter.java index b7afb74..a8a8c4a 100644 --- a/src/jcgp/gui/settings/parameters/GUIParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIParameter.java @@ -49,6 +49,7 @@ public abstract class GUIParameter<T> extends HBox { private Text name; private Control valueControl; + protected SettingsPane settingsPane; protected Tooltip tooltip; protected Parameter<T> parameter; @@ -70,24 +71,24 @@ public abstract class GUIParameter<T> extends HBox { * @param parameter a Parameter for which to generate a GUIParameter * @param sp a reference to the SettingsPane */ - protected GUIParameter(Parameter<T> parameter, final SettingsPane sp) { + 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 Text(parameter.getName()); // set text width to half of the total width of the GUIParameter name.wrappingWidthProperty().bind(widthProperty().divide(2)); - // allow the text to grow to always fill half of the GUIParameter // the tooltip is the hover-over label containing status information, when appropriate tooltip = new Tooltip(); tooltip.setStyle("-fx-background-color: white; -fx-border-color: black; .page-corner {-fx-background-color: transparent;}"); tooltip.setSkin(null); - valueControl = makeControl(); setHgrow(valueControl, Priority.ALWAYS); @@ -99,7 +100,7 @@ public abstract class GUIParameter<T> extends HBox { // if parameter is not a monitor, make sure the control is constrained appropriately if (!parameter.isMonitor()) { - setControlListeners(sp); + setControlListeners(); } getChildren().addAll(name, valueControl); @@ -143,7 +144,7 @@ public abstract class GUIParameter<T> extends HBox { ObservableValue<? extends Object> observable, Object oldValue, Object newValue) { // only do this if the experiment is running - if (GUI.isWorking()) { + if (settingsPane.isExperimentRunning()) { /* 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 @@ -221,11 +222,11 @@ public abstract class GUIParameter<T> extends HBox { * 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. - * - * @param settingsPane the parent Pane on which revalidateParameters() should - * be called. + * <br><br> + * Note that changelisteners registered to the main content property of the + * control should always call handleChange() to update the */ - protected abstract void setControlListeners(SettingsPane settingsPane); + protected abstract void setControlListeners(); /** * This method is called to style the GUIParameter according to the status of diff --git a/src/jcgp/gui/settings/testcase/TestCaseTable.java b/src/jcgp/gui/settings/testcase/TestCaseTable.java new file mode 100644 index 0000000..7e72cbd --- /dev/null +++ b/src/jcgp/gui/settings/testcase/TestCaseTable.java @@ -0,0 +1,90 @@ +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.gui.GUI; + +/** + * Dont forget to override toString()! + * + * + * @author Eduardo Pedroni + * + */ +public class TestCaseTable extends Stage { + + public TestCaseTable(final TestCaseProblem<Object> problem, final GUI gui) { + super(); + + TableView<TestCase<Object>> tv = new TableView<TestCase<Object>>(); + ObservableList<TestCase<Object>> testCaseList = problem.getTestCases(); + + ArrayList<TableColumn<TestCase<Object>, String>> inputs = new ArrayList<TableColumn<TestCase<Object>, String>>(problem.getInputCount()); + ArrayList<TableColumn<TestCase<Object>, String>> outputs = new ArrayList<TableColumn<TestCase<Object>, String>>(problem.getOutputCount()); + + TableColumn<TestCase<Object>, String> tc; + for (int i = 0; i < problem.getInputCount(); 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) { + return new SimpleStringProperty(param.getValue().getInput(index).toString()); + } + }); + tc.setSortable(false); + tc.prefWidthProperty().bind(tv.widthProperty().divide(problem.getInputCount() + problem.getOutputCount())); + } + + for (int o = 0; o < problem.getOutputCount(); 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) { + return new SimpleStringProperty(param.getValue().getOutput(index).toString()); + } + }); + tc.setSortable(false); + tc.prefWidthProperty().bind(tv.widthProperty().divide(problem.getInputCount() + problem.getOutputCount())); + } + + tv.getColumns().addAll(inputs); + tv.getColumns().addAll(outputs); + + tv.setItems(testCaseList); + + tv.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); + } + }); + + setOnCloseRequest(new EventHandler<WindowEvent>() { + @Override + public void handle(WindowEvent event) { + gui.hideGeneValues(); + } + }); + + setScene(new Scene(tv)); + } +} |