From dbae5ce2e0765f229e11b692a2aba570286980f4 Mon Sep 17 00:00:00 2001 From: Eduardo Pedroni Date: Thu, 10 Apr 2014 16:57:30 +0100 Subject: Added manual test case evaluation to GUI --- src/jcgp/gui/population/ChromosomePane.java | 92 ++++++++++++++++++++++----- src/jcgp/gui/population/FunctionSelector.java | 3 +- src/jcgp/gui/population/GUIGene.java | 32 ++++++---- src/jcgp/gui/population/GUIInput.java | 17 ++++- src/jcgp/gui/population/GUINode.java | 48 ++++++++++---- src/jcgp/gui/population/GUIOutput.java | 26 ++++++-- src/jcgp/gui/population/PopulationPane.java | 40 +++++++++--- 7 files changed, 199 insertions(+), 59 deletions(-) (limited to 'src/jcgp/gui/population') diff --git a/src/jcgp/gui/population/ChromosomePane.java b/src/jcgp/gui/population/ChromosomePane.java index 1f67255..0279d09 100644 --- a/src/jcgp/gui/population/ChromosomePane.java +++ b/src/jcgp/gui/population/ChromosomePane.java @@ -10,7 +10,7 @@ import jcgp.backend.population.Connection; import jcgp.backend.population.Input; import jcgp.backend.population.Node; import jcgp.backend.resources.Resources; - +import jcgp.gui.GUI; public class ChromosomePane extends ScrollPane { @@ -21,15 +21,23 @@ public class ChromosomePane extends ScrollPane { private Pane content; private ArrayList connectionLines; - private ArrayList relock = new ArrayList(); - + + private int rows, columns; + private boolean target = false; + private boolean evaluating = false; - public ChromosomePane(Chromosome chromosome, Resources resources) { - super(); + public ChromosomePane(Chromosome chromosome, GUI gui) { + super(); + + final Resources resources = gui.getExperiment().getResources(); + + rows = resources.rows(); + columns = resources.columns(); + connectionLines = new ArrayList(); - + content = new Pane(); content.setId("content pane for genes"); @@ -42,10 +50,10 @@ public class ChromosomePane extends ScrollPane { content.getChildren().addAll(guiInputs[i]); } // nodes - guiNodes = new GUINode[resources.rows()][resources.columns()]; + guiNodes = new GUINode[rows][columns]; double angle, xPos, yPos; - for (int r = 0; r < guiNodes.length; r++) { - for (int c = 0; c < guiNodes[r].length; c++) { + for (int r = 0; r < rows; r++) { + for (int c = 0; c < columns; c++) { // make the connection lines Line lines[] = new Line[resources.arity()]; for (int l = 0; l < lines.length; l++) { @@ -59,7 +67,7 @@ public class ChromosomePane extends ScrollPane { connectionLines.add(lines[l]); } // make the GUI elements - guiNodes[r][c] = new GUINode(this, chromosome.getNode(r, c), lines); + guiNodes[r][c] = new GUINode(this, chromosome.getNode(r, c), lines, gui); } content.getChildren().addAll(guiNodes[r]); } @@ -74,7 +82,7 @@ public class ChromosomePane extends ScrollPane { line.setVisible(false); connectionLines.add(line); // make the GUI elements - guiOutputs[i] = new GUIOutput(this, chromosome.getOutput(i), line); + guiOutputs[i] = new GUIOutput(this, chromosome.getOutput(i), line, gui); content.getChildren().addAll(guiOutputs[i]); } @@ -83,7 +91,7 @@ public class ChromosomePane extends ScrollPane { setContent(content); } - public GUIGene getGuiGene(Connection gene) { + protected GUIGene getGuiGene(Connection gene) { if (gene instanceof Input) { return guiInputs[((Input) gene).getIndex()]; } else if (gene instanceof Node) { @@ -94,24 +102,28 @@ public class ChromosomePane extends ScrollPane { } } - public boolean isTarget() { + protected boolean isTarget() { return target; } - public void setTarget(boolean newValue) { + protected void setTarget(boolean newValue) { target = newValue; } public void updateGenes() { - for (int r = 0; r < guiNodes.length; r++) { - for (int c = 0; c < guiNodes[r].length; c++) { + for (int r = 0; r < rows; r++) { + for (int c = 0; c < columns; c++) { guiNodes[r][c].updateLines(); - guiNodes[r][c].updateFunction(); + guiNodes[r][c].updateText(); } } for (int i = 0; i < guiOutputs.length; i++) { guiOutputs[i].updateLines(); } + if (isEvaluating()) { + evaluate(0); + } + } public void unlockOutputs() { @@ -129,4 +141,50 @@ public class ChromosomePane extends ScrollPane { relock.get(i).lock(); } } + + public void setInputs(Object[] values) { + evaluating = true; + for (int i = 0; i < guiInputs.length; i++) { + guiInputs[i].setValue(values[i]); + guiInputs[i].updateText(); + } + evaluate(0); + } + + public void evaluate(int start) { + if (start >= 0 || start < columns) { + for (int c = start; c < columns; c++) { + for (int r = 0; r < rows; r++) { + guiNodes[r][c].calculate(); + guiNodes[r][c].updateText(); + } + } + for (int o = 0; o < guiOutputs.length; o++) { + guiOutputs[o].calculate(); + guiOutputs[o].updateText(); + } + } + } + + public void hideValues() { + evaluating = false; + for (int i = 0; i < guiInputs.length; i++) { + guiInputs[i].updateText(); + } + for (int c = 0; c < columns; c++) { + for (int r = 0; r < rows; r++) { + guiNodes[r][c].updateText(); + } + } + for (int o = 0; o < guiOutputs.length; o++) { + guiOutputs[o].updateText(); + } + } + + /** + * @return the evaluating + */ + public boolean isEvaluating() { + return evaluating; + } } diff --git a/src/jcgp/gui/population/FunctionSelector.java b/src/jcgp/gui/population/FunctionSelector.java index 0a9606f..28eb54d 100644 --- a/src/jcgp/gui/population/FunctionSelector.java +++ b/src/jcgp/gui/population/FunctionSelector.java @@ -50,8 +50,7 @@ public class FunctionSelector extends VBox { l.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler() { @Override public void handle(MouseEvent event) { - target.getGene().setFunction(fs.getAllowedFunction(index)); - target.updateFunction(); + target.setFunction(fs.getAllowedFunction(index)); dismiss(); } }); diff --git a/src/jcgp/gui/population/GUIGene.java b/src/jcgp/gui/population/GUIGene.java index 6e9d098..5ce839e 100644 --- a/src/jcgp/gui/population/GUIGene.java +++ b/src/jcgp/gui/population/GUIGene.java @@ -10,18 +10,6 @@ import javafx.scene.text.TextAlignment; import jcgp.backend.population.Connection; import jcgp.backend.population.Gene; -enum GUIGeneState { - NEUTRAL, - HOVER, - INDIRECT_HOVER, - ACTIVE_HOVER, - LOCKED_HOVER, - SOURCE, - TARGET, - NO_CHANGE_TARGET, - FORBIDDEN_TARGET -} - public abstract class GUIGene extends Group { public static final double NODE_RADIUS = 30; @@ -32,6 +20,18 @@ public abstract class GUIGene extends Group { public static final double NODE_TEXT = NODE_RADIUS / 2.5; + public enum GUIGeneState { + NEUTRAL, + HOVER, + INDIRECT_HOVER, + ACTIVE_HOVER, + LOCKED_HOVER, + SOURCE, + TARGET, + NO_CHANGE_TARGET, + FORBIDDEN_TARGET + } + protected Text text = new Text(); protected Circle mainCircle = new Circle(NODE_RADIUS, Paint.valueOf("white")); @@ -40,6 +40,8 @@ public abstract class GUIGene extends Group { protected ChromosomePane parent; protected int locked = 0; + + protected Object value; public GUIGene() { text.setFont(Font.font("Arial", 12)); @@ -73,7 +75,7 @@ public abstract class GUIGene extends Group { public abstract void addLocks(int value); /** - * test + * * * @param value */ @@ -93,5 +95,9 @@ public abstract class GUIGene extends Group { public abstract void setConnectionLine(GUIGene gene); + public Object getValue() { + return value; + } + public abstract void updateText(); } diff --git a/src/jcgp/gui/population/GUIInput.java b/src/jcgp/gui/population/GUIInput.java index b4eccaa..6a783db 100644 --- a/src/jcgp/gui/population/GUIInput.java +++ b/src/jcgp/gui/population/GUIInput.java @@ -23,8 +23,7 @@ public class GUIInput extends GUIGene { relocate(NODE_RADIUS, (input.getIndex() * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS); - text.setText("I: " + input.getIndex()); - + updateText(); Circle outputSocket = new Circle(NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); outputSocket.setId(String.valueOf(0)); @@ -232,5 +231,19 @@ public class GUIInput extends GUIGene { @Override public void setConnectionLine(GUIGene gene) { // nothing + } + + public void setValue(Object newValue) { + value = newValue; + input.setValue(newValue); + } + + @Override + public void updateText() { + if (parent.isEvaluating()) { + text.setText("I: " + input.getIndex() + "\nValue: " + value.toString()); + } else { + text.setText("I: " + input.getIndex()); + } } } diff --git a/src/jcgp/gui/population/GUINode.java b/src/jcgp/gui/population/GUINode.java index 8e2d8a0..2b953c0 100644 --- a/src/jcgp/gui/population/GUINode.java +++ b/src/jcgp/gui/population/GUINode.java @@ -7,24 +7,29 @@ import javafx.scene.input.MouseEvent; import javafx.scene.paint.Paint; import javafx.scene.shape.Circle; import javafx.scene.shape.Line; +import jcgp.backend.function.Function; import jcgp.backend.population.Connection; import jcgp.backend.population.Input; import jcgp.backend.population.Node; +import jcgp.backend.resources.Resources; import jcgp.gui.GUI; public class GUINode extends GUIGene { private Line[] lines; private Node node; + private Resources resources; private int connectionIndex = 0; + - public GUINode(ChromosomePane parentRef, final Node node, Line[] connectionLines) { + public GUINode(ChromosomePane parentRef, final Node node, Line[] connectionLines, final GUI gui) { super(); // store references this.parent = parentRef; this.node = node; this.lines = connectionLines; + this.resources = gui.getExperiment().getResources(); // move the GUIGene to the right position relocate(((node.getColumn() + 1) * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS, @@ -40,12 +45,12 @@ public class GUINode extends GUIGene { Circle output = new Circle(NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); output.setStroke(Paint.valueOf("black")); - text.setText(node.getFunction().getName()); + updateText(); - Circle[] sockets = new Circle[GUI.resources.arity()]; + Circle[] sockets = new Circle[resources.arity()]; double angle, xPos, yPos; for (int l = 0; l < sockets.length; l++) { - angle = (((l + 1) / ((double) (GUI.resources.arity() + 1))) * THETA) - (THETA / 2); + angle = (((l + 1) / ((double) (resources.arity() + 1))) * THETA) - (THETA / 2); xPos = -Math.cos(angle) * NODE_RADIUS; yPos = Math.sin(angle) * NODE_RADIUS; @@ -128,7 +133,7 @@ public class GUINode extends GUIGene { addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler() { @Override public void handle(MouseEvent event) { - GUI.functionSelector.relocateAndShow(event, (GUINode) event.getSource()); + gui.bringFunctionSelector(event, (GUINode) event.getSource()); } }); @@ -189,17 +194,16 @@ public class GUINode extends GUIGene { // the user released the drag gesture on this node, react appropriately if (isAllowed((GUIGene) event.getGestureSource(), (GUIGene) event.getSource())) { if (source.isLocked()) { - // remove locks from the old connection, add the to the new + // remove locks from the old connection, add the to setConnethe new // note that the old connection may still have locks after this parent.getGuiGene(source.getChangingConnection()).removeLocks(source.getLocks()); - source.setChangingConnection(node); addLocks(source.getLocks()); } else { if (source instanceof GUIOutput) { source.resetState(); } - source.setChangingConnection(node); } + source.setChangingConnection(node); } source.updateLines(); @@ -316,7 +320,7 @@ public class GUINode extends GUIGene { } else if (target instanceof GUINode) { // target and source are nodes, let's look at levels back Node t = ((GUINode) target).getGene(), s = ((GUINode) source).getGene(); - if (s.getColumn() - t.getColumn() > 0 && s.getColumn() - t.getColumn() <= GUI.resources.levelsBack()) { + if (s.getColumn() - t.getColumn() > 0 && s.getColumn() - t.getColumn() <= resources.levelsBack()) { return true; } return false; @@ -395,6 +399,9 @@ public class GUINode extends GUIGene { @Override public void setChangingConnection(Connection newConnection) { node.setConnection(connectionIndex, newConnection); + if (parent.isEvaluating()) { + parent.evaluate(node.getColumn()); + } } @@ -445,7 +452,26 @@ public class GUINode extends GUIGene { lines[connectionIndex].setEndY(gene.getLayoutY()); } - public void updateFunction() { - text.setText(node.getFunction().getName()); + public void updateText() { + if (parent.isEvaluating()) { + text.setText(node.getFunction().getName() + "\nValue: " + value.toString()); + } else { + text.setText(node.getFunction().getName()); + } + } + + public void calculate() { + value = node.getValue(); + } + + public void setFunction(Function function) { + node.setFunction(function); + if (parent.isEvaluating()) { + calculate(); + parent.evaluate(node.getColumn()); + } else { + updateText(); + } + } } diff --git a/src/jcgp/gui/population/GUIOutput.java b/src/jcgp/gui/population/GUIOutput.java index c5b889e..89c12b3 100644 --- a/src/jcgp/gui/population/GUIOutput.java +++ b/src/jcgp/gui/population/GUIOutput.java @@ -16,23 +16,21 @@ import jcgp.gui.GUI; public class GUIOutput extends GUIGene { private Line sourceLine; - private Output output; - public GUIOutput(ChromosomePane parentRef, final Output output, Line line) { + public GUIOutput(ChromosomePane parentRef, final Output output, Line line, GUI gui) { super(); this.parent = parentRef; this.output = output; this.sourceLine = line; - relocate(((GUI.resources.columns() + 1) * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS, + relocate(((gui.getExperiment().getResources().columns() + 1) * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS, (output.getIndex() * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS); // set the line ends correctly updateLines(); - - text.setText("O: " + output.getIndex()); + updateText(); Circle socket = new Circle(-NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); socket.setId(String.valueOf(0)); @@ -274,6 +272,10 @@ public class GUIOutput extends GUIGene { @Override public void setChangingConnection(Connection newConnection) { output.setConnection(0, newConnection); + if (parent.isEvaluating()) { + calculate(); + updateText(); + } } @Override @@ -311,5 +313,19 @@ public class GUIOutput extends GUIGene { setLocked(true); } } + + public void calculate() { + value = output.getSource().getValue(); + } + + @Override + public void updateText() { + if (parent.isEvaluating()) { + text.setText("O: " + output.getIndex() + "\nValue: " + value.toString()); + } else { + text.setText("O: " + output.getIndex()); + } + + } } diff --git a/src/jcgp/gui/population/PopulationPane.java b/src/jcgp/gui/population/PopulationPane.java index 5232eb5..64b61c4 100644 --- a/src/jcgp/gui/population/PopulationPane.java +++ b/src/jcgp/gui/population/PopulationPane.java @@ -3,26 +3,29 @@ package jcgp.gui.population; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import jcgp.JCGP; -import jcgp.backend.population.Population; -import jcgp.backend.resources.Resources; +import jcgp.backend.modules.problem.TestCaseProblem; +import jcgp.backend.modules.problem.TestCaseProblem.TestCase; +import jcgp.gui.GUI; public class PopulationPane extends TabPane { - public PopulationPane(JCGP jcgp) { + private GUI gui; + + public PopulationPane(GUI gui) { super(); - + this.gui = gui; setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE); - - remakeTabs(jcgp.getPopulation(), jcgp.getResources()); + remakeTabs(); } - public void remakeTabs(Population population, Resources resources) { + public void remakeTabs() { getTabs().clear(); + JCGP jcgp = gui.getExperiment(); Tab tab; ChromosomePane cp; - for (int i = 0; i < resources.populationSize(); i++) { - cp = new ChromosomePane(population.getChromosome(i), resources); + for (int i = 0; i < jcgp.getResources().populationSize(); i++) { + cp = new ChromosomePane(jcgp.getPopulation().getChromosome(i), gui); tab = new Tab("Chr " + i); tab.setContent(cp); getTabs().add(tab); @@ -46,4 +49,23 @@ public class PopulationPane extends TabPane { ((ChromosomePane) getTabs().get(i).getContent()).relockOutputs(); } } + + public void evaluateTestCase(TestCase testCase) { + if (gui.getExperiment().getProblem() instanceof TestCaseProblem) { + if (testCase.getInputs().length == gui.getExperiment().getResources().inputs()) { + for (int i = 0; i < getTabs().size(); i++) { + ((ChromosomePane) getTabs().get(i).getContent()).setInputs(testCase.getInputs()); + } + } else { + throw new IllegalArgumentException("Test case has " + testCase.getInputs().length + + " inputs and chromosome has " + gui.getExperiment().getResources().inputs()); + } + } + } + + public void hideValues() { + for (int i = 0; i < getTabs().size(); i++) { + ((ChromosomePane) getTabs().get(i).getContent()).hideValues(); + } + } } -- cgit v1.2.3