diff options
author | Eduardo Pedroni <e.pedroni91@gmail.com> | 2014-11-15 19:16:25 +0000 |
---|---|---|
committer | Eduardo Pedroni <e.pedroni91@gmail.com> | 2014-11-15 19:16:25 +0000 |
commit | 12ebe6f6375e7db31ba1bb2eba5e3b28b51c7a19 (patch) | |
tree | e4ed8c2617550db031d8cf94cdc52d71ac972cab /src/jcgp/gui/population | |
parent | d0aca8c4035a59bdb562650a4a8d6efbcf55f2ca (diff) |
Added GUIHandlers file for extracted handlers, started removing parent class references from genes
Diffstat (limited to 'src/jcgp/gui/population')
-rw-r--r-- | src/jcgp/gui/population/ChromosomePane.java | 127 | ||||
-rw-r--r-- | src/jcgp/gui/population/FunctionSelector.java | 2 | ||||
-rw-r--r-- | src/jcgp/gui/population/GUIGene.java | 81 | ||||
-rw-r--r-- | src/jcgp/gui/population/GUIInput.java | 229 | ||||
-rw-r--r-- | src/jcgp/gui/population/GUINode.java | 450 | ||||
-rw-r--r-- | src/jcgp/gui/population/GUIOutput.java | 307 | ||||
-rw-r--r-- | src/jcgp/gui/population/PopulationPane.java | 16 |
7 files changed, 101 insertions, 1111 deletions
diff --git a/src/jcgp/gui/population/ChromosomePane.java b/src/jcgp/gui/population/ChromosomePane.java index 3546011..f09d452 100644 --- a/src/jcgp/gui/population/ChromosomePane.java +++ b/src/jcgp/gui/population/ChromosomePane.java @@ -1,10 +1,7 @@ package jcgp.gui.population; -import java.util.ArrayList; - import javafx.scene.control.ScrollPane; import javafx.scene.layout.Pane; -import javafx.scene.shape.Line; import jcgp.backend.population.Chromosome; import jcgp.backend.population.Connection; import jcgp.backend.population.Input; @@ -12,6 +9,7 @@ import jcgp.backend.population.Node; import jcgp.backend.resources.Resources; import jcgp.gui.GUI; import jcgp.gui.constants.Constants; +import jcgp.gui.handlers.GUIHandlers; /** * This extension of {@code ScrollPane} contains a series of @@ -30,27 +28,18 @@ public class ChromosomePane extends ScrollPane { private Pane content; - private ArrayList<Line> connectionLines; - private ArrayList<GUIOutput> relock = new ArrayList<GUIOutput>(); - private int rows, columns; - private Object[] testInputs; - private boolean target = false; - private PopulationPane parent; public ChromosomePane(Chromosome chromosome, GUI gui, PopulationPane parent) { super(); final Resources resources = gui.getExperiment().getResources(); - this.parent = parent; rows = resources.rows(); columns = resources.columns(); - connectionLines = new ArrayList<Line>(); - content = new Pane(); content.setId("content pane for genes"); @@ -59,47 +48,35 @@ public class ChromosomePane extends ScrollPane { guiInputs = new GUIInput[resources.inputs()]; for (int i = 0; i < guiInputs.length; i++) { // make the GUI elements - guiInputs[i] = new GUIInput(this, chromosome.getInput(i)); - content.getChildren().addAll(guiInputs[i]); + guiInputs[i] = new GUIInput(chromosome.getInput(i)); + guiInputs[i].relocate(Constants.NODE_RADIUS, + (chromosome.getInput(i).getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); + GUIHandlers.addHandlers(guiInputs[i]); } + content.getChildren().addAll(guiInputs); // nodes guiNodes = new GUINode[rows][columns]; - double angle, xPos, yPos; 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++) { - angle = ((((double) (l + 1)) / ((double) (lines.length + 1))) * Constants.THETA) - (Constants.THETA / 2); - xPos = (-Math.cos(angle) * Constants.NODE_RADIUS) + (((c + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); - yPos = (Math.sin(angle) * Constants.NODE_RADIUS) + ((r * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); - - lines[l] = new Line(xPos, yPos, xPos, yPos); - lines[l].setMouseTransparent(true); - lines[l].setVisible(false); - connectionLines.add(lines[l]); - } // make the GUI elements - guiNodes[r][c] = new GUINode(this, chromosome.getNode(r, c), lines, gui); + guiNodes[r][c] = new GUINode(chromosome.getNode(r, c)); + guiNodes[r][c].relocate(((chromosome.getNode(r, c).getColumn() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS, + (chromosome.getNode(r, c).getRow() * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); + GUIHandlers.addHandlers(guiNodes[r][c]); } content.getChildren().addAll(guiNodes[r]); } // outputs guiOutputs = new GUIOutput[resources.outputs()]; for (int i = 0; i < guiOutputs.length; i++) { - xPos = ((resources.columns() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)); - yPos = (chromosome.getOutput(i).getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS; - // make the line - Line line = new Line(xPos, yPos, xPos, yPos); - line.setMouseTransparent(true); - line.setVisible(false); - connectionLines.add(line); // make the GUI elements - guiOutputs[i] = new GUIOutput(this, chromosome.getOutput(i), line, gui); - content.getChildren().addAll(guiOutputs[i]); + guiOutputs[i] = new GUIOutput(chromosome.getOutput(i)); + guiOutputs[i].relocate(((resources.columns() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS, + (chromosome.getOutput(i).getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); + GUIHandlers.addHandlers(guiOutputs[i]); } + content.getChildren().addAll(guiOutputs); - content.getChildren().addAll(connectionLines); setPrefWidth(620); setContent(content); } @@ -127,61 +104,41 @@ public class ChromosomePane extends ScrollPane { for (int r = 0; r < rows; r++) { for (int c = 0; c < columns; c++) { guiNodes[r][c].setNode(chr.getNode(r, c)); - guiNodes[r][c].updateLines(); - guiNodes[r][c].updateText(); } } for (int i = 0; i < guiOutputs.length; i++) { guiOutputs[i].setOutput(chr.getOutput(i)); - guiOutputs[i].updateLines(); - } - if (isEvaluating()) { - setInputs(testInputs); - } - } - - public void unlockOutputs() { - relock.clear(); - for (int i = 0; i < guiOutputs.length; i++) { - if (guiOutputs[i].isLocked()) { - guiOutputs[i].unlock(); - relock.add(guiOutputs[i]); - } - } - } - - public void relockOutputs() { - for (int i = 0; i < relock.size(); i++) { - relock.get(i).lock(); } } - public void setInputs(Object[] values) { - testInputs = values; - for (int i = 0; i < guiInputs.length; i++) { - guiInputs[i].setValue(values[i]); - } - updateValues(); - } - - public void updateValues() { - 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(); + public static boolean isAllowed(GUIGene source, GUIGene target) { + if (source instanceof GUINode) { + // if the source is a node, all inputs and some nodes are valid + if (target instanceof GUIInput) { + return true; + } else if (target instanceof GUINode) { + // target and source are nodes, let's look at levels back + Node t = ((GUINode) target).getNode(), s = ((GUINode) source).getNode(); + if (s.getColumn() - t.getColumn() > 0 && s.getColumn() - t.getColumn() <= 1 /* TODO this should be levels back */) { + return true; + } + return false; + } else if (target instanceof GUIOutput) { + return false; + } else { + throw new ClassCastException("Target was neither GUINode nor GUIInput nor GUIOutput."); + } + } else if (source instanceof GUIOutput) { + // if the source is an output, any node or input is valid + if (target instanceof GUINode || target instanceof GUIInput) { + return true; + } else if (target instanceof GUIOutput) { + return false; + } else { + throw new ClassCastException("Target was neither GUINode nor GUIInput nor GUIOutput."); } } - for (int o = 0; o < guiOutputs.length; o++) { - guiOutputs[o].updateText(); - } - } - - /** - * @return the evaluating attribute. - */ - public boolean isEvaluating() { - return parent.isEvaluating(); + // if the source was neither node nor output, something bad is happening + throw new ClassCastException("Source was neither GUINode nor GUIOutput."); } } diff --git a/src/jcgp/gui/population/FunctionSelector.java b/src/jcgp/gui/population/FunctionSelector.java index ac7a2c2..d96617c 100644 --- a/src/jcgp/gui/population/FunctionSelector.java +++ b/src/jcgp/gui/population/FunctionSelector.java @@ -58,7 +58,7 @@ public class FunctionSelector extends VBox { l.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { - target.setFunction(fs.getAllowedFunction(index)); + //target.setFunction(fs.getAllowedFunction(index)); dismiss(); } }); diff --git a/src/jcgp/gui/population/GUIGene.java b/src/jcgp/gui/population/GUIGene.java index bae7647..eb7070c 100644 --- a/src/jcgp/gui/population/GUIGene.java +++ b/src/jcgp/gui/population/GUIGene.java @@ -7,33 +7,27 @@ import javafx.scene.shape.Circle; import javafx.scene.text.Font; import javafx.scene.text.Text; import javafx.scene.text.TextAlignment; -import jcgp.backend.population.Connection; import jcgp.gui.constants.Constants; +/** + * Defines the general behaviour of the visual representation of each chromosome gene. + * <br><br> + * In practice, this is subclass of {@code javafx.scene.Group} containing a {@code Circle} + * object and a {@code Text} object. Subclasses may add further elements to the group, for + * instance to display connection input and output sockets. + * + * @author Eduardo Pedroni + * + */ public abstract class GUIGene extends Group { - public enum GUIGeneState { - NEUTRAL, - HOVER, - INDIRECT_HOVER, - ACTIVE_HOVER, - LOCKED_HOVER, - SOURCE, - VALID_TARGET, - NO_CHANGE_TARGET, - INVALID_TARGET - } - - protected Text text = new Text(); - protected Circle mainCircle = new Circle(Constants.NODE_RADIUS, Paint.valueOf("white")); + private Text text = new Text(); + protected final Circle mainCircle = new Circle(Constants.NODE_RADIUS, Paint.valueOf(Constants.NEUTRAL_COLOUR)); - private GUIGeneState state = GUIGeneState.NEUTRAL; - - protected ChromosomePane parent; - - protected int locked = 0; - - public GUIGene() { + /** + * Initialises the {@code Text} and {@code Circle} objects so that all genes are standardised. + */ + protected GUIGene() { text.setFont(Font.font("Arial", 12)); text.setTextOrigin(VPos.CENTER); text.setTextAlignment(TextAlignment.CENTER); @@ -42,41 +36,20 @@ public abstract class GUIGene extends Group { text.setVisible(true); mainCircle.setStroke(Paint.valueOf("black")); + + getChildren().addAll(mainCircle, text); } - public void setState(GUIGeneState newState) { - state = newState; - } - - public GUIGeneState getState() { - return state; - } - - public boolean isLocked() { - return locked > 0; - } - - public int getLocks() { - return locked; + /** + * Sets the gene's text field. + * + * @param newText the text string to be displayed. + */ + public void setText(String newText) { + text.setText(newText); } - protected abstract void setLocked(boolean value); - - public abstract void addLocks(int value); - - public abstract void removeLocks(int value); - - public abstract void updateLines(); - - public abstract void setChangingConnection(Connection newConnection); - - public abstract Connection getChangingConnection(); - - public abstract void setConnectionStates(GUIGeneState newState); - - public abstract void resetState(); - - public abstract void setConnectionLine(GUIGene gene); + public abstract void mouseEnter(); + public abstract void mouseExit(); - public abstract void updateText(); } diff --git a/src/jcgp/gui/population/GUIInput.java b/src/jcgp/gui/population/GUIInput.java index 8b55a58..d29851e 100644 --- a/src/jcgp/gui/population/GUIInput.java +++ b/src/jcgp/gui/population/GUIInput.java @@ -1,233 +1,32 @@ package jcgp.gui.population; -import javafx.event.EventHandler; -import javafx.scene.input.MouseDragEvent; -import javafx.scene.input.MouseEvent; import javafx.scene.paint.Paint; -import javafx.scene.shape.Circle; -import jcgp.backend.population.Connection; import jcgp.backend.population.Input; import jcgp.gui.constants.Constants; +/** + * + * + * @author Eduardo Pedroni + * + */ public class GUIInput extends GUIGene { - private Input input; - - public GUIInput(ChromosomePane parentRef, final Input input) { - super(); - - this.parent = parentRef; - this.input = input; - - relocate(Constants.NODE_RADIUS, - (input.getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); - - updateText(); - - Circle outputSocket = new Circle(Constants.NODE_RADIUS, 0, Constants.SOCKET_RADIUS, Paint.valueOf("white")); - outputSocket.setId(String.valueOf(0)); - outputSocket.setStroke(Paint.valueOf("black")); - - getChildren().addAll(mainCircle, text, outputSocket); - - /* - * Mouse event handlers on whole gene - */ - addEventFilter(MouseDragEvent.MOUSE_DRAG_ENTERED, new EventHandler<MouseDragEvent>() { - @Override - public void handle(MouseDragEvent event) { - // the drag has entered this node, react appropriately - // this happens even if we are the source of the drag - ((GUIGene) event.getGestureSource()).setConnectionLine((GUIGene) event.getSource()); - Connection source = ((GUIGene) event.getGestureSource()).getChangingConnection(); - if (input == source) { - setState(GUIGeneState.NO_CHANGE_TARGET); - } else { - setState(GUIGeneState.VALID_TARGET); - } - } - }); - - addEventFilter(MouseDragEvent.MOUSE_DRAG_EXITED, new EventHandler<MouseDragEvent>() { - @Override - public void handle(MouseDragEvent event) { - // the drag has exited this node, react appropriately - // this happens even if we are the source of the drag - parent.setTarget(false); - if (event.isPrimaryButtonDown()) { - if (getState() == GUIGeneState.NO_CHANGE_TARGET) { - setState(GUIGeneState.INDIRECT_HOVER); - } else { - setState(GUIGeneState.NEUTRAL); - ((GUIGene) event.getGestureSource()).setConnectionStates(GUIGeneState.INDIRECT_HOVER); - } - } - } - - }); - - addEventFilter(MouseDragEvent.MOUSE_DRAG_RELEASED, new EventHandler<MouseDragEvent>() { - @Override - public void handle(MouseDragEvent event) { - GUIGene source = ((GUIGene) event.getGestureSource()); - // set states to reflect the new situation - if (source.isLocked()) { - source.setState(GUIGeneState.HOVER); - source.setConnectionStates(GUIGeneState.HOVER); - } else { - source.setState(GUIGeneState.NEUTRAL); - source.setConnectionStates(GUIGeneState.NEUTRAL); - } - - // the user released the drag gesture on this node, react appropriately - if (source.isLocked()) { - // remove locks from the old connection, add the to the new - // note that the old connection may still have locks after this - parent.getGuiGene(source.getChangingConnection()).removeLocks(source.getLocks()); - source.setChangingConnection(input); - addLocks(source.getLocks()); - } else { - source.setChangingConnection(input); - } - - source.updateLines(); - setState(GUIGeneState.HOVER); - } - }); - - addEventFilter(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // cursor has entered this node without dragging, or it is dragging and this is the source - if (getState() == GUIGeneState.NEUTRAL) { - setState(GUIGeneState.HOVER); - } - } - }); - - addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // cursor has left this node without dragging, or it is dragging and this is the source - if (getState() == GUIGeneState.HOVER) { - setState(GUIGeneState.NEUTRAL); - setConnectionStates(GUIGeneState.NEUTRAL); - } - } - }); - } - - @Override - public void setState(GUIGeneState newState) { - super.setState(newState); - - switch (newState) { - case ACTIVE_HOVER: - if (locked > 0) { - setState(GUIGeneState.LOCKED_HOVER); - } else { - mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); - } - break; - case INVALID_TARGET: - mainCircle.setFill(Paint.valueOf(Constants.BAD_SELECTION_COLOUR)); - break; - case LOCKED_HOVER: - mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); - break; - case HOVER: - mainCircle.setFill(Paint.valueOf(Constants.MEDIUM_HIGHLIGHT_COLOUR)); - break; - case INDIRECT_HOVER: - mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); - break; - case NEUTRAL: - if (locked > 0) { - setState(GUIGeneState.HOVER); - } else { - mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_COLOUR)); - } - break; - case NO_CHANGE_TARGET: - parent.setTarget(true); - mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_SELECTION_COLOUR)); - break; - case SOURCE: - mainCircle.setFill(Paint.valueOf(Constants.MEDIUM_HIGHLIGHT_COLOUR)); - break; - case VALID_TARGET: - parent.setTarget(true); - mainCircle.setFill(Paint.valueOf(Constants.GOOD_SELECTION_COLOUR)); - break; - default: - break; - } - - } - /** - * Set all connections to a given state. - * - * @param newState the state to set connections to. + * @param input */ - @Override - public void setConnectionStates(GUIGeneState newState) { - // nothing - } - - @Override - public void resetState() { - setState(GUIGeneState.NEUTRAL); - } - - @Override - protected void setLocked(boolean value) { - locked += value ? 1 : -1; - setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); - } - - @Override - public void setChangingConnection(Connection newConnection) { - // do nothing - } - - @Override - public Connection getChangingConnection() { - return null; - } - - @Override - public void addLocks(int value) { - locked += value; - setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); - } - - @Override - public void updateLines() { - // nothing + public GUIInput(final Input input) { + super(); } @Override - public void removeLocks(int value) { - locked -= value; - setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.NEUTRAL); + public void mouseEnter() { + mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); } @Override - public void setConnectionLine(GUIGene gene) { - // nothing + public void mouseExit() { + mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_COLOUR)); } - - public void setValue(Object newValue) { - input.setValue(newValue); - } - - @Override - public void updateText() { - if (parent.isEvaluating()) { - text.setText("I: " + input.getIndex() + "\n" + input.getValue().toString()); - } else { - text.setText("I: " + input.getIndex()); - } - } + } diff --git a/src/jcgp/gui/population/GUINode.java b/src/jcgp/gui/population/GUINode.java index 4d420ea..7b59162 100644 --- a/src/jcgp/gui/population/GUINode.java +++ b/src/jcgp/gui/population/GUINode.java @@ -1,472 +1,38 @@ package jcgp.gui.population; -import javafx.event.EventHandler; -import javafx.scene.control.Label; -import javafx.scene.input.MouseDragEvent; -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; import jcgp.gui.constants.Constants; 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, final GUI gui) { + public GUINode(final Node node) { 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 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS, - (node.getRow() * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); - - // set the line ends correctly - updateLines(); - - final Label connectionNumber = new Label(); - connectionNumber.setStyle("-fx-background-color:rgb(255, 255, 255); -fx-border-color:rgba(0, 0, 0, 0.5); "); - connectionNumber.setVisible(false); - - Circle output = new Circle(Constants.NODE_RADIUS, 0, Constants.SOCKET_RADIUS, Paint.valueOf("white")); - output.setStroke(Paint.valueOf("black")); - - updateText(); - - Circle[] sockets = new Circle[resources.arity()]; - double angle, xPos, yPos; - for (int l = 0; l < sockets.length; l++) { - angle = (((l + 1) / ((double) (resources.arity() + 1))) * Constants.THETA) - (Constants.THETA / 2); - xPos = -Math.cos(angle) * Constants.NODE_RADIUS; - yPos = Math.sin(angle) * Constants.NODE_RADIUS; - - sockets[l] = new Circle(xPos, yPos, Constants.SOCKET_RADIUS, Paint.valueOf("white")); - sockets[l].setId(String.valueOf(l)); - sockets[l].setStroke(Paint.valueOf("black")); - - final Circle s = sockets[l]; - final int index = l; - - /* - * Mouse event handlers on sockets - * - */ - s.addEventFilter(MouseEvent.DRAG_DETECTED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // the mouse has been dragged out of the socket, this means a full drag is in progress - startFullDrag(); - } - }); - - s.addEventFilter(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // user is hovering over connection socket - connectionNumber.setText("C: " + s.getId()); - connectionNumber.relocate(s.getCenterX() + 5, s.getCenterY() - 10); - connectionNumber.setVisible(true); - } - }); - - s.addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // user exits the connection socket - connectionNumber.setVisible(false); - } - }); - - s.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // mouse was pressed on the socket - setState(GUIGeneState.SOURCE); - connectionIndex = index; - } - }); - - s.addEventFilter(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - if (!parent.isTarget()) { - lines[connectionIndex].setEndX(event.getX() + ((Circle) event.getSource()).getParent().getLayoutX()); - lines[connectionIndex].setEndY(event.getY() + ((Circle) event.getSource()).getParent().getLayoutY()); - } - } - }); - - s.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - if (event.isStillSincePress()) { - // mouse was released before dragging out of the socket - updateLine(index); - setState(GUIGeneState.HOVER); - } else if (getState() == GUIGeneState.SOURCE) { - // no connection has been made, fallback - resetState(); - updateLines(); - } - } - }); - } - - /* - * Mouse event handlers on whole gene - */ - addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - gui.bringFunctionSelector(event, (GUINode) event.getSource()); - } - }); - - addEventFilter(MouseDragEvent.MOUSE_DRAG_ENTERED, new EventHandler<MouseDragEvent>() { - @Override - public void handle(MouseDragEvent event) { - // the drag has entered this node, react appropriately - // this happens even if we are the source of the drag - if (isAllowed((GUIGene) event.getGestureSource(), (GUIGene) event.getSource())) { - ((GUIGene) event.getGestureSource()).setConnectionLine((GUIGene) event.getSource()); - - Connection source = ((GUIGene) event.getGestureSource()).getChangingConnection(); - if (node == source) { - setState(GUIGeneState.NO_CHANGE_TARGET); - } else { - setState(GUIGeneState.VALID_TARGET); - } - } else { - setState(GUIGeneState.INVALID_TARGET); - } - } - }); - - addEventFilter(MouseDragEvent.MOUSE_DRAG_EXITED, new EventHandler<MouseDragEvent>() { - @Override - public void handle(MouseDragEvent event) { - // the drag has exited this node, react appropriately - // this happens even if we are the source of the drag - parent.setTarget(false); - if (event.isPrimaryButtonDown()) { - if (event.getGestureSource() == event.getSource()) { - setState(GUIGeneState.SOURCE); - } else { - if (getState() == GUIGeneState.NO_CHANGE_TARGET) { - setState(GUIGeneState.INDIRECT_HOVER); - } else { - setState(GUIGeneState.NEUTRAL); - ((GUIGene) event.getGestureSource()).setConnectionStates(GUIGeneState.INDIRECT_HOVER); - } - } - } - } - }); - - addEventFilter(MouseDragEvent.MOUSE_DRAG_RELEASED, new EventHandler<MouseDragEvent>() { - @Override - public void handle(MouseDragEvent event) { - GUIGene source = ((GUIGene) event.getGestureSource()); - // set states to reflect the new situation - if (source.isLocked()) { - source.setState(GUIGeneState.HOVER); - source.setConnectionStates(GUIGeneState.HOVER); - } else { - source.setState(GUIGeneState.NEUTRAL); - source.setConnectionStates(GUIGeneState.NEUTRAL); - } - - // 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 setConnethe new - // note that the old connection may still have locks after this - parent.getGuiGene(source.getChangingConnection()).removeLocks(source.getLocks()); - addLocks(source.getLocks()); - } else { - if (source instanceof GUIOutput) { - source.resetState(); - } - } - source.setChangingConnection(node); - - } - source.updateLines(); - setState(GUIGeneState.HOVER); - } - }); - - addEventFilter(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // cursor has entered this node without dragging, or it is dragging and this is the source - if (getState() == GUIGeneState.NEUTRAL) { - setState(GUIGeneState.HOVER); - } else if (locked > 0) { - setConnectionStates(GUIGeneState.LOCKED_HOVER); - } - } - }); - - addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // cursor has left this node without dragging, or it is dragging and this is the source - if (getState() == GUIGeneState.HOVER && locked <= 0) { - setState(GUIGeneState.NEUTRAL); - setConnectionStates(GUIGeneState.NEUTRAL); - } else if (locked > 0) { - if (getState() == GUIGeneState.SOURCE || getState() == GUIGeneState.INVALID_TARGET) { - setConnectionStates(GUIGeneState.INDIRECT_HOVER); - } else { - setConnectionStates(GUIGeneState.HOVER); - } - - } - } - }); - - getChildren().addAll(mainCircle, text); - getChildren().addAll(sockets); - getChildren().addAll(output, connectionNumber); - - } - - @Override - public void setState(GUIGeneState newState) { - switch (newState) { - case ACTIVE_HOVER: - if (locked > 0) { - setState(GUIGeneState.LOCKED_HOVER); - } else { - mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); - showLines(true); - } - setConnectionStates(GUIGeneState.ACTIVE_HOVER); - break; - case LOCKED_HOVER: - mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); - break; - case INVALID_TARGET: - mainCircle.setFill(Paint.valueOf(Constants.BAD_SELECTION_COLOUR)); - break; - case HOVER: - mainCircle.setFill(Paint.valueOf(Constants.MEDIUM_HIGHLIGHT_COLOUR)); - showLines(true); - if (locked <= 0) { - setConnectionStates(GUIGeneState.INDIRECT_HOVER); - } else { - setConnectionStates(GUIGeneState.HOVER); - } - break; - case INDIRECT_HOVER: - mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); - break; - case NEUTRAL: - if (locked > 0) { - setState(GUIGeneState.HOVER); - } else { - mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_COLOUR)); - showLines(false); - if (getState() == GUIGeneState.ACTIVE_HOVER) { - setConnectionStates(GUIGeneState.NEUTRAL); - } - } - break; - case NO_CHANGE_TARGET: - parent.setTarget(true); - mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_SELECTION_COLOUR)); - break; - case SOURCE: - mainCircle.setFill(Paint.valueOf(Constants.HARD_HIGHLIGHT_COLOUR)); - break; - case VALID_TARGET: - parent.setTarget(true); - mainCircle.setFill(Paint.valueOf(Constants.GOOD_SELECTION_COLOUR)); - break; - default: - break; - } - - super.setState(newState); } - @Override - public Connection getChangingConnection() { - return node.getConnection(connectionIndex); - } - - private boolean isAllowed(GUIGene source, GUIGene target) { - if (source instanceof GUINode) { - // if the source is a node, all inputs and some nodes are valid - if (target instanceof GUIInput) { - return true; - } else if (target instanceof GUINode) { - // target and source are nodes, let's look at levels back - Node t = ((GUINode) target).getNode(), s = ((GUINode) source).getNode(); - if (s.getColumn() - t.getColumn() > 0 && s.getColumn() - t.getColumn() <= resources.levelsBack()) { - return true; - } - return false; - } else if (target instanceof GUIOutput) { - return false; - } else { - throw new ClassCastException("Target was neither GUINode nor GUIInput nor GUIOutput."); - } - } else if (source instanceof GUIOutput) { - // if the source is an output, any node or input is valid - if (target instanceof GUINode || target instanceof GUIInput) { - return true; - } else if (target instanceof GUIOutput) { - return false; - } else { - throw new ClassCastException("Target was neither GUINode nor GUIInput nor GUIOutput."); - } - } - // if the source was neither node nor output, something bad is happening - throw new ClassCastException("Source was neither GUINode nor GUIOutput."); - } - - public Node getNode() { return node; } - /** - * Place the end of the specified line on the output of the associated connection. - * - * @param index the line to be updated. - */ - public void updateLine(int index) { - if (node.getConnection(index) instanceof Node) { - int row = ((Node) node.getConnection(index)).getRow(), - column = ((Node) node.getConnection(index)).getColumn(); - lines[index].setEndX(((column + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + 2 * Constants.NODE_RADIUS); - lines[index].setEndY((row * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); - } else if (node.getConnection(index) instanceof Input) { - int inputIndex = ((Input) node.getConnection(index)).getIndex(); - lines[index].setEndX(2 * Constants.NODE_RADIUS); - lines[index].setEndY(inputIndex * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.NODE_RADIUS); - } - } - - /** - * Updates the end of all lines to match the associated connections. - */ - @Override - public void updateLines() { - for (int c = 0; c < lines.length; c++) { - updateLine(c); - } - } - - /** - * Toggle visibility of all connection lines. - * - * @param value whether to show the lines or not. - */ - private void showLines(boolean value) { - for (int i = 0; i < lines.length; i++) { - lines[i].setVisible(value); - } - } - - @Override - public void setConnectionStates(GUIGeneState newState) { - for (int i = 0; i < lines.length; i++) { - parent.getGuiGene(node.getConnection(i)).setState(newState); - } - } - - @Override - public void setChangingConnection(Connection newConnection) { - node.setConnection(connectionIndex, newConnection); - if (parent.isEvaluating()) { - parent.updateValues(); - } - } - - - @Override - public void resetState() { - if (locked > 0) { - setState(GUIGeneState.HOVER); - } else { - setState(GUIGeneState.NEUTRAL); - setConnectionStates(GUIGeneState.NEUTRAL); - } - - } - - @Override - protected void setLocked(boolean value) { - locked += value ? 1 : -1; - setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); - - for (int i = 0; i < lines.length; i++) { - parent.getGuiGene(node.getConnection(i)).setLocked(value); - } - } - - @Override - public void addLocks(int value) { - locked += value; - setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); - - for (int i = 0; i < lines.length; i++) { - parent.getGuiGene(node.getConnection(i)).addLocks(value); - } + void setNode(Node node2) { + // TODO Auto-generated method stub + } @Override - public void removeLocks(int value) { - locked -= value; - setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.NEUTRAL); - - for (int i = 0; i < lines.length; i++) { - parent.getGuiGene(node.getConnection(i)).removeLocks(value); - } + public void mouseEnter() { + mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); } @Override - public void setConnectionLine(GUIGene gene) { - lines[connectionIndex].setEndX(gene.getLayoutX() + Constants.NODE_RADIUS); - lines[connectionIndex].setEndY(gene.getLayoutY()); - } - - public void updateText() { - if (parent.isEvaluating()) { - text.setText(node.getFunction() + "\n" + node.getValue().toString()); - } else { - text.setText(node.getFunction().toString()); - } + public void mouseExit() { + mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_COLOUR)); } - public void setFunction(Function function) { - node.setFunction(function); - if (parent.isEvaluating()) { - parent.updateValues(); - } else { - updateText(); - } - } - - public void setNode(Node newNode) { - node = newNode; - } } diff --git a/src/jcgp/gui/population/GUIOutput.java b/src/jcgp/gui/population/GUIOutput.java index d715138..ccc96c3 100644 --- a/src/jcgp/gui/population/GUIOutput.java +++ b/src/jcgp/gui/population/GUIOutput.java @@ -1,324 +1,31 @@ package jcgp.gui.population; -import javafx.event.EventHandler; -import javafx.scene.control.Label; -import javafx.scene.input.MouseDragEvent; -import javafx.scene.input.MouseEvent; import javafx.scene.paint.Paint; -import javafx.scene.shape.Circle; -import javafx.scene.shape.Line; -import jcgp.backend.population.Connection; -import jcgp.backend.population.Input; -import jcgp.backend.population.Node; import jcgp.backend.population.Output; -import jcgp.gui.GUI; import jcgp.gui.constants.Constants; public class GUIOutput extends GUIGene { - private Line sourceLine; private Output output; - public GUIOutput(ChromosomePane parentRef, final Output output, Line line, GUI gui) { + public GUIOutput(final Output output) { super(); - this.parent = parentRef; this.output = output; - this.sourceLine = line; - - relocate(((gui.getExperiment().getResources().columns() + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS, - (output.getIndex() * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); - - // set the line ends correctly - updateLines(); - updateText(); - - Circle socket = new Circle(-Constants.NODE_RADIUS, 0, Constants.SOCKET_RADIUS, Paint.valueOf("white")); - socket.setId(String.valueOf(0)); - socket.setStroke(Paint.valueOf("black")); - - final Label connectionLabel = new Label("S"); - connectionLabel.setStyle("-fx-background-color:rgb(255, 255, 255); -fx-border-color:rgba(0, 0, 0, 0.5); "); - connectionLabel.relocate(socket.getCenterX() + 5, socket.getCenterY() - 10); - connectionLabel.setVisible(false); - - /* - * Mouse event handlers on sockets - * - */ - socket.addEventFilter(MouseEvent.DRAG_DETECTED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // the mouse has been dragged out of the socket, this means a full drag is in progress - startFullDrag(); - } - }); - - socket.addEventFilter(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // user is hovering over connection socket - connectionLabel.setVisible(true); - } - }); - - socket.addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // user exits the connection socket - connectionLabel.setVisible(false); - } - }); - - socket.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // mouse was pressed on the socket - setState(GUIGeneState.SOURCE); - } - }); - - socket.addEventFilter(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - if (!parent.isTarget()) { - sourceLine.setEndX(event.getX() + ((Circle) event.getSource()).getParent().getLayoutX()); - sourceLine.setEndY(event.getY() + ((Circle) event.getSource()).getParent().getLayoutY()); - } - - } - }); - - socket.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - if (event.isStillSincePress()) { - // mouse was released before dragging out of the socket - updateLines(); - setState(GUIGeneState.HOVER); - } else if (getState() == GUIGeneState.SOURCE) { - // no connection has been made, fallback - resetState(); - updateLines(); - } - - } - }); - - - /* - * Mouse event handlers on whole gene - */ - addEventFilter(MouseDragEvent.MOUSE_DRAG_ENTERED, new EventHandler<MouseDragEvent>() { - @Override - public void handle(MouseDragEvent event) { - // the drag has entered this node, react appropriately - setState(GUIGeneState.INVALID_TARGET); - } - }); - - addEventFilter(MouseDragEvent.MOUSE_DRAG_EXITED, new EventHandler<MouseDragEvent>() { - @Override - public void handle(MouseDragEvent event) { - // the drag has exited this node, react appropriately - // this happens even if we are the source of the drag - if (event.isPrimaryButtonDown()) { - if (event.getGestureSource() == event.getSource()) { - setState(GUIGeneState.SOURCE); - } else { - setState(isLocked() ? GUIGeneState.HOVER : GUIGeneState.NEUTRAL); - } - } - } - }); - - addEventFilter(MouseDragEvent.MOUSE_DRAG_RELEASED, new EventHandler<MouseDragEvent>() { - @Override - public void handle(MouseDragEvent event) { - // making a connection to an output is illegal - // set states to reflect the new situation - GUIGene source = ((GUIGene) event.getGestureSource()); - - if (source.isLocked()) { - source.setState(GUIGeneState.HOVER); - source.setConnectionStates(GUIGeneState.HOVER); - } else { - source.setState(GUIGeneState.NEUTRAL); - source.setConnectionStates(GUIGeneState.NEUTRAL); - } - - source.updateLines(); - setState(GUIGeneState.HOVER); - } - }); - - - addEventFilter(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // cursor has entered this node without dragging, or it is dragging and this is the source - if (getState() == GUIGeneState.NEUTRAL) { - setState(GUIGeneState.HOVER); - } - } - }); - - addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - setLocked(!isLocked()); - } - }); - - addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // cursor has left this node without dragging, or it is dragging and this is the source - if (getState() == GUIGeneState.HOVER && !isLocked()) { - setState(GUIGeneState.NEUTRAL); - setConnectionStates(GUIGeneState.NEUTRAL); - } - } - }); - - - getChildren().addAll(mainCircle, text, socket, connectionLabel); - } - @Override - public void setState(GUIGeneState newState) { - super.setState(newState); + void setOutput(Output output2) { + // TODO Auto-generated method stub - switch (newState) { - case ACTIVE_HOVER: - break; - case INVALID_TARGET: - mainCircle.setFill(Paint.valueOf(Constants.BAD_SELECTION_COLOUR)); - break; - case HOVER: - mainCircle.setFill(Paint.valueOf(Constants.MEDIUM_HIGHLIGHT_COLOUR)); - sourceLine.setVisible(true); - if (!isLocked()) { - setConnectionStates(GUIGeneState.ACTIVE_HOVER); - } - break; - case INDIRECT_HOVER: - mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); - break; - case NEUTRAL: - mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_COLOUR)); - sourceLine.setVisible(false); - break; - case NO_CHANGE_TARGET: - mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_SELECTION_COLOUR)); - break; - case SOURCE: - mainCircle.setFill(Paint.valueOf(Constants.HARD_HIGHLIGHT_COLOUR)); - setConnectionStates(GUIGeneState.NEUTRAL); - setConnectionStates(GUIGeneState.INDIRECT_HOVER); - break; - case VALID_TARGET: - mainCircle.setFill(Paint.valueOf(Constants.GOOD_SELECTION_COLOUR)); - break; - default: - break; - } - } - - @Override - public void updateLines() { - if (output.getSource() instanceof Node) { - int row = ((Node) output.getSource()).getRow(), - column = ((Node) output.getSource()).getColumn(); - sourceLine.setEndX(((column + 1) * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + 2 * Constants.NODE_RADIUS); - sourceLine.setEndY((row * (2 * Constants.NODE_RADIUS + Constants.SPACING)) + Constants.NODE_RADIUS); - } else if (output.getSource() instanceof Input) { - int inputIndex = ((Input) output.getSource()).getIndex(); - sourceLine.setEndX(2 * Constants.NODE_RADIUS); - sourceLine.setEndY(inputIndex * (2 * Constants.NODE_RADIUS + Constants.SPACING) + Constants.NODE_RADIUS); - } - } - - @Override - public void setConnectionStates(GUIGeneState newState) { - parent.getGuiGene(output.getSource()).setState(newState); } @Override - public void resetState() { - if (locked > 0) { - setState(GUIGeneState.HOVER); - setConnectionStates(GUIGeneState.HOVER); - } else { - setState(GUIGeneState.NEUTRAL); - setConnectionStates(GUIGeneState.NEUTRAL); - } + public void mouseEnter() { + mainCircle.setFill(Paint.valueOf(Constants.SOFT_HIGHLIGHT_COLOUR)); } @Override - protected void setLocked(boolean value) { - locked += value ? 1 : -1; - setConnectionStates(value ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); - - parent.getGuiGene(output.getSource()).setLocked(value); - - } - - @Override - public void setChangingConnection(Connection newConnection) { - output.setSource(newConnection); - updateText(); - } - - @Override - public Connection getChangingConnection() { - return output.getSource(); - } - - @Override - public void addLocks(int value) { - locked += value; - } - - @Override - public void removeLocks(int value) { - locked -= value; + public void mouseExit() { + mainCircle.setFill(Paint.valueOf(Constants.NEUTRAL_COLOUR)); } - - @Override - public void setConnectionLine(GUIGene gene) { - sourceLine.setEndX(gene.getLayoutX() + Constants.NODE_RADIUS); - sourceLine.setEndY(gene.getLayoutY()); - } - - public void unlock() { - if (isLocked()) { - setLocked(false); - setState(GUIGeneState.NEUTRAL); - setConnectionStates(GUIGeneState.NEUTRAL); - } - } - - public void lock() { - if (!isLocked()) { - setState(GUIGeneState.HOVER); - setLocked(true); - } - } - - @Override - public void updateText() { - if (parent.isEvaluating()) { - text.setText("O: " + output.getIndex() + "\n" + output.getSource().getValue().toString()); - } else { - text.setText("O: " + output.getIndex()); - } - - } - - public void setOutput(Output newOutput) { - output = newOutput; - } - } diff --git a/src/jcgp/gui/population/PopulationPane.java b/src/jcgp/gui/population/PopulationPane.java index 4b1b7f8..31f6c33 100644 --- a/src/jcgp/gui/population/PopulationPane.java +++ b/src/jcgp/gui/population/PopulationPane.java @@ -43,25 +43,13 @@ public class PopulationPane extends TabPane { } } - public void unlockOutputs() { - for (int i = 0; i < getTabs().size(); i++) { - ((ChromosomePane) getTabs().get(i).getContent()).unlockOutputs(); - } - } - - public void relockOutputs() { - for (int i = 0; i < getTabs().size(); i++) { - ((ChromosomePane) getTabs().get(i).getContent()).relockOutputs(); - } - } - public void evaluateTestCase(TestCase<Object> testCase) { if (gui.getExperiment().getProblem() instanceof TestCaseProblem && testCase != null) { currentTestCase = testCase; if (testCase.getInputs().length == gui.getExperiment().getResources().inputs()) { evaluating = true; for (int i = 0; i < getTabs().size(); i++) { - ((ChromosomePane) getTabs().get(i).getContent()).setInputs(testCase.getInputs()); + //((ChromosomePane) getTabs().get(i).getContent()).setInputs(testCase.getInputs()); } } else { throw new IllegalArgumentException("Test case has " + testCase.getInputs().length @@ -73,7 +61,7 @@ public class PopulationPane extends TabPane { public void hideValues() { evaluating = false; for (int i = 0; i < getTabs().size(); i++) { - ((ChromosomePane) getTabs().get(i).getContent()).updateValues(); + //((ChromosomePane) getTabs().get(i).getContent()).updateValues(); } } |