From 2bf2d3ac2c578de481ecfd545d58be73c5628996 Mon Sep 17 00:00:00 2001 From: Eduardo Pedroni Date: Wed, 26 Mar 2014 21:34:37 +0000 Subject: Node grid has been refactored a few times, settings pane is almost complete, console is all done. --- src/jcgp/gui/Console.java | 13 -- src/jcgp/gui/GUIConsole.java | 96 ++++++++++ src/jcgp/gui/SettingsPane.java | 253 +++++++++++++++++++++++-- src/jcgp/gui/population/ChromosomePane.java | 21 +- src/jcgp/gui/population/GUIGene.java | 2 +- src/jcgp/gui/population/GUIInput.java | 3 +- src/jcgp/gui/population/GUINode.java | 74 +++----- src/jcgp/gui/population/GUIOutput.java | 42 ++-- src/jcgp/gui/settings/GUIBooleanParameter.java | 24 +++ src/jcgp/gui/settings/GUIDoubleParameter.java | 33 ++++ src/jcgp/gui/settings/GUIIntegerParameter.java | 18 +- src/jcgp/gui/settings/GUIParameter.java | 5 +- 12 files changed, 465 insertions(+), 119 deletions(-) delete mode 100644 src/jcgp/gui/Console.java create mode 100644 src/jcgp/gui/GUIConsole.java create mode 100644 src/jcgp/gui/settings/GUIBooleanParameter.java create mode 100644 src/jcgp/gui/settings/GUIDoubleParameter.java (limited to 'src/jcgp/gui') diff --git a/src/jcgp/gui/Console.java b/src/jcgp/gui/Console.java deleted file mode 100644 index 9008531..0000000 --- a/src/jcgp/gui/Console.java +++ /dev/null @@ -1,13 +0,0 @@ -package jcgp.gui; - -import javafx.scene.control.TextArea; - -public class Console extends TextArea { - - public Console() { - super(); - setDisable(true); - setPrefHeight(100); - } - -} diff --git a/src/jcgp/gui/GUIConsole.java b/src/jcgp/gui/GUIConsole.java new file mode 100644 index 0000000..a14a23b --- /dev/null +++ b/src/jcgp/gui/GUIConsole.java @@ -0,0 +1,96 @@ +package jcgp.gui; + +import javafx.event.EventHandler; +import javafx.scene.Cursor; +import javafx.scene.control.TextArea; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.AnchorPane; +import jcgp.GUI; + +public class GUIConsole extends AnchorPane { + + private boolean dragging; + private TextArea textArea = new TextArea("Welcome to JCGP!\n"); + + public GUIConsole() { + super(); + textArea.setEditable(false); + textArea.setWrapText(true); + + //setStyle("-fx-border-width: 5 0 0 0; -fx-border-color: #D1D1D1"); + + setResizeListeners(); + + AnchorPane.setTopAnchor(textArea, GUI.RESIZE_MARGIN); + AnchorPane.setBottomAnchor(textArea, 0.0); + AnchorPane.setRightAnchor(textArea, 0.0); + AnchorPane.setLeftAnchor(textArea, 0.0); + + setMinHeight(GUI.CONSOLE_HEIGHT); + setPrefHeight(GUI.CONSOLE_HEIGHT); + + getChildren().add(textArea); + + } + + /** + * + */ + private void setResizeListeners() { + setOnMousePressed(new EventHandler() { + @Override + public void handle(MouseEvent event) { + // ignore clicks outside of the draggable margin + if(isInDraggableZone(event)) { + dragging = true; + } + } + }); + setOnMouseDragged(new EventHandler() { + @Override + public void handle(MouseEvent event) { + if(dragging) { + double newHeight = getHeight() - event.getY(); + if (newHeight >= getMinHeight()) { + setPrefHeight(newHeight); + } else { + setPrefHeight(getMinHeight()); + } + } + } + }); + setOnMouseMoved(new EventHandler() { + @Override + public void handle(MouseEvent event) { + if(isInDraggableZone(event) || dragging) { + setCursor(Cursor.V_RESIZE); + } + else { + setCursor(Cursor.DEFAULT); + } + } + }); + setOnMouseReleased(new EventHandler() { + @Override + public void handle(MouseEvent event) { + dragging = false; + setCursor(Cursor.DEFAULT); + } + }); + textArea.setOnMouseEntered(new EventHandler() { + @Override + public void handle(MouseEvent event) { + setCursor(Cursor.DEFAULT); + } + }); + } + + private boolean isInDraggableZone(MouseEvent event) { + return event.getY() < (GUI.RESIZE_MARGIN); + } + + public TextArea getTextArea() { + return textArea; + } + +} diff --git a/src/jcgp/gui/SettingsPane.java b/src/jcgp/gui/SettingsPane.java index f7e7767..594147f 100644 --- a/src/jcgp/gui/SettingsPane.java +++ b/src/jcgp/gui/SettingsPane.java @@ -1,37 +1,266 @@ package jcgp.gui; +import java.util.ArrayList; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.geometry.Insets; +import javafx.scene.Cursor; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ComboBox; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; +import javafx.scene.text.Font; import javafx.scene.text.Text; +import jcgp.GUI; import jcgp.JCGP; +import jcgp.function.FunctionSet; +import jcgp.gui.settings.GUIBooleanParameter; +import jcgp.gui.settings.GUIDoubleParameter; import jcgp.gui.settings.GUIIntegerParameter; +import jcgp.gui.settings.GUIParameter; +import jcgp.modules.ea.EvolutionaryAlgorithm; +import jcgp.modules.fitness.FitnessFunction; +import jcgp.modules.mutator.Mutator; +import jcgp.parameters.BooleanParameter; +import jcgp.parameters.DoubleParameter; import jcgp.parameters.IntegerParameter; import jcgp.parameters.Parameter; -public class SettingsPane extends VBox { +public class SettingsPane extends AnchorPane { + private VBox mainContainer, eas, mutators, ffs; + private boolean dragging = false; + public SettingsPane(JCGP cgp) { super(); - setPrefSize(180, 500); + setResizeListeners(); - Text parameters = new Text("Parameters"); - getChildren().add(parameters); + //setStyle("-fx-border-width: 0 0 0 5; -fx-border-color: #D1D1D1"); - Iterator> it = cgp.getResources().iterator(); - while (it.hasNext()) { - Parameter p = (Parameter) ((Map.Entry) it.next()).getValue(); - if (p instanceof IntegerParameter) { - GUIIntegerParameter gip = new GUIIntegerParameter((IntegerParameter) p); - getChildren().add(gip); - } - } + mainContainer = new VBox(); + + AnchorPane.setTopAnchor(mainContainer, 0.0); + AnchorPane.setBottomAnchor(mainContainer, 0.0); + AnchorPane.setRightAnchor(mainContainer, 0.0); + AnchorPane.setLeftAnchor(mainContainer, GUI.RESIZE_MARGIN); + mainContainer.setPadding(new Insets(5, 0, 0, 0)); + mainContainer.setSpacing(6); + + setMinWidth(GUI.SETTINGS_WIDTH); + setPrefWidth(GUI.SETTINGS_WIDTH); + + makeBaseParameters(cgp); + makeEAParameters(cgp); + mainContainer.getChildren().add(eas); + + makeMutatorParameters(cgp); + mainContainer.getChildren().add(mutators); + makeFitnessFunctionParameters(cgp); + mainContainer.getChildren().add(ffs); + + makeNodeFunctionParameters(cgp); + + getChildren().add(mainContainer); + } + + private void makeBaseParameters(JCGP cgp) { + VBox vb = new VBox(); + vb.setSpacing(2); + + Text header = new Text("Base Parameters"); + header.setFont(Font.font("Arial", 14)); + header.setUnderline(true); + + vb.getChildren().add(header); + + ArrayList gp = new ArrayList(); + + gp.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("rows"))); + gp.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("columns"))); + gp.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("inputs"))); + gp.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("outputs"))); + gp.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("levelsBack"))); + + gp.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("popSize"))); + gp.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("generations"))); + gp.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("runs"))); + + gp.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("seed"))); + gp.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("report"))); + gp.add(new GUIBooleanParameter((BooleanParameter) cgp.getResources().getParameter("debug"))); + + vb.getChildren().addAll(gp); + + mainContainer.getChildren().add(vb); + } + + private void makeEAParameters(JCGP cgp) { + eas = new VBox(); + eas.setSpacing(2); + + Text header = new Text("EA"); + header.setFont(Font.font("Arial", 14)); + header.setUnderline(true); + + eas.getChildren().add(header); + + ComboBox eab = new ComboBox(); + eab.getItems().addAll(cgp.getEvolutionaryAlgorithms()); + eab.getSelectionModel().select(cgp.getEvolutionaryAlgorithm()); + eab.prefWidthProperty().bind(mainContainer.widthProperty()); + eas.getChildren().add(eab); + + addParameters(cgp.getEvolutionaryAlgorithm().getLocalParameters().entrySet().iterator(), eas); + } + + private void makeMutatorParameters(JCGP cgp) { + mutators = new VBox(); + mutators.setSpacing(2); + + Text header = new Text("Mutator"); + header.setFont(Font.font("Arial", 14)); + header.setUnderline(true); + + mutators.getChildren().add(header); + + ComboBox mb = new ComboBox(); + mb.getItems().addAll(cgp.getMutators()); + mb.getSelectionModel().select(cgp.getMutator()); + mb.prefWidthProperty().bind(mainContainer.widthProperty()); + mutators.getChildren().add(mb); + + addParameters(cgp.getMutator().getLocalParameters().entrySet().iterator(), mutators); + } + + private void makeFitnessFunctionParameters(JCGP cgp) { + ffs = new VBox(); + ffs.setSpacing(2); + + Text header = new Text("Fitness Function"); + header.setFont(Font.font("Arial", 14)); + header.setUnderline(true); + + ffs.getChildren().add(header); + + ComboBox ff = new ComboBox(); + ff.getItems().addAll(cgp.getFitnessFunctions()); + ff.getSelectionModel().select(cgp.getFitnessFunction()); + ff.prefWidthProperty().bind(mainContainer.widthProperty()); + ffs.getChildren().add(ff); + + addParameters(cgp.getFitnessFunction().getLocalParameters().entrySet().iterator(), ffs); + } + + private void makeNodeFunctionParameters(JCGP cgp) { + VBox vb = new VBox(); + vb.setSpacing(2); + + Text header = new Text("Node Functions"); + header.setFont(Font.font("Arial", 14)); + header.setUnderline(true); + + vb.getChildren().add(header); + + ComboBox nf = new ComboBox(); + nf.getItems().addAll(cgp.getResources().getFunctionSets()); + nf.getSelectionModel().select(cgp.getResources().getFunctionSet()); + nf.prefWidthProperty().bind(mainContainer.widthProperty()); + vb.getChildren().add(nf); + + // TODO make this function re-usable + addFunctions(cgp.getResources().getFunctionSet(), vb); + + mainContainer.getChildren().add(vb); } + /** + * @param cgp + * @param vb + */ + private void addParameters(Iterator> it, VBox vb) { + while (it.hasNext()) { + Parameter parameter = ((Map.Entry) it.next()).getValue(); + if (parameter instanceof IntegerParameter) { + vb.getChildren().add(new GUIIntegerParameter((IntegerParameter) parameter)); + } else if (parameter instanceof DoubleParameter) { + vb.getChildren().add(new GUIDoubleParameter((DoubleParameter) parameter)); + } else if (parameter instanceof BooleanParameter) { + vb.getChildren().add(new GUIBooleanParameter((BooleanParameter) parameter)); + } + } + } + private void addFunctions(final FunctionSet fs, VBox vb) { + CheckBox cb; + for (int i = 0; i < fs.getTotalFunctionCount(); i++) { + cb = new CheckBox(fs.getFunction(i).getName()); + cb.setId(String.valueOf(i)); + cb.setSelected(true); + final int index = i; + cb.setOnAction(new EventHandler() { + @Override + public void handle(ActionEvent event) { + if (((CheckBox) event.getSource()).isSelected()) { + fs.enableFunction(index); + } else { + fs.disableFunction(index); + } + } + }); + vb.getChildren().add(cb); + } + } + private void setResizeListeners() { + setOnMousePressed(new EventHandler() { + @Override + public void handle(MouseEvent event) { + if(isInDraggableZone(event)) { + dragging = true; + } + } + }); + setOnMouseDragged(new EventHandler() { + @Override + public void handle(MouseEvent event) { + if(dragging) { + double newWidth = getWidth() - event.getX(); + if (newWidth >= getMinWidth()) { + setPrefWidth(newWidth); + } else { + setPrefWidth(getMinWidth()); + } + } + } + }); + setOnMouseMoved(new EventHandler() { + @Override + public void handle(MouseEvent event) { + if(isInDraggableZone(event) || dragging) { + setCursor(Cursor.H_RESIZE); + } + else { + setCursor(Cursor.DEFAULT); + } + } + }); + setOnMouseReleased(new EventHandler() { + @Override + public void handle(MouseEvent event) { + dragging = false; + setCursor(Cursor.DEFAULT); + } + }); + } + private boolean isInDraggableZone(MouseEvent event) { + return event.getX() < (GUI.RESIZE_MARGIN); + } + } diff --git a/src/jcgp/gui/population/ChromosomePane.java b/src/jcgp/gui/population/ChromosomePane.java index 0c7b3d2..7fa8a54 100644 --- a/src/jcgp/gui/population/ChromosomePane.java +++ b/src/jcgp/gui/population/ChromosomePane.java @@ -28,6 +28,8 @@ public class ChromosomePane extends ScrollPane { super(); connectionLines = new ArrayList(); + //setMouseTransparent(true); + content = new Pane(); content.setId("content pane for genes"); @@ -82,19 +84,6 @@ public class ChromosomePane extends ScrollPane { setContent(content); } - -// public GUINode getGuiNode(int row, int column) { -// return guiNodes[row][column]; -// } -// -// public GUIInput getGuiInput(int index) { -// return guiInputs[index]; -// } -// -// public GUIOutput getGuiOutput(int index) { -// return guiOutputs[index]; -// } - public GUIGene getGuiGene(Connection gene) { if (gene instanceof Input) { return guiInputs[((Input) gene).getIndex()]; @@ -107,11 +96,6 @@ public class ChromosomePane extends ScrollPane { } - public Pane getContentPane() { - return content; - } - - public boolean isTarget() { return target; } @@ -119,5 +103,4 @@ public class ChromosomePane extends ScrollPane { public void setTarget(boolean newValue) { target = newValue; } - } diff --git a/src/jcgp/gui/population/GUIGene.java b/src/jcgp/gui/population/GUIGene.java index 1be662e..3addca7 100644 --- a/src/jcgp/gui/population/GUIGene.java +++ b/src/jcgp/gui/population/GUIGene.java @@ -27,7 +27,7 @@ public abstract class GUIGene extends Group { public static final double THETA = Math.PI / 1.4; public static final double SOCKET_RADIUS = Math.sqrt(NODE_RADIUS) / 1.8; - public static final double NODE_TEXT = 0; + public static final double NODE_TEXT = NODE_RADIUS / 2.5; protected Text text; protected Circle mainCircle; diff --git a/src/jcgp/gui/population/GUIInput.java b/src/jcgp/gui/population/GUIInput.java index ac1a775..84e8a2a 100644 --- a/src/jcgp/gui/population/GUIInput.java +++ b/src/jcgp/gui/population/GUIInput.java @@ -18,7 +18,6 @@ import jcgp.population.Output; public class GUIInput extends GUIGene { - private Circle outputSocket; private Input input; public GUIInput(ChromosomePane parentRef, final Input input) { @@ -40,7 +39,7 @@ public class GUIInput extends GUIGene { text.setX(-NODE_RADIUS); text.setVisible(true); - outputSocket = new Circle(NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); + Circle outputSocket = new Circle(NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); outputSocket.setId(String.valueOf(0)); outputSocket.setStroke(Paint.valueOf("black")); diff --git a/src/jcgp/gui/population/GUINode.java b/src/jcgp/gui/population/GUINode.java index dd20006..eeacb9e 100644 --- a/src/jcgp/gui/population/GUINode.java +++ b/src/jcgp/gui/population/GUINode.java @@ -14,23 +14,14 @@ import javafx.scene.text.Font; import javafx.scene.text.Text; import javafx.scene.text.TextAlignment; import jcgp.GUI; -import jcgp.function.Function; import jcgp.population.Connection; import jcgp.population.Input; import jcgp.population.Node; -import jcgp.population.Output; public class GUINode extends GUIGene { - private Circle[] sockets; - private Circle output; - private Line[] lines; - - private Label connectionNumber; - private Node node; - private int connectionIndex = 0; public GUINode(ChromosomePane parentRef, final Node node, Line[] connectionLines) { @@ -39,7 +30,7 @@ public class GUINode extends GUIGene { this.parent = parentRef; this.node = node; this.lines = connectionLines; - + // move the GUIGene to the right position relocate(((node.getColumn() + 1) * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS, (node.getRow() * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS); @@ -47,32 +38,25 @@ public class GUINode extends GUIGene { // set the line ends correctly updateLines(); - connectionNumber = new Label(); + 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); - output = new Circle(NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); + Circle output = new Circle(NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); output.setStroke(Paint.valueOf("black")); mainCircle = new Circle(NODE_RADIUS, Paint.valueOf("white")); mainCircle.setStroke(Paint.valueOf("black")); text = new Text(node.getFunction().getName()); - this.node.functionProperty().addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, - Function oldValue, Function newValue) { - text.setText(newValue.getName()); - } - }); - text.setFont(Font.font("Arial", 12)); + text.setFont(Font.font("Arial", NODE_TEXT)); text.setTextOrigin(VPos.CENTER); text.setTextAlignment(TextAlignment.CENTER); text.setWrappingWidth(NODE_RADIUS * 2); text.setX(-NODE_RADIUS); text.setVisible(true); - sockets = new Circle[(int) GUI.resources.get("arity")]; + Circle[] sockets = new Circle[(int) GUI.resources.get("arity")]; double angle, xPos, yPos; for (int l = 0; l < sockets.length; l++) { angle = ((((double) (l + 1)) / ((double) ((int) GUI.resources.get("arity") + 1))) * THETA) - (THETA / 2); @@ -137,11 +121,15 @@ public class GUINode extends GUIGene { s.addEventFilter(MouseDragEvent.MOUSE_RELEASED, new EventHandler() { @Override - public void handle(MouseEvent event) { - if (event.isDragDetect()) { + public void handle(MouseEvent event) { + if (event.isStillSincePress()) { // mouse was released before dragging out of the socket updateLine(index); stateProperty.set(GUIGeneState.HOVER); + } else if (stateProperty.get() == GUIGeneState.SOURCE) { + // no connection has been made, fallback + resetState(); + updateLines(); } } }); @@ -157,19 +145,13 @@ public class GUINode extends GUIGene { // 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()); - if (event.getGestureSource() instanceof GUINode) { - Connection source = ((GUINode) event.getGestureSource()).getChangingConnection(); - if (node == source) { - stateProperty.set(GUIGeneState.NO_CHANGE_TARGET); - return; - } - } else if (event.getGestureSource() instanceof GUIOutput) { - Output source = ((GUIOutput) event.getGestureSource()).getGene(); - if (((GUIGene) event.getSource()).getGene() == source.getSource()) { - ((GUIGene) event.getSource()).setState(GUIGeneState.NO_CHANGE_TARGET); - } + + Connection source = ((GUIGene) event.getGestureSource()).getChangingConnection(); + if (node == source) { + stateProperty.set(GUIGeneState.NO_CHANGE_TARGET); + } else { + stateProperty.set(GUIGeneState.TARGET); } - stateProperty.set(GUIGeneState.TARGET); } else { stateProperty.set(GUIGeneState.FORBIDDEN_TARGET); } @@ -289,7 +271,7 @@ public class GUINode extends GUIGene { case HOVER: mainCircle.setFill(Paint.valueOf(GUI.MEDIUM_HIGHLIGHT_COLOUR)); showLines(true); - if ((oldValue != GUIGeneState.LOCKED_HOVER || oldValue != GUIGeneState.SOURCE) && locked <= 0) { + if (locked <= 0) { setConnections(GUIGeneState.INDIRECT_HOVER); } else { setConnections(GUIGeneState.HOVER); @@ -326,16 +308,16 @@ public class GUINode extends GUIGene { } }); - for (int c = 0; c < lines.length; c++) { - final int i = c; - node.connections().get(c).addListener(new ChangeListener() { - @Override - public void changed(ObservableValue observable, - Connection oldValue, Connection newValue) { - updateLine(i); - } - }); - } +// for (int c = 0; c < lines.length; c++) { +// final int i = c; +// node.connections().get(c).addListener(new ChangeListener() { +// @Override +// public void changed(ObservableValue observable, +// Connection oldValue, Connection newValue) { +// updateLine(i); +// } +// }); +// } } diff --git a/src/jcgp/gui/population/GUIOutput.java b/src/jcgp/gui/population/GUIOutput.java index 87d420e..57042eb 100644 --- a/src/jcgp/gui/population/GUIOutput.java +++ b/src/jcgp/gui/population/GUIOutput.java @@ -21,10 +21,6 @@ import jcgp.population.Output; public class GUIOutput extends GUIGene { - private Circle socket; - - private Label connectionLabel; - private Line sourceLine; private Output output; @@ -52,11 +48,11 @@ public class GUIOutput extends GUIGene { text.setX(-NODE_RADIUS); text.setVisible(true); - socket = new Circle(-NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); + Circle socket = new Circle(-NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); socket.setId(String.valueOf(0)); socket.setStroke(Paint.valueOf("black")); - connectionLabel = new Label("S"); + 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); @@ -100,19 +96,27 @@ public class GUIOutput extends GUIGene { socket.addEventFilter(MouseDragEvent.MOUSE_DRAGGED, new EventHandler() { @Override public void handle(MouseEvent event) { - sourceLine.setEndX(event.getX() + ((Circle) event.getSource()).getParent().getLayoutX()); - sourceLine.setEndY(event.getY() + ((Circle) event.getSource()).getParent().getLayoutY()); + if (!parent.isTarget()) { + sourceLine.setEndX(event.getX() + ((Circle) event.getSource()).getParent().getLayoutX()); + sourceLine.setEndY(event.getY() + ((Circle) event.getSource()).getParent().getLayoutY()); + } + } }); socket.addEventFilter(MouseDragEvent.MOUSE_RELEASED, new EventHandler() { @Override public void handle(MouseEvent event) { - if (event.isDragDetect()) { + if (event.isStillSincePress()) { // mouse was released before dragging out of the socket updateLines(); stateProperty.set(GUIGeneState.HOVER); + } else if (stateProperty.get() == GUIGeneState.SOURCE) { + // no connection has been made, fallback + resetState(); + updateLines(); } + } }); @@ -185,14 +189,9 @@ public class GUIOutput extends GUIGene { @Override public void handle(MouseEvent event) { // cursor has left this node without dragging, or it is dragging and this is the source - if (stateProperty.get() == GUIGeneState.HOVER) { - if (isLocked()) { - - } else { - stateProperty.set(GUIGeneState.NEUTRAL); - setConnections(GUIGeneState.NEUTRAL); - } - + if (stateProperty.get() == GUIGeneState.HOVER && !isLocked()) { + stateProperty.set(GUIGeneState.NEUTRAL); + setConnections(GUIGeneState.NEUTRAL); } } }); @@ -279,8 +278,13 @@ public class GUIOutput extends GUIGene { @Override public void resetState() { - stateProperty.set(GUIGeneState.NEUTRAL); - setConnections(GUIGeneState.NEUTRAL); + if (locked > 0) { + stateProperty.set(GUIGeneState.HOVER); + setConnections(GUIGeneState.HOVER); + } else { + stateProperty.set(GUIGeneState.NEUTRAL); + setConnections(GUIGeneState.NEUTRAL); + } } @Override diff --git a/src/jcgp/gui/settings/GUIBooleanParameter.java b/src/jcgp/gui/settings/GUIBooleanParameter.java new file mode 100644 index 0000000..7b20c3b --- /dev/null +++ b/src/jcgp/gui/settings/GUIBooleanParameter.java @@ -0,0 +1,24 @@ +package jcgp.gui.settings; + +import javafx.geometry.Pos; +import javafx.scene.control.CheckBox; +import jcgp.parameters.BooleanParameter; + +public class GUIBooleanParameter extends GUIParameter { + + public GUIBooleanParameter(BooleanParameter parameter) { + setAlignment(Pos.CENTER_LEFT); + setSpacing(5); + + this.parameter = parameter; + + value = new CheckBox(parameter.getName()); + ((CheckBox) value).setSelected(parameter.getValue()); + + value.setDisable(parameter.isManaged()); + + getChildren().add(value); + + } + +} diff --git a/src/jcgp/gui/settings/GUIDoubleParameter.java b/src/jcgp/gui/settings/GUIDoubleParameter.java new file mode 100644 index 0000000..d61899b --- /dev/null +++ b/src/jcgp/gui/settings/GUIDoubleParameter.java @@ -0,0 +1,33 @@ +package jcgp.gui.settings; + +import javafx.geometry.Pos; +import javafx.scene.control.TextField; +import javafx.scene.layout.Priority; +import javafx.scene.text.Text; +import jcgp.GUI; +import jcgp.parameters.DoubleParameter; + +public class GUIDoubleParameter extends GUIParameter { + + public GUIDoubleParameter(DoubleParameter parameter) { + setAlignment(Pos.CENTER_LEFT); + setSpacing(5); + + this.parameter = parameter; + + name = new Text(parameter.getName()); + value = new TextField(String.valueOf(parameter.getValue())); + + ((TextField) value).setAlignment(Pos.CENTER_RIGHT); + + setHgrow(value, Priority.ALWAYS); + + name.setWrappingWidth(GUI.WRAP_WIDTH); + + value.setDisable(parameter.isManaged()); + + getChildren().addAll(name, value); + + } + +} diff --git a/src/jcgp/gui/settings/GUIIntegerParameter.java b/src/jcgp/gui/settings/GUIIntegerParameter.java index 2bf5480..b7a23a4 100644 --- a/src/jcgp/gui/settings/GUIIntegerParameter.java +++ b/src/jcgp/gui/settings/GUIIntegerParameter.java @@ -1,23 +1,31 @@ package jcgp.gui.settings; +import javafx.geometry.Pos; import javafx.scene.control.TextField; +import javafx.scene.layout.Priority; import javafx.scene.text.Text; +import jcgp.GUI; import jcgp.parameters.IntegerParameter; public class GUIIntegerParameter extends GUIParameter { - private TextField value; - public GUIIntegerParameter(IntegerParameter parameter) { + setAlignment(Pos.CENTER_LEFT); + setSpacing(5); + this.parameter = parameter; name = new Text(parameter.getName()); - value = new TextField(String.valueOf((int) parameter.getValue())); + value = new TextField(String.valueOf(parameter.getValue())); + + ((TextField) value).setAlignment(Pos.CENTER_RIGHT); + + setHgrow(value, Priority.ALWAYS); + + name.setWrappingWidth(GUI.WRAP_WIDTH); value.setDisable(parameter.isManaged()); getChildren().addAll(name, value); - } - } diff --git a/src/jcgp/gui/settings/GUIParameter.java b/src/jcgp/gui/settings/GUIParameter.java index d084060..0547758 100644 --- a/src/jcgp/gui/settings/GUIParameter.java +++ b/src/jcgp/gui/settings/GUIParameter.java @@ -1,13 +1,14 @@ package jcgp.gui.settings; +import javafx.scene.control.Control; import javafx.scene.layout.HBox; import javafx.scene.text.Text; import jcgp.parameters.Parameter; public abstract class GUIParameter extends HBox { - + protected Parameter parameter; - protected Text name; + protected Control value; } -- cgit v1.2.3