diff options
author | Eduardo Pedroni <ep625@york.ac.uk> | 2014-04-06 21:58:53 +0100 |
---|---|---|
committer | Eduardo Pedroni <ep625@york.ac.uk> | 2014-04-06 21:58:53 +0100 |
commit | e6dd7711c7dad5e000445208eb5845801f4ccffc (patch) | |
tree | 1454bd20a8dd7069b1283184c42f4def6d5f7e6f /src/jcgp/gui | |
parent | c7969623b44f375e30fa3f15dcd7581609276a0f (diff) |
About to make big changes to the way fitness works, committing just in case
Diffstat (limited to 'src/jcgp/gui')
-rw-r--r-- | src/jcgp/gui/GUI.java | 172 | ||||
-rw-r--r-- | src/jcgp/gui/console/Console.java | 11 | ||||
-rw-r--r-- | src/jcgp/gui/console/GUIConsole.java | 63 | ||||
-rw-r--r-- | src/jcgp/gui/dragresize/HorizontalDragResize.java | 90 | ||||
-rw-r--r-- | src/jcgp/gui/dragresize/VerticalDragResize.java | 90 | ||||
-rw-r--r-- | src/jcgp/gui/population/ChromosomePane.java (renamed from src/jcgp/gui/ChromosomePane.java) | 19 | ||||
-rw-r--r-- | src/jcgp/gui/population/FunctionSelector.java | 73 | ||||
-rw-r--r-- | src/jcgp/gui/population/GUIGene.java | 40 | ||||
-rw-r--r-- | src/jcgp/gui/population/GUIInput.java | 145 | ||||
-rw-r--r-- | src/jcgp/gui/population/GUINode.java | 207 | ||||
-rw-r--r-- | src/jcgp/gui/population/GUIOutput.java | 142 | ||||
-rw-r--r-- | src/jcgp/gui/population/PopulationPane.java | 49 | ||||
-rw-r--r-- | src/jcgp/gui/settings/SettingsPane.java | 184 | ||||
-rw-r--r-- | src/jcgp/gui/settings/parameters/GUIBooleanParameter.java | 11 | ||||
-rw-r--r-- | src/jcgp/gui/settings/parameters/GUIDoubleParameter.java | 17 | ||||
-rw-r--r-- | src/jcgp/gui/settings/parameters/GUIIntegerParameter.java | 17 | ||||
-rw-r--r-- | src/jcgp/gui/settings/parameters/GUIParameter.java | 18 |
17 files changed, 717 insertions, 631 deletions
diff --git a/src/jcgp/gui/GUI.java b/src/jcgp/gui/GUI.java index f7aa25d..8f28884 100644 --- a/src/jcgp/gui/GUI.java +++ b/src/jcgp/gui/GUI.java @@ -5,14 +5,16 @@ import javafx.application.Platform; import javafx.concurrent.Service; import javafx.concurrent.Task; import javafx.scene.Scene; -import javafx.scene.control.Tab; -import javafx.scene.control.TabPane; -import javafx.scene.control.TabPane.TabClosingPolicy; import javafx.scene.layout.BorderPane; +import javafx.scene.layout.Pane; import javafx.stage.Stage; import jcgp.JCGP; -import jcgp.JCGP.Resources; +import jcgp.backend.resources.Resources; import jcgp.gui.console.GUIConsole; +import jcgp.gui.dragresize.HorizontalDragResize; +import jcgp.gui.dragresize.VerticalDragResize; +import jcgp.gui.population.FunctionSelector; +import jcgp.gui.population.PopulationPane; import jcgp.gui.settings.SettingsPane; public class GUI extends Application { @@ -28,10 +30,6 @@ public class GUI extends Application { public static final String GOOD_SELECTION_COLOUR = "#38C25B"; public static final String NEUTRAL_SELECTION_COLOUR = "#FFEF73"; public static final String BAD_SELECTION_COLOUR = "#FF5C5C"; - - public static final String INVALID_PARAMETER_STYLE = "-fx-border-color: C9C9C9; -fx-border-radius: 2; -fx-padding: 0; -fx-background-color: " + BAD_SELECTION_COLOUR; - public static final String WARNING_PARAMETER_STYLE = "-fx-border-color: C9C9C9; -fx-border-radius: 2; -fx-padding: 0; -fx-background-color: " + NEUTRAL_SELECTION_COLOUR; - public static final String VALID_PARAMETER_STYLE = "-fx-border-color: C9C9C9; -fx-border-radius: 2; -fx-padding: 0; -fx-background-color: " + NEUTRAL_COLOUR; /* Sizes and distances */ public static final double RESIZE_MARGIN = 5.0; @@ -41,17 +39,16 @@ public class GUI extends Application { public static final double WRAP_WIDTH = 90; - private static JCGP cgp; - public static Resources resources; + public static final JCGP jcgp = new JCGP(); + public static final Resources resources = jcgp.getResources(); - private BorderPane leftPane; - private BorderPane window; + public static final FunctionSelector functionSelector = new FunctionSelector(resources.getFunctionSet()); - private ChromosomePane[] chromosomes; - private TabPane chromosomeTabs; + private PopulationPane populationPane; private GUIConsole console = new GUIConsole(); - private SettingsPane settings; + + private SettingsPane settingsPane; private boolean evolving = false; @@ -63,14 +60,14 @@ public class GUI extends Application { Task<Void> t = new Task<Void>() { @Override protected Void call() throws Exception { - while (!isCancelled() && !cgp.isFinished()) { + while (!isCancelled() && !jcgp.isFinished()) { synchronized (printLock) { Platform.runLater(consoleFlush); - cgp.nextGeneration(); + jcgp.nextGeneration(); printLock.wait(); } } - if (cgp.isFinished()) { + if (jcgp.isFinished()) { Platform.runLater(new Runnable() { @Override public void run() { @@ -96,84 +93,55 @@ public class GUI extends Application { }; public static void main(String[] args) { - cgp = new JCGP(); - resources = cgp.getResources(); +// jcgp = new JCGP(); +// resources = jcgp.getResources(); +// +// functionSelector = launch(); } @Override public void start(Stage primaryStage) throws Exception { - resources.setConsole(console); + jcgp.setConsole(console); /* * Instantiate the various GUI elements here. * * */ + BorderPane leftFrame = new BorderPane(); - leftPane = new BorderPane(); + populationPane = new PopulationPane(jcgp); - chromosomeTabs = new TabPane(); - chromosomeTabs.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE); - makeChromosomeTabPane(); + settingsPane = new SettingsPane(jcgp, this); - settings = new SettingsPane(cgp, this); + HorizontalDragResize.makeDragResizable(settingsPane); + VerticalDragResize.makeDragResizable(console); - leftPane.setCenter(chromosomeTabs); - leftPane.setBottom(console); + leftFrame.setCenter(populationPane); + leftFrame.setBottom(console); - window = new BorderPane(); + BorderPane experimentLayer = new BorderPane(); - window.setCenter(leftPane); - window.setRight(settings); + experimentLayer.setCenter(leftFrame); + experimentLayer.setRight(settingsPane); primaryStage.setTitle("JCGP"); - primaryStage.setScene(new Scene(window)); + Pane sceneParent = new Pane(); + experimentLayer.prefHeightProperty().bind(sceneParent.heightProperty()); + experimentLayer.prefWidthProperty().bind(sceneParent.widthProperty()); + sceneParent.getChildren().addAll(experimentLayer, functionSelector); + + primaryStage.setScene(new Scene(sceneParent)); + primaryStage.setMinWidth(800); + primaryStage.setMinHeight(600); primaryStage.show(); } - /** - * - */ - private void makeChromosomeTabPane() { - chromosomeTabs.getTabs().clear(); - - chromosomes = new ChromosomePane[cgp.getResources().getInt("popSize")]; - Tab tab; - for (int i = 0; i < chromosomes.length; i++) { - chromosomes[i] = new ChromosomePane(cgp.getPopulation().getChromosome(i), resources); - tab = new Tab("Chr " + i); - tab.setContent(chromosomes[i]); - chromosomeTabs.getTabs().add(tab); - } - } - - private void updateNodeGrids() { - for (int i = 0; i < chromosomes.length; i++) { - chromosomes[i].update(); - } - } - - private void unlockOutputs() { - for (int i = 0; i < chromosomes.length; i++) { - chromosomes[i].unlockOutputs(); - } - } - - private void relockOutputs() { - for (int i = 0; i < chromosomes.length; i++) { - chromosomes[i].relockOutputs(); - } - } - - public void disableChromosomePanes(boolean value) { - chromosomeTabs.setDisable(value); - } - public void runPause() { - if (!cgp.isFinished() && settings.areParametersValid()) { + if (!jcgp.isFinished() && settingsPane.areParametersValid()) { if (!evolving) { runningMode(true); cgpService.restart(); @@ -185,55 +153,49 @@ public class GUI extends Application { } public void step() { - if (!evolving && !cgp.isFinished() && settings.areParametersValid()) { - if (settings.isResetRequired()) { + if (!evolving && !jcgp.isFinished() && settingsPane.areParametersValid()) { + if (settingsPane.isResetRequired()) { reset(); } - unlockOutputs(); - Task<Void> task = new Task<Void>() { - @Override - protected Void call() throws Exception { - cgp.nextGeneration(); - Platform.runLater(consoleFlush); - return null; - } - }; - Thread t = new Thread(task); - t.start(); - try { - t.join(); - } catch (InterruptedException e) { - // nothing - } finally { - updateNodeGrids(); - relockOutputs(); - } + populationPane.unlockOutputs(); + + jcgp.nextGeneration(); + console.flush(); + + populationPane.updateGenes(); + populationPane.relockOutputs(); + } } public void reset() { - if (!evolving && settings.areParametersValid()) { - settings.applyParameters(); - cgp.reset(); - makeChromosomeTabPane(); - settings.revalidateParameters(); + if (!evolving && settingsPane.areParametersValid()) { + settingsPane.applyParameters(); + jcgp.reset(); + populationPane.remakeTabs(jcgp.getPopulation(), jcgp.getResources()); + settingsPane.revalidateParameters(); + console.flush(); } } private void runningMode(boolean value) { - chromosomeTabs.setDisable(value); - settings.disableSettings(value); + populationPane.setDisable(value); + settingsPane.runningMode(value); + if (value) { - unlockOutputs(); - settings.getRunButton().setText("Pause"); - if (settings.isResetRequired()) { + populationPane.unlockOutputs(); + if (settingsPane.isResetRequired()) { reset(); } } else { - updateNodeGrids(); - relockOutputs(); - settings.getRunButton().setText("Run"); + populationPane.updateGenes(); + populationPane.relockOutputs(); } evolving = value; } + + public static void updateFunctionSelector() { + functionSelector.remakeFunctions(resources.getFunctionSet()); + } + } diff --git a/src/jcgp/gui/console/Console.java b/src/jcgp/gui/console/Console.java deleted file mode 100644 index 63c7f5b..0000000 --- a/src/jcgp/gui/console/Console.java +++ /dev/null @@ -1,11 +0,0 @@ -package jcgp.gui.console; - -public interface Console { - - public void println(String s); - - public void print(String s); - - public void flush(); - -} diff --git a/src/jcgp/gui/console/GUIConsole.java b/src/jcgp/gui/console/GUIConsole.java index d8625f5..694f1a5 100644 --- a/src/jcgp/gui/console/GUIConsole.java +++ b/src/jcgp/gui/console/GUIConsole.java @@ -1,15 +1,12 @@ package jcgp.gui.console; -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.backend.resources.Console; import jcgp.gui.GUI; public class GUIConsole extends AnchorPane implements Console { - private boolean dragging; private TextArea textArea = new TextArea("Welcome to JCGP!"); private StringBuffer printBuffer = new StringBuffer(); @@ -18,8 +15,6 @@ public class GUIConsole extends AnchorPane implements Console { super(); textArea.setEditable(false); - setResizeListeners(); - AnchorPane.setTopAnchor(textArea, GUI.RESIZE_MARGIN); AnchorPane.setBottomAnchor(textArea, 0.0); AnchorPane.setRightAnchor(textArea, 0.0); @@ -32,62 +27,6 @@ public class GUIConsole extends AnchorPane implements Console { } - /** - * - */ - private void setResizeListeners() { - setOnMousePressed(new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - // ignore clicks outside of the draggable margin - if(isInDraggableZone(event)) { - dragging = true; - } - } - }); - setOnMouseDragged(new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - if(dragging) { - double newHeight = getHeight() - event.getY(); - if (newHeight >= getMinHeight()) { - setPrefHeight(newHeight); - } else { - setPrefHeight(getMinHeight()); - } - } - } - }); - setOnMouseMoved(new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - if(isInDraggableZone(event) || dragging) { - setCursor(Cursor.V_RESIZE); - } - else { - setCursor(Cursor.DEFAULT); - } - } - }); - setOnMouseReleased(new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - dragging = false; - setCursor(Cursor.DEFAULT); - } - }); - textArea.setOnMouseEntered(new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - setCursor(Cursor.DEFAULT); - } - }); - } - - private boolean isInDraggableZone(MouseEvent event) { - return event.getY() < (GUI.RESIZE_MARGIN); - } - @Override public void println(String s) { printBuffer.append("\n" + s); diff --git a/src/jcgp/gui/dragresize/HorizontalDragResize.java b/src/jcgp/gui/dragresize/HorizontalDragResize.java new file mode 100644 index 0000000..d580878 --- /dev/null +++ b/src/jcgp/gui/dragresize/HorizontalDragResize.java @@ -0,0 +1,90 @@ +package jcgp.gui.dragresize; + +import javafx.event.EventHandler; +import javafx.scene.Cursor; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.Region; +import jcgp.gui.GUI; + +/** + * + * http://andrewtill.blogspot.co.uk/2012/12/dragging-to-resize-javafx-region.html + * + * @author eddy + * + */ +public class HorizontalDragResize { + + private boolean dragging = false; + private final Region region; + + private HorizontalDragResize(Region region) { + this.region = region; + } + + public static void makeDragResizable(final Region region) { + final HorizontalDragResize dr = new HorizontalDragResize(region); + + region.setOnMousePressed(new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + dr.mousePressed(event); + } + }); + region.setOnMouseDragged(new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + dr.mouseDragged(event); + } + }); + region.setOnMouseMoved(new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + dr.mouseMoved(event); + } + }); + region.setOnMouseReleased(new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + dr.mouseReleased(); + } + }); + + } + + private void mousePressed(MouseEvent event) { + if(isInDraggableZone(event)) { + dragging = true; + } + } + + private void mouseDragged(MouseEvent event) { + if(dragging) { + double newWidth = region.getWidth() - event.getX(); + if (newWidth >= region.getMinWidth()) { + region.setPrefWidth(newWidth); + } else { + region.setPrefWidth(region.getMinWidth()); + } + } + } + + private void mouseMoved(MouseEvent event) { + if(isInDraggableZone(event) || dragging) { + region.setCursor(Cursor.H_RESIZE); + } + else { + region.setCursor(Cursor.DEFAULT); + } + } + + private void mouseReleased() { + dragging = false; + region.setCursor(Cursor.DEFAULT); + } + + private boolean isInDraggableZone(MouseEvent event) { + return event.getX() < (GUI.RESIZE_MARGIN); + } + +} diff --git a/src/jcgp/gui/dragresize/VerticalDragResize.java b/src/jcgp/gui/dragresize/VerticalDragResize.java new file mode 100644 index 0000000..32a7526 --- /dev/null +++ b/src/jcgp/gui/dragresize/VerticalDragResize.java @@ -0,0 +1,90 @@ +package jcgp.gui.dragresize; + +import javafx.event.EventHandler; +import javafx.scene.Cursor; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.Region; +import jcgp.gui.GUI; + +/** + * + * http://andrewtill.blogspot.co.uk/2012/12/dragging-to-resize-javafx-region.html + * + * @author eddy + * + */ +public class VerticalDragResize { + + private boolean dragging = false; + private final Region region; + + private VerticalDragResize(Region region) { + this.region = region; + } + + public static void makeDragResizable(final Region region) { + final VerticalDragResize dr = new VerticalDragResize(region); + + region.setOnMousePressed(new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + dr.mousePressed(event); + } + }); + region.setOnMouseDragged(new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + dr.mouseDragged(event); + } + }); + region.setOnMouseMoved(new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + dr.mouseMoved(event); + } + }); + region.setOnMouseReleased(new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + dr.mouseReleased(); + } + }); + + } + + private void mousePressed(MouseEvent event) { + if(isInDraggableZone(event)) { + dragging = true; + } + } + + private void mouseDragged(MouseEvent event) { + if(dragging) { + double newHeight = region.getHeight() - event.getY(); + if (newHeight >= region.getMinHeight()) { + region.setPrefHeight(newHeight); + } else { + region.setPrefHeight(region.getMinHeight()); + } + } + } + + private void mouseMoved(MouseEvent event) { + if(isInDraggableZone(event) || dragging) { + region.setCursor(Cursor.V_RESIZE); + } + else { + region.setCursor(Cursor.DEFAULT); + } + } + + private void mouseReleased() { + dragging = false; + region.setCursor(Cursor.DEFAULT); + } + + private boolean isInDraggableZone(MouseEvent event) { + return event.getY() < (GUI.RESIZE_MARGIN); + } + +} diff --git a/src/jcgp/gui/ChromosomePane.java b/src/jcgp/gui/population/ChromosomePane.java index b1f4bf0..cba58d2 100644 --- a/src/jcgp/gui/ChromosomePane.java +++ b/src/jcgp/gui/population/ChromosomePane.java @@ -1,19 +1,15 @@ -package jcgp.gui; +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.JCGP.Resources; import jcgp.backend.population.Chromosome; import jcgp.backend.population.Connection; import jcgp.backend.population.Input; import jcgp.backend.population.Node; -import jcgp.gui.population.GUIGene; -import jcgp.gui.population.GUIInput; -import jcgp.gui.population.GUINode; -import jcgp.gui.population.GUIOutput; +import jcgp.backend.resources.Resources; public class ChromosomePane extends ScrollPane { @@ -27,13 +23,13 @@ public class ChromosomePane extends ScrollPane { private ArrayList<Line> connectionLines; private ArrayList<GUIOutput> relock = new ArrayList<GUIOutput>(); - + private boolean target = false; public ChromosomePane(Chromosome chromosome, Resources resources) { super(); connectionLines = new ArrayList<Line>(); - + content = new Pane(); content.setId("content pane for genes"); @@ -96,8 +92,7 @@ public class ChromosomePane extends ScrollPane { } else { // something bad happened! throw new ClassCastException(); - } - + } } public boolean isTarget() { @@ -108,7 +103,7 @@ public class ChromosomePane extends ScrollPane { target = newValue; } - public void update() { + public void updateGenes() { for (int r = 0; r < guiNodes.length; r++) { for (int c = 0; c < guiNodes[r].length; c++) { guiNodes[r][c].updateLines(); @@ -119,7 +114,7 @@ public class ChromosomePane extends ScrollPane { guiOutputs[i].updateLines(); } } - + public void unlockOutputs() { relock.clear(); for (int i = 0; i < guiOutputs.length; i++) { diff --git a/src/jcgp/gui/population/FunctionSelector.java b/src/jcgp/gui/population/FunctionSelector.java new file mode 100644 index 0000000..0a9606f --- /dev/null +++ b/src/jcgp/gui/population/FunctionSelector.java @@ -0,0 +1,73 @@ +package jcgp.gui.population; + +import javafx.event.EventHandler; +import javafx.scene.control.Label; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.VBox; +import jcgp.backend.function.FunctionSet; +import jcgp.gui.GUI; + +public class FunctionSelector extends VBox { + + private GUINode target; + + public FunctionSelector(FunctionSet functionSet) { + setFillWidth(true); + setVisible(false); + setStyle("-fx-border-color: #A0A0A0; -fx-border-width: 1 1 0 1"); + + remakeFunctions(functionSet); + + addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + dismiss(); + } + }); + } + + public void remakeFunctions(final FunctionSet fs) { + getChildren().clear(); + + for (int i = 0; i < fs.getAllowedFunctionCount(); i++) { + final int index = i; + Label l = new Label(fs.getAllowedFunction(i).getName()); + l.setMaxWidth(Double.MAX_VALUE); + l.setStyle("-fx-background-color: #FFFFFF; -fx-border-color: #A0A0A0; -fx-border-width: 0 0 1 0; -fx-padding: 2"); + + l.addEventFilter(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + ((Label) event.getSource()).setStyle("-fx-background-color: " + GUI.SOFT_HIGHLIGHT_COLOUR + "; -fx-border-color: #B0B0B0; -fx-border-width: 0 0 1 0; -fx-padding: 2"); + } + }); + l.addEventFilter(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + ((Label) event.getSource()).setStyle("-fx-background-color: #FFFFFF; -fx-border-color: #A0A0A0; -fx-border-width: 0 0 1 0; -fx-padding: 2"); + } + }); + l.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + target.getGene().setFunction(fs.getAllowedFunction(index)); + target.updateFunction(); + dismiss(); + } + }); + + getChildren().add(l); + } + } + + public void relocateAndShow(MouseEvent event, GUINode node) { + relocate(event.getSceneX() - 5, event.getSceneY() - 5); + target = node; + setVisible(true); + } + + private void dismiss() { + setVisible(false); + } + +} diff --git a/src/jcgp/gui/population/GUIGene.java b/src/jcgp/gui/population/GUIGene.java index 26be2a5..6e9d098 100644 --- a/src/jcgp/gui/population/GUIGene.java +++ b/src/jcgp/gui/population/GUIGene.java @@ -1,12 +1,14 @@ package jcgp.gui.population; -import javafx.beans.property.SimpleObjectProperty; +import javafx.geometry.VPos; import javafx.scene.Group; +import javafx.scene.paint.Paint; 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.backend.population.Gene; -import jcgp.gui.ChromosomePane; enum GUIGeneState { NEUTRAL, @@ -30,27 +32,34 @@ public abstract class GUIGene extends Group { public static final double NODE_TEXT = NODE_RADIUS / 2.5; - protected Text text; - protected Circle mainCircle; + protected Text text = new Text(); + protected Circle mainCircle = new Circle(NODE_RADIUS, Paint.valueOf("white")); - protected SimpleObjectProperty<GUIGeneState> stateProperty = new SimpleObjectProperty<GUIGeneState>(GUIGeneState.NEUTRAL); + private GUIGeneState state = GUIGeneState.NEUTRAL; protected ChromosomePane parent; protected int locked = 0; - - public SimpleObjectProperty<GUIGeneState> stateProperty() { - return stateProperty; + + public GUIGene() { + text.setFont(Font.font("Arial", 12)); + text.setTextOrigin(VPos.CENTER); + text.setTextAlignment(TextAlignment.CENTER); + text.setWrappingWidth(NODE_RADIUS * 2); + text.setX(-NODE_RADIUS); + text.setVisible(true); + + mainCircle.setStroke(Paint.valueOf("black")); } public void setState(GUIGeneState newState) { - stateProperty.set(newState); - } - - public void showText(boolean value) { - text.setVisible(value); + state = newState; } + public GUIGeneState getState() { + return state; + } + public boolean isLocked() { return locked > 0; } @@ -63,6 +72,11 @@ public abstract class GUIGene extends Group { public abstract void addLocks(int value); + /** + * test + * + * @param value + */ public abstract void removeLocks(int value); public abstract void updateLines(); diff --git a/src/jcgp/gui/population/GUIInput.java b/src/jcgp/gui/population/GUIInput.java index f47186c..b4eccaa 100644 --- a/src/jcgp/gui/population/GUIInput.java +++ b/src/jcgp/gui/population/GUIInput.java @@ -1,20 +1,13 @@ package jcgp.gui.population; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; import javafx.event.EventHandler; -import javafx.geometry.VPos; import javafx.scene.input.MouseDragEvent; import javafx.scene.input.MouseEvent; import javafx.scene.paint.Paint; 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.backend.population.Input; import jcgp.backend.population.Output; -import jcgp.gui.ChromosomePane; import jcgp.gui.GUI; public class GUIInput extends GUIGene { @@ -22,23 +15,16 @@ public class GUIInput extends GUIGene { private Input input; public GUIInput(ChromosomePane parentRef, final Input input) { - + super(); + this.parent = parentRef; this.input = input; relocate(NODE_RADIUS, (input.getIndex() * (2 * NODE_RADIUS + SPACING)) + NODE_RADIUS); - mainCircle = new Circle(NODE_RADIUS, Paint.valueOf("white")); - mainCircle.setStroke(Paint.valueOf("black")); - - text = new Text("I: " + input.getIndex()); - text.setFont(Font.font("Arial", 12)); - text.setTextOrigin(VPos.CENTER); - text.setTextAlignment(TextAlignment.CENTER); - text.setWrappingWidth(NODE_RADIUS * 2); - text.setX(-NODE_RADIUS); - text.setVisible(true); + text.setText("I: " + input.getIndex()); + Circle outputSocket = new Circle(NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); outputSocket.setId(String.valueOf(0)); @@ -59,7 +45,7 @@ public class GUIInput extends GUIGene { if (event.getGestureSource() instanceof GUINode) { Connection source = ((GUINode) event.getGestureSource()).getChangingConnection(); if (input == source) { - stateProperty.set(GUIGeneState.NO_CHANGE_TARGET); + setState(GUIGeneState.NO_CHANGE_TARGET); return; } } else if (event.getGestureSource() instanceof GUIOutput) { @@ -68,7 +54,7 @@ public class GUIInput extends GUIGene { ((GUIGene) event.getSource()).setState(GUIGeneState.NO_CHANGE_TARGET); } } - stateProperty.set(GUIGeneState.TARGET); + setState(GUIGeneState.TARGET); } }); @@ -79,10 +65,10 @@ public class GUIInput extends GUIGene { // this happens even if we are the source of the drag parent.setTarget(false); if (event.isPrimaryButtonDown()) { - if (stateProperty.get() == GUIGeneState.NO_CHANGE_TARGET) { - stateProperty.set(GUIGeneState.INDIRECT_HOVER); + if (getState() == GUIGeneState.NO_CHANGE_TARGET) { + setState(GUIGeneState.INDIRECT_HOVER); } else { - stateProperty.set(GUIGeneState.NEUTRAL); + setState(GUIGeneState.NEUTRAL); ((GUIGene) event.getGestureSource()).setConnections(GUIGeneState.INDIRECT_HOVER); } } @@ -115,7 +101,7 @@ public class GUIInput extends GUIGene { } source.updateLines(); - stateProperty.set(GUIGeneState.HOVER); + setState(GUIGeneState.HOVER); } }); @@ -123,8 +109,8 @@ public class GUIInput extends GUIGene { @Override public void handle(MouseEvent event) { // cursor has entered this node without dragging, or it is dragging and this is the source - if (stateProperty.get() == GUIGeneState.NEUTRAL) { - stateProperty.set(GUIGeneState.HOVER); + if (getState() == GUIGeneState.NEUTRAL) { + setState(GUIGeneState.HOVER); } } }); @@ -133,62 +119,61 @@ public class GUIInput 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) { - stateProperty.set(GUIGeneState.NEUTRAL); + if (getState() == GUIGeneState.HOVER) { + setState(GUIGeneState.NEUTRAL); setConnections(GUIGeneState.NEUTRAL); } } }); + } + + @Override + public void setState(GUIGeneState newState) { + super.setState(newState); - stateProperty.addListener(new ChangeListener<GUIGeneState>() { - @Override - public void changed(ObservableValue<? extends GUIGeneState> observable, GUIGeneState oldValue, GUIGeneState newValue) { - - switch (newValue) { - case ACTIVE_HOVER: - if (locked > 0) { - stateProperty().set(GUIGeneState.LOCKED_HOVER); - } else { - mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); - } - break; - case FORBIDDEN_TARGET: - mainCircle.setFill(Paint.valueOf(GUI.BAD_SELECTION_COLOUR)); - break; - case LOCKED_HOVER: - mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); - break; - case HOVER: - mainCircle.setFill(Paint.valueOf(GUI.MEDIUM_HIGHLIGHT_COLOUR)); - break; - case INDIRECT_HOVER: - mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); - break; - case NEUTRAL: - if (locked > 0) { - stateProperty.set(GUIGeneState.HOVER); - } else { - mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_COLOUR)); - } - break; - case NO_CHANGE_TARGET: - parent.setTarget(true); - mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_SELECTION_COLOUR)); - break; - case SOURCE: - mainCircle.setFill(Paint.valueOf(GUI.MEDIUM_HIGHLIGHT_COLOUR)); - break; - case TARGET: - parent.setTarget(true); - mainCircle.setFill(Paint.valueOf(GUI.GOOD_SELECTION_COLOUR)); - break; - default: - break; - - } + switch (newState) { + case ACTIVE_HOVER: + if (locked > 0) { + setState(GUIGeneState.LOCKED_HOVER); + } else { + mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); } - }); - + break; + case FORBIDDEN_TARGET: + mainCircle.setFill(Paint.valueOf(GUI.BAD_SELECTION_COLOUR)); + break; + case LOCKED_HOVER: + mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); + break; + case HOVER: + mainCircle.setFill(Paint.valueOf(GUI.MEDIUM_HIGHLIGHT_COLOUR)); + break; + case INDIRECT_HOVER: + mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); + break; + case NEUTRAL: + if (locked > 0) { + setState(GUIGeneState.HOVER); + } else { + mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_COLOUR)); + } + break; + case NO_CHANGE_TARGET: + parent.setTarget(true); + mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_SELECTION_COLOUR)); + break; + case SOURCE: + mainCircle.setFill(Paint.valueOf(GUI.MEDIUM_HIGHLIGHT_COLOUR)); + break; + case TARGET: + parent.setTarget(true); + mainCircle.setFill(Paint.valueOf(GUI.GOOD_SELECTION_COLOUR)); + break; + default: + break; + + } + } @Override @@ -208,13 +193,13 @@ public class GUIInput extends GUIGene { @Override public void resetState() { - stateProperty.set(GUIGeneState.NEUTRAL); + setState(GUIGeneState.NEUTRAL); } @Override void setLocked(boolean value) { locked += value ? 1 : -1; - stateProperty.set(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); + setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); } @Override @@ -230,7 +215,7 @@ public class GUIInput extends GUIGene { @Override public void addLocks(int value) { locked += value; - stateProperty.set(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); + setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); } @Override @@ -241,7 +226,7 @@ public class GUIInput extends GUIGene { @Override public void removeLocks(int value) { locked -= value; - stateProperty.set(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.NEUTRAL); + setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.NEUTRAL); } @Override diff --git a/src/jcgp/gui/population/GUINode.java b/src/jcgp/gui/population/GUINode.java index 450647f..98ba738 100644 --- a/src/jcgp/gui/population/GUINode.java +++ b/src/jcgp/gui/population/GUINode.java @@ -1,22 +1,15 @@ package jcgp.gui.population; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; import javafx.event.EventHandler; -import javafx.geometry.VPos; 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 javafx.scene.text.Font; -import javafx.scene.text.Text; -import javafx.scene.text.TextAlignment; import jcgp.backend.population.Connection; import jcgp.backend.population.Input; import jcgp.backend.population.Node; -import jcgp.gui.ChromosomePane; import jcgp.gui.GUI; public class GUINode extends GUIGene { @@ -26,7 +19,8 @@ public class GUINode extends GUIGene { private int connectionIndex = 0; public GUINode(ChromosomePane parentRef, final Node node, Line[] connectionLines) { - + super(); + // store references this.parent = parentRef; this.node = node; @@ -46,21 +40,12 @@ public class GUINode extends GUIGene { 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()); - 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); + text.setText(node.getFunction().getName()); Circle[] sockets = new Circle[GUI.resources.getInt("arity")]; double angle, xPos, yPos; for (int l = 0; l < sockets.length; l++) { - angle = ((((double) (l + 1)) / ((GUI.resources.getDouble("arity") + 1))) * THETA) - (THETA / 2); + angle = (((l + 1) / ((GUI.resources.getDouble("arity") + 1))) * THETA) - (THETA / 2); xPos = -Math.cos(angle) * NODE_RADIUS; yPos = Math.sin(angle) * NODE_RADIUS; @@ -75,7 +60,7 @@ public class GUINode extends GUIGene { * Mouse event handlers on sockets * */ - s.addEventFilter(MouseDragEvent.DRAG_DETECTED, new EventHandler<MouseEvent>() { + 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 @@ -101,16 +86,16 @@ public class GUINode extends GUIGene { } }); - s.addEventFilter(MouseDragEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() { + s.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { // mouse was pressed on the socket - stateProperty.set(GUIGeneState.SOURCE); + setState(GUIGeneState.SOURCE); connectionIndex = index; } }); - s.addEventFilter(MouseDragEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() { + s.addEventFilter(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { if (!parent.isTarget()) { @@ -120,14 +105,14 @@ public class GUINode extends GUIGene { } }); - s.addEventFilter(MouseDragEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() { + 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); - stateProperty.set(GUIGeneState.HOVER); - } else if (stateProperty.get() == GUIGeneState.SOURCE) { + setState(GUIGeneState.HOVER); + } else if (getState() == GUIGeneState.SOURCE) { // no connection has been made, fallback resetState(); updateLines(); @@ -139,6 +124,14 @@ public class GUINode extends GUIGene { /* * Mouse event handlers on whole gene */ + + addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { + @Override + public void handle(MouseEvent event) { + GUI.functionSelector.relocateAndShow(event, (GUINode) event.getSource()); + } + }); + addEventFilter(MouseDragEvent.MOUSE_DRAG_ENTERED, new EventHandler<MouseDragEvent>() { @Override public void handle(MouseDragEvent event) { @@ -149,12 +142,12 @@ public class GUINode extends GUIGene { Connection source = ((GUIGene) event.getGestureSource()).getChangingConnection(); if (node == source) { - stateProperty.set(GUIGeneState.NO_CHANGE_TARGET); + setState(GUIGeneState.NO_CHANGE_TARGET); } else { - stateProperty.set(GUIGeneState.TARGET); + setState(GUIGeneState.TARGET); } } else { - stateProperty.set(GUIGeneState.FORBIDDEN_TARGET); + setState(GUIGeneState.FORBIDDEN_TARGET); } } }); @@ -167,12 +160,12 @@ public class GUINode extends GUIGene { parent.setTarget(false); if (event.isPrimaryButtonDown()) { if (event.getGestureSource() == event.getSource()) { - stateProperty.set(GUIGeneState.SOURCE); + setState(GUIGeneState.SOURCE); } else { - if (stateProperty.get() == GUIGeneState.NO_CHANGE_TARGET) { - stateProperty.set(GUIGeneState.INDIRECT_HOVER); + if (getState() == GUIGeneState.NO_CHANGE_TARGET) { + setState(GUIGeneState.INDIRECT_HOVER); } else { - stateProperty.set(GUIGeneState.NEUTRAL); + setState(GUIGeneState.NEUTRAL); ((GUIGene) event.getGestureSource()).setConnections(GUIGeneState.INDIRECT_HOVER); } } @@ -210,7 +203,7 @@ public class GUINode extends GUIGene { } source.updateLines(); - stateProperty.set(GUIGeneState.HOVER); + setState(GUIGeneState.HOVER); } }); @@ -219,8 +212,8 @@ public class GUINode extends GUIGene { @Override public void handle(MouseEvent event) { // cursor has entered this node without dragging, or it is dragging and this is the source - if (stateProperty.get() == GUIGeneState.NEUTRAL) { - stateProperty.set(GUIGeneState.HOVER); + if (getState() == GUIGeneState.NEUTRAL) { + setState(GUIGeneState.HOVER); } else if (locked > 0) { setConnections(GUIGeneState.LOCKED_HOVER); } @@ -231,11 +224,11 @@ public class GUINode 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 && locked <= 0) { - stateProperty.set(GUIGeneState.NEUTRAL); + if (getState() == GUIGeneState.HOVER && locked <= 0) { + setState(GUIGeneState.NEUTRAL); setConnections(GUIGeneState.NEUTRAL); } else if (locked > 0) { - if (stateProperty.get() == GUIGeneState.SOURCE || stateProperty.get() == GUIGeneState.FORBIDDEN_TARGET) { + if (getState() == GUIGeneState.SOURCE || getState() == GUIGeneState.FORBIDDEN_TARGET) { setConnections(GUIGeneState.INDIRECT_HOVER); } else { setConnections(GUIGeneState.HOVER); @@ -249,85 +242,72 @@ public class GUINode extends GUIGene { getChildren().addAll(sockets); getChildren().addAll(output, connectionNumber); - stateProperty.addListener(new ChangeListener<GUIGeneState>() { - @Override - public void changed(ObservableValue<? extends GUIGeneState> observable, GUIGeneState oldValue, GUIGeneState newValue) { + } - switch (newValue) { - case ACTIVE_HOVER: - if (locked > 0) { - stateProperty().set(GUIGeneState.LOCKED_HOVER); - } else { - mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); - showLines(true); - } - setConnections(GUIGeneState.ACTIVE_HOVER); - break; - case LOCKED_HOVER: - mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); - break; - case FORBIDDEN_TARGET: - mainCircle.setFill(Paint.valueOf(GUI.BAD_SELECTION_COLOUR)); - break; - case HOVER: - mainCircle.setFill(Paint.valueOf(GUI.MEDIUM_HIGHLIGHT_COLOUR)); - showLines(true); - if (locked <= 0) { - setConnections(GUIGeneState.INDIRECT_HOVER); - } else { - setConnections(GUIGeneState.HOVER); - } - break; - case INDIRECT_HOVER: - mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); - break; - case NEUTRAL: - if (locked > 0) { - stateProperty.set(GUIGeneState.HOVER); - } else { - mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_COLOUR)); - showLines(false); - if (oldValue == GUIGeneState.ACTIVE_HOVER) { - setConnections(GUIGeneState.NEUTRAL); - } - } - break; - case NO_CHANGE_TARGET: - parent.setTarget(true); - mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_SELECTION_COLOUR)); - break; - case SOURCE: - mainCircle.setFill(Paint.valueOf(GUI.HARD_HIGHLIGHT_COLOUR)); - break; - case TARGET: - parent.setTarget(true); - mainCircle.setFill(Paint.valueOf(GUI.GOOD_SELECTION_COLOUR)); - break; - default: - break; + @Override + public void setState(GUIGeneState newState) { + switch (newState) { + case ACTIVE_HOVER: + if (locked > 0) { + setState(GUIGeneState.LOCKED_HOVER); + } else { + mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); + showLines(true); + } + setConnections(GUIGeneState.ACTIVE_HOVER); + break; + case LOCKED_HOVER: + mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); + break; + case FORBIDDEN_TARGET: + mainCircle.setFill(Paint.valueOf(GUI.BAD_SELECTION_COLOUR)); + break; + case HOVER: + mainCircle.setFill(Paint.valueOf(GUI.MEDIUM_HIGHLIGHT_COLOUR)); + showLines(true); + if (locked <= 0) { + setConnections(GUIGeneState.INDIRECT_HOVER); + } else { + setConnections(GUIGeneState.HOVER); + } + break; + case INDIRECT_HOVER: + mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); + break; + case NEUTRAL: + if (locked > 0) { + setState(GUIGeneState.HOVER); + } else { + mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_COLOUR)); + showLines(false); + if (getState() == GUIGeneState.ACTIVE_HOVER) { + setConnections(GUIGeneState.NEUTRAL); } } - }); - -// for (int c = 0; c < lines.length; c++) { -// final int i = c; -// node.connections().get(c).addListener(new ChangeListener<Connection>() { -// @Override -// public void changed(ObservableValue<? extends Connection> observable, -// Connection oldValue, Connection newValue) { -// updateLine(i); -// } -// }); -// } + break; + case NO_CHANGE_TARGET: + parent.setTarget(true); + mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_SELECTION_COLOUR)); + break; + case SOURCE: + mainCircle.setFill(Paint.valueOf(GUI.HARD_HIGHLIGHT_COLOUR)); + break; + case TARGET: + parent.setTarget(true); + mainCircle.setFill(Paint.valueOf(GUI.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 @@ -381,6 +361,7 @@ public class GUINode extends GUIGene { /** * 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); @@ -420,9 +401,9 @@ public class GUINode extends GUIGene { @Override public void resetState() { if (locked > 0) { - stateProperty.set(GUIGeneState.HOVER); + setState(GUIGeneState.HOVER); } else { - stateProperty.set(GUIGeneState.NEUTRAL); + setState(GUIGeneState.NEUTRAL); setConnections(GUIGeneState.NEUTRAL); } @@ -431,7 +412,7 @@ public class GUINode extends GUIGene { @Override void setLocked(boolean value) { locked += value ? 1 : -1; - stateProperty.set(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); + setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); for (int i = 0; i < lines.length; i++) { parent.getGuiGene(node.getConnection(i)).setLocked(value); @@ -441,7 +422,7 @@ public class GUINode extends GUIGene { @Override public void addLocks(int value) { locked += value; - stateProperty.set(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); + setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.ACTIVE_HOVER); for (int i = 0; i < lines.length; i++) { parent.getGuiGene(node.getConnection(i)).addLocks(value); @@ -451,7 +432,7 @@ public class GUINode extends GUIGene { @Override public void removeLocks(int value) { locked -= value; - stateProperty.set(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.NEUTRAL); + setState(locked > 0 ? GUIGeneState.HOVER : GUIGeneState.NEUTRAL); for (int i = 0; i < lines.length; i++) { parent.getGuiGene(node.getConnection(i)).removeLocks(value); diff --git a/src/jcgp/gui/population/GUIOutput.java b/src/jcgp/gui/population/GUIOutput.java index 9c5dfa5..4a12385 100644 --- a/src/jcgp/gui/population/GUIOutput.java +++ b/src/jcgp/gui/population/GUIOutput.java @@ -1,23 +1,16 @@ package jcgp.gui.population; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; import javafx.event.EventHandler; -import javafx.geometry.VPos; 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 javafx.scene.text.Font; -import javafx.scene.text.Text; -import javafx.scene.text.TextAlignment; import jcgp.backend.population.Connection; import jcgp.backend.population.Input; import jcgp.backend.population.Node; import jcgp.backend.population.Output; -import jcgp.gui.ChromosomePane; import jcgp.gui.GUI; public class GUIOutput extends GUIGene { @@ -27,7 +20,8 @@ public class GUIOutput extends GUIGene { private Output output; public GUIOutput(ChromosomePane parentRef, final Output output, Line line) { - + super(); + this.parent = parentRef; this.output = output; this.sourceLine = line; @@ -38,16 +32,7 @@ public class GUIOutput extends GUIGene { // set the line ends correctly updateLines(); - mainCircle = new Circle(NODE_RADIUS, Paint.valueOf("white")); - mainCircle.setStroke(Paint.valueOf("black")); - - text = new Text("O: " + output.getIndex()); - text.setFont(Font.font("Arial", 12)); - text.setTextOrigin(VPos.CENTER); - text.setTextAlignment(TextAlignment.CENTER); - text.setWrappingWidth(NODE_RADIUS * 2); - text.setX(-NODE_RADIUS); - text.setVisible(true); + text.setText("O: " + output.getIndex()); Circle socket = new Circle(-NODE_RADIUS, 0, SOCKET_RADIUS, Paint.valueOf("white")); socket.setId(String.valueOf(0)); @@ -62,7 +47,7 @@ public class GUIOutput extends GUIGene { * Mouse event handlers on sockets * */ - socket.addEventFilter(MouseDragEvent.DRAG_DETECTED, new EventHandler<MouseEvent>() { + 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 @@ -86,15 +71,15 @@ public class GUIOutput extends GUIGene { } }); - socket.addEventFilter(MouseDragEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() { + socket.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { // mouse was pressed on the socket - stateProperty.set(GUIGeneState.SOURCE); + setState(GUIGeneState.SOURCE); } }); - socket.addEventFilter(MouseDragEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() { + socket.addEventFilter(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { if (!parent.isTarget()) { @@ -105,14 +90,14 @@ public class GUIOutput extends GUIGene { } }); - socket.addEventFilter(MouseDragEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() { + 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(); - stateProperty.set(GUIGeneState.HOVER); - } else if (stateProperty.get() == GUIGeneState.SOURCE) { + setState(GUIGeneState.HOVER); + } else if (getState() == GUIGeneState.SOURCE) { // no connection has been made, fallback resetState(); updateLines(); @@ -129,7 +114,7 @@ public class GUIOutput extends GUIGene { @Override public void handle(MouseDragEvent event) { // the drag has entered this node, react appropriately - stateProperty.set(GUIGeneState.FORBIDDEN_TARGET); + setState(GUIGeneState.FORBIDDEN_TARGET); } }); @@ -140,9 +125,9 @@ public class GUIOutput extends GUIGene { // this happens even if we are the source of the drag if (event.isPrimaryButtonDown()) { if (event.getGestureSource() == event.getSource()) { - stateProperty.set(GUIGeneState.SOURCE); + setState(GUIGeneState.SOURCE); } else { - stateProperty.set(isLocked() ? GUIGeneState.HOVER : GUIGeneState.NEUTRAL); + setState(isLocked() ? GUIGeneState.HOVER : GUIGeneState.NEUTRAL); } } } @@ -164,7 +149,7 @@ public class GUIOutput extends GUIGene { } source.updateLines(); - stateProperty.set(GUIGeneState.HOVER); + setState(GUIGeneState.HOVER); } }); @@ -173,8 +158,8 @@ public class GUIOutput extends GUIGene { @Override public void handle(MouseEvent event) { // cursor has entered this node without dragging, or it is dragging and this is the source - if (stateProperty.get() == GUIGeneState.NEUTRAL) { - stateProperty.set(GUIGeneState.HOVER); + if (getState() == GUIGeneState.NEUTRAL) { + setState(GUIGeneState.HOVER); } } }); @@ -190,8 +175,8 @@ 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 && !isLocked()) { - stateProperty.set(GUIGeneState.NEUTRAL); + if (getState() == GUIGeneState.HOVER && !isLocked()) { + setState(GUIGeneState.NEUTRAL); setConnections(GUIGeneState.NEUTRAL); } } @@ -199,52 +184,49 @@ public class GUIOutput extends GUIGene { getChildren().addAll(mainCircle, text, socket, connectionLabel); + + } - stateProperty.addListener(new ChangeListener<GUIGeneState>() { - @Override - public void changed(ObservableValue<? extends GUIGeneState> observable, GUIGeneState oldValue, GUIGeneState newValue) { - - - switch (newValue) { - case ACTIVE_HOVER: - break; - case FORBIDDEN_TARGET: - mainCircle.setFill(Paint.valueOf(GUI.BAD_SELECTION_COLOUR)); - break; - case HOVER: - mainCircle.setFill(Paint.valueOf(GUI.MEDIUM_HIGHLIGHT_COLOUR)); - sourceLine.setVisible(true); - if (!isLocked()) { - setConnections(GUIGeneState.ACTIVE_HOVER); - } - break; - case INDIRECT_HOVER: - mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); - break; - case NEUTRAL: - mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_COLOUR)); - sourceLine.setVisible(false); - break; - case NO_CHANGE_TARGET: - mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_SELECTION_COLOUR)); - break; - case SOURCE: - mainCircle.setFill(Paint.valueOf(GUI.HARD_HIGHLIGHT_COLOUR)); - setConnections(GUIGeneState.NEUTRAL); - setConnections(GUIGeneState.INDIRECT_HOVER); - break; - case TARGET: - mainCircle.setFill(Paint.valueOf(GUI.GOOD_SELECTION_COLOUR)); - break; - default: - break; - - } + @Override + public void setState(GUIGeneState newState) { + super.setState(newState); + + switch (newState) { + case ACTIVE_HOVER: + break; + case FORBIDDEN_TARGET: + mainCircle.setFill(Paint.valueOf(GUI.BAD_SELECTION_COLOUR)); + break; + case HOVER: + mainCircle.setFill(Paint.valueOf(GUI.MEDIUM_HIGHLIGHT_COLOUR)); + sourceLine.setVisible(true); + if (!isLocked()) { + setConnections(GUIGeneState.ACTIVE_HOVER); } - }); - + break; + case INDIRECT_HOVER: + mainCircle.setFill(Paint.valueOf(GUI.SOFT_HIGHLIGHT_COLOUR)); + break; + case NEUTRAL: + mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_COLOUR)); + sourceLine.setVisible(false); + break; + case NO_CHANGE_TARGET: + mainCircle.setFill(Paint.valueOf(GUI.NEUTRAL_SELECTION_COLOUR)); + break; + case SOURCE: + mainCircle.setFill(Paint.valueOf(GUI.HARD_HIGHLIGHT_COLOUR)); + setConnections(GUIGeneState.NEUTRAL); + setConnections(GUIGeneState.INDIRECT_HOVER); + break; + case TARGET: + mainCircle.setFill(Paint.valueOf(GUI.GOOD_SELECTION_COLOUR)); + break; + default: + break; + } } - + @Override public void updateLines() { if (output.getSource() instanceof Node) { @@ -272,10 +254,10 @@ public class GUIOutput extends GUIGene { @Override public void resetState() { if (locked > 0) { - stateProperty.set(GUIGeneState.HOVER); + setState(GUIGeneState.HOVER); setConnections(GUIGeneState.HOVER); } else { - stateProperty.set(GUIGeneState.NEUTRAL); + setState(GUIGeneState.NEUTRAL); setConnections(GUIGeneState.NEUTRAL); } } @@ -318,14 +300,14 @@ public class GUIOutput extends GUIGene { public void unlock() { if (isLocked()) { setLocked(false); - stateProperty.set(GUIGeneState.NEUTRAL); + setState(GUIGeneState.NEUTRAL); setConnections(GUIGeneState.NEUTRAL); } } public void lock() { if (!isLocked()) { - stateProperty.set(GUIGeneState.HOVER); + setState(GUIGeneState.HOVER); setLocked(true); } } diff --git a/src/jcgp/gui/population/PopulationPane.java b/src/jcgp/gui/population/PopulationPane.java new file mode 100644 index 0000000..3a83a86 --- /dev/null +++ b/src/jcgp/gui/population/PopulationPane.java @@ -0,0 +1,49 @@ +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; + +public class PopulationPane extends TabPane { + + public PopulationPane(JCGP jcgp) { + super(); + + setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE); + + remakeTabs(jcgp.getPopulation(), jcgp.getResources()); + } + + public void remakeTabs(Population population, Resources resources) { + getTabs().clear(); + + Tab tab; + ChromosomePane cp; + for (int i = 0; i < resources.getInt("popSize"); i++) { + cp = new ChromosomePane(population.getChromosome(i), resources); + tab = new Tab("Chr " + i); + tab.setContent(cp); + getTabs().add(tab); + } + } + + public void updateGenes() { + for (int i = 0; i < getChildrenUnmodifiable().size(); i++) { + ((ChromosomePane) getTabs().get(i).getContent()).updateGenes(); + } + } + + public void unlockOutputs() { + for (int i = 0; i < getChildrenUnmodifiable().size(); i++) { + ((ChromosomePane) getTabs().get(i).getContent()).unlockOutputs(); + } + } + + public void relockOutputs() { + for (int i = 0; i < getChildrenUnmodifiable().size(); i++) { + ((ChromosomePane) getTabs().get(i).getContent()).relockOutputs(); + } + } +} diff --git a/src/jcgp/gui/settings/SettingsPane.java b/src/jcgp/gui/settings/SettingsPane.java index cb066b7..8c707d3 100644 --- a/src/jcgp/gui/settings/SettingsPane.java +++ b/src/jcgp/gui/settings/SettingsPane.java @@ -5,12 +5,10 @@ import java.util.ArrayList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Insets; -import javafx.scene.Cursor; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.ComboBox; import javafx.scene.control.ScrollPane; -import javafx.scene.input.MouseEvent; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; @@ -23,26 +21,21 @@ import jcgp.backend.function.FunctionSet; import jcgp.backend.modules.ea.EvolutionaryAlgorithm; import jcgp.backend.modules.fitness.FitnessFunction; import jcgp.backend.modules.mutator.Mutator; -import jcgp.backend.parameters.IntegerParameter; -import jcgp.backend.parameters.Parameter; +import jcgp.backend.resources.parameters.Parameter; import jcgp.gui.GUI; -import jcgp.gui.settings.parameters.*; +import jcgp.gui.settings.parameters.GUIParameter; public class SettingsPane extends AnchorPane { private VBox mainContainer; - private VBox bpPane, eaPane, mutatorPane, ffPane, nfPane; + private VBox baseParameterPane, eaPane, mutatorPane, ffPane, nfPane; - private Button runPause; + private Button runPause = new Button("Run"), step = new Button("Step"), reset = new Button("Reset"); private ArrayList<GUIParameter> parameters = new ArrayList<GUIParameter>(); - private boolean dragging = false; - public SettingsPane(JCGP cgp, GUI gui) { super(); - - setResizeListeners(); mainContainer = new VBox(8); mainContainer.setPadding(new Insets(5, GUI.RESIZE_MARGIN, 0, 2)); @@ -50,15 +43,13 @@ public class SettingsPane extends AnchorPane { setMinWidth(GUI.SETTINGS_WIDTH); setPrefWidth(GUI.SETTINGS_WIDTH); - initialiseBaseParameters(cgp, gui); + initialiseBaseParameters(cgp); initialiseEAParameters(cgp); initialiseMutatorParameters(cgp); - initialiseFitnessFunctionParameters(cgp); - - initialiseNodeFunctionParameters(cgp); + initialiseProblemTypeParameters(cgp, gui); createControls(cgp, gui); @@ -75,35 +66,39 @@ public class SettingsPane extends AnchorPane { getChildren().add(scroll); } - private void initialiseBaseParameters(JCGP cgp, GUI gui) { - bpPane = new VBox(2); + private void initialiseBaseParameters(JCGP cgp) { + baseParameterPane = new VBox(2); Text header = new Text("Base Parameters"); header.setFont(Font.font("Arial", 14)); header.setUnderline(true); - bpPane.getChildren().add(header); - - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("rows"), this)); - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("columns"), this)); - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("inputs"), this)); - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("outputs"), this)); - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("levelsBack"), this)); - - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("popSize"), this)); - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("generations"), this)); - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("runs"), this)); - - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("currentGen"), this)); - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("currentRun"), this)); - - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("maxFitness"), this)); - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("seed"), this)); - parameters.add(GUIParameter.create((IntegerParameter) cgp.getResources().getParameter("report"), this)); - - bpPane.getChildren().addAll(parameters); - - mainContainer.getChildren().add(bpPane); + baseParameterPane.getChildren().add(header); + + parameters.add(GUIParameter.create(cgp.getResources().getParameter("rows"), this)); + parameters.add(GUIParameter.create(cgp.getResources().getParameter("columns"), this)); + parameters.add(GUIParameter.create(cgp.getResources().getParameter("inputs"), this)); + parameters.add(GUIParameter.create(cgp.getResources().getParameter("outputs"), this)); + parameters.add(GUIParameter.create(cgp.getResources().getParameter("levelsBack"), this)); + + GUIParameter gp = GUIParameter.create(cgp.getResources().getParameter("popSize"), this); + gp.setPadding(new Insets(0, 0, 10, 0)); + parameters.add(gp); + + parameters.add(GUIParameter.create(cgp.getResources().getParameter("currentGen"), this)); + parameters.add(GUIParameter.create(cgp.getResources().getParameter("generations"), this)); + parameters.add(GUIParameter.create(cgp.getResources().getParameter("currentRun"), this)); + + gp = GUIParameter.create(cgp.getResources().getParameter("runs"), this); + gp.setPadding(new Insets(0, 0, 10, 0)); + parameters.add(gp); + + parameters.add(GUIParameter.create(cgp.getResources().getParameter("seed"), this)); + parameters.add(GUIParameter.create(cgp.getResources().getParameter("report"), this)); + parameters.add(GUIParameter.create(cgp.getResources().getParameter("maxFitness"), this)); + + baseParameterPane.getChildren().addAll(parameters); + mainContainer.getChildren().add(baseParameterPane); } private void initialiseEAParameters(final JCGP cgp) { @@ -172,10 +167,10 @@ public class SettingsPane extends AnchorPane { mainContainer.getChildren().add(mutatorPane); } - private void initialiseFitnessFunctionParameters(final JCGP cgp) { + private void initialiseProblemTypeParameters(final JCGP cgp, final GUI gui) { ffPane= new VBox(2); - Text header = new Text("Fitness Function"); + Text header = new Text("Problem type"); header.setFont(Font.font("Arial", 14)); header.setUnderline(true); @@ -200,36 +195,13 @@ public class SettingsPane extends AnchorPane { } }); - ffPane.getChildren().addAll(header, ffCBox, ffParameters); - mainContainer.getChildren().add(ffPane); - - } - - private void initialiseNodeFunctionParameters(JCGP cgp) { - nfPane = new VBox(2); - - Text header = new Text("Node Functions"); - header.setFont(Font.font("Arial", 14)); - header.setUnderline(true); - - final ComboBox<FunctionSet> nfCBox = new ComboBox<FunctionSet>(); - nfCBox.getItems().addAll(cgp.getResources().getFunctionSets()); - nfCBox.getSelectionModel().select(cgp.getResources().getFunctionSet()); - nfCBox.prefWidthProperty().bind(mainContainer.widthProperty()); - final VBox nfParameters = new VBox(); nfParameters.setSpacing(2); - refreshFunctions(cgp.getResources().getFunctionSet(), nfParameters); + refreshFunctions(cgp.getResources().getFunctionSet(), nfParameters, gui); - nfCBox.setOnAction(new EventHandler<ActionEvent>() { - @Override - public void handle(ActionEvent event) { - refreshFunctions(nfCBox.getSelectionModel().getSelectedItem(), nfParameters); - } - }); + ffPane.getChildren().addAll(header, ffCBox, ffParameters, nfParameters); + mainContainer.getChildren().add(ffPane); - nfPane.getChildren().addAll(header, nfCBox, nfParameters); - mainContainer.getChildren().add(nfPane); } private void createControls(final JCGP cgp, final GUI gui) { @@ -237,7 +209,6 @@ public class SettingsPane extends AnchorPane { controls.setFillWidth(true); final HBox flowButtons = new HBox(2); - runPause = new Button("Run"); runPause.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { @@ -245,7 +216,7 @@ public class SettingsPane extends AnchorPane { } }); - Button step = new Button("Step"); + step = new Button("Step"); step.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { @@ -253,7 +224,7 @@ public class SettingsPane extends AnchorPane { } }); - Button reset = new Button("Reset"); + reset = new Button("Reset"); reset.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { @@ -265,10 +236,8 @@ public class SettingsPane extends AnchorPane { HBox.setHgrow(runPause, Priority.ALWAYS); runPause.setMaxWidth(Double.MAX_VALUE); - HBox.setHgrow(step, Priority.ALWAYS); step.setMaxWidth(Double.MAX_VALUE); - HBox.setHgrow(reset, Priority.ALWAYS); reset.setMaxWidth(Double.MAX_VALUE); @@ -293,7 +262,7 @@ public class SettingsPane extends AnchorPane { revalidateParameters(); } - private void refreshFunctions(final FunctionSet fs, VBox vb) { + private void refreshFunctions(final FunctionSet fs, VBox vb, final GUI gui) { vb.getChildren().clear(); CheckBox cb; for (int i = 0; i < fs.getTotalFunctionCount(); i++) { @@ -309,69 +278,30 @@ public class SettingsPane extends AnchorPane { } else { fs.disableFunction(index); } + GUI.updateFunctionSelector(); } }); vb.getChildren().add(cb); + + GUI.updateFunctionSelector(); } } - private void setResizeListeners() { - setOnMousePressed(new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - if(isInDraggableZone(event)) { - dragging = true; - } - } - }); - setOnMouseDragged(new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - if(dragging) { - double newWidth = getWidth() - event.getX(); - if (newWidth >= getMinWidth()) { - setPrefWidth(newWidth); - } else { - setPrefWidth(getMinWidth()); - } - } - } - }); - setOnMouseMoved(new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - if(isInDraggableZone(event) || dragging) { - setCursor(Cursor.H_RESIZE); - } - else { - setCursor(Cursor.DEFAULT); - } - } - }); - setOnMouseReleased(new EventHandler<MouseEvent>() { - @Override - public void handle(MouseEvent event) { - dragging = false; - setCursor(Cursor.DEFAULT); - } - }); - } - - private boolean isInDraggableZone(MouseEvent event) { - return event.getX() < (GUI.RESIZE_MARGIN); - } + - public void disableSettings(boolean value) { - bpPane.setDisable(value); + public void runningMode(boolean value) { + baseParameterPane.setDisable(value); eaPane.setDisable(value); mutatorPane.setDisable(value); ffPane.setDisable(value); nfPane.setDisable(value); + step.setDisable(value); + reset.setDisable(value); + + runPause.setText(value ? "Pause" : "Run"); } /** - * Writes the GUI parameter value back to the resources parameter, - * if any changes were made. * * @return true if the experiment needs to be reset, false otherwise. */ @@ -394,8 +324,12 @@ public class SettingsPane extends AnchorPane { } public void revalidateParameters() { + runPause.setDisable(false); for (GUIParameter parameter : parameters) { parameter.validate(); + if (parameter.requiresReset()) { + runPause.setDisable(true); + } } } @@ -404,10 +338,4 @@ public class SettingsPane extends AnchorPane { parameter.applyValue(); } } - - public Button getRunButton() { - return runPause; - } - - } diff --git a/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java b/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java index fc66e7d..4339562 100644 --- a/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIBooleanParameter.java @@ -3,9 +3,8 @@ package jcgp.gui.settings.parameters; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.scene.control.CheckBox; -import jcgp.backend.parameters.BooleanParameter; -import jcgp.backend.parameters.ParameterStatus; -import jcgp.gui.GUI; +import jcgp.backend.resources.parameters.BooleanParameter; +import jcgp.backend.resources.parameters.ParameterStatus; import jcgp.gui.settings.SettingsPane; public class GUIBooleanParameter extends GUIParameter { @@ -65,15 +64,15 @@ public class GUIBooleanParameter extends GUIParameter { */ private void setValidityStyle() { if (parameter.getStatus() == ParameterStatus.INVALID) { - valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE); + valueControl.setStyle(BASE_CHECKBOX_STYLE + INVALID_PARAMETER_STYLE); valueControl.setTooltip(tooltip); tooltip.setText(parameter.getStatus().getDetails()); } else if (parameter.getStatus() == ParameterStatus.WARNING || parameter.getStatus() == ParameterStatus.WARNING_RESET) { - valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE); + valueControl.setStyle(BASE_CHECKBOX_STYLE + WARNING_PARAMETER_STYLE); valueControl.setTooltip(tooltip); tooltip.setText(parameter.getStatus().getDetails()); } else { - valueControl.setStyle(GUI.VALID_PARAMETER_STYLE); + valueControl.setStyle(BASE_CHECKBOX_STYLE + VALID_PARAMETER_STYLE); valueControl.setTooltip(null); } } diff --git a/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java b/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java index 190f4b7..eecff2d 100644 --- a/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIDoubleParameter.java @@ -8,9 +8,8 @@ import javafx.scene.control.TextField; import javafx.scene.input.KeyEvent; import javafx.scene.layout.Priority; import javafx.scene.text.Text; -import jcgp.backend.parameters.DoubleParameter; -import jcgp.backend.parameters.ParameterStatus; -import jcgp.gui.GUI; +import jcgp.backend.resources.parameters.DoubleParameter; +import jcgp.backend.resources.parameters.ParameterStatus; import jcgp.gui.settings.SettingsPane; public class GUIDoubleParameter extends GUIParameter { @@ -26,13 +25,14 @@ public class GUIDoubleParameter extends GUIParameter { name = new Text(parameter.getName()); valueControl = new TextField(String.valueOf(parameter.get())); - valueControl.setStyle(GUI.VALID_PARAMETER_STYLE); + valueControl.setStyle(VALID_PARAMETER_STYLE); ((TextField) valueControl).setAlignment(Pos.CENTER_RIGHT); setHgrow(valueControl, Priority.ALWAYS); + setHgrow(name, Priority.ALWAYS); - name.setWrappingWidth(GUI.WRAP_WIDTH); + name.wrappingWidthProperty().bind(widthProperty().divide(2)); ((TextField) valueControl).setEditable(!parameter.isMonitor()); @@ -41,6 +41,7 @@ public class GUIDoubleParameter extends GUIParameter { makeLightBinding(); } else { valueControl.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler<KeyEvent>() { + @Override public void handle( KeyEvent t ) { char ch = t.getCharacter().toCharArray()[t.getCharacter().toCharArray().length - 1]; if (!((ch >= '0' && ch <= '9') || (ch == '.' && !((TextField) valueControl).getText().contains(".")))) { @@ -101,15 +102,15 @@ public class GUIDoubleParameter extends GUIParameter { private void setValidityStyle() { if (parameter.getStatus() == ParameterStatus.INVALID) { - valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE); + valueControl.setStyle(BASE_TEXT_STYLE + INVALID_PARAMETER_STYLE); valueControl.setTooltip(tooltip); tooltip.setText(parameter.getStatus().getDetails()); } else if (parameter.getStatus() == ParameterStatus.WARNING || parameter.getStatus() == ParameterStatus.WARNING_RESET) { - valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE); + valueControl.setStyle(BASE_TEXT_STYLE + WARNING_PARAMETER_STYLE); valueControl.setTooltip(tooltip); tooltip.setText(parameter.getStatus().getDetails()); } else { - valueControl.setStyle(GUI.VALID_PARAMETER_STYLE); + valueControl.setStyle(BASE_TEXT_STYLE + VALID_PARAMETER_STYLE); valueControl.setTooltip(null); } } diff --git a/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java b/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java index a2040d7..9c84c6a 100644 --- a/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIIntegerParameter.java @@ -8,9 +8,8 @@ import javafx.scene.control.TextField; import javafx.scene.input.KeyEvent; import javafx.scene.layout.Priority; import javafx.scene.text.Text; -import jcgp.backend.parameters.IntegerParameter; -import jcgp.backend.parameters.ParameterStatus; -import jcgp.gui.GUI; +import jcgp.backend.resources.parameters.IntegerParameter; +import jcgp.backend.resources.parameters.ParameterStatus; import jcgp.gui.settings.SettingsPane; public class GUIIntegerParameter extends GUIParameter { @@ -26,13 +25,14 @@ public class GUIIntegerParameter extends GUIParameter { name = new Text(parameter.getName()); valueControl = new TextField(String.valueOf(parameter.get())); - valueControl.setStyle(GUI.VALID_PARAMETER_STYLE); + valueControl.setStyle(VALID_PARAMETER_STYLE); ((TextField) valueControl).setAlignment(Pos.CENTER_RIGHT); setHgrow(valueControl, Priority.ALWAYS); + setHgrow(name, Priority.ALWAYS); - name.setWrappingWidth(GUI.WRAP_WIDTH); + name.wrappingWidthProperty().bind(widthProperty().divide(2)); ((TextField) valueControl).setEditable(!parameter.isMonitor()); @@ -41,6 +41,7 @@ public class GUIIntegerParameter extends GUIParameter { makeLightBinding(); } else { valueControl.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler<KeyEvent>() { + @Override public void handle( KeyEvent t ) { char ch = t.getCharacter().toCharArray()[t.getCharacter().toCharArray().length - 1]; if (!(ch >= '0' && ch <= '9')) { @@ -101,15 +102,15 @@ public class GUIIntegerParameter extends GUIParameter { private void setValidityStyle() { if (parameter.getStatus() == ParameterStatus.INVALID) { - valueControl.setStyle(GUI.INVALID_PARAMETER_STYLE); + valueControl.setStyle(BASE_TEXT_STYLE + INVALID_PARAMETER_STYLE); valueControl.setTooltip(tooltip); tooltip.setText(parameter.getStatus().getDetails()); } else if (parameter.getStatus() == ParameterStatus.WARNING || parameter.getStatus() == ParameterStatus.WARNING_RESET) { - valueControl.setStyle(GUI.WARNING_PARAMETER_STYLE); + valueControl.setStyle(BASE_TEXT_STYLE + WARNING_PARAMETER_STYLE); valueControl.setTooltip(tooltip); tooltip.setText(parameter.getStatus().getDetails()); } else { - valueControl.setStyle(GUI.VALID_PARAMETER_STYLE); + valueControl.setStyle(BASE_TEXT_STYLE + VALID_PARAMETER_STYLE); valueControl.setTooltip(null); } } diff --git a/src/jcgp/gui/settings/parameters/GUIParameter.java b/src/jcgp/gui/settings/parameters/GUIParameter.java index da2fe86..6bfdf30 100644 --- a/src/jcgp/gui/settings/parameters/GUIParameter.java +++ b/src/jcgp/gui/settings/parameters/GUIParameter.java @@ -10,14 +10,22 @@ import javafx.scene.control.Control; import javafx.scene.control.Tooltip; import javafx.scene.layout.HBox; import javafx.scene.text.Text; -import jcgp.backend.parameters.BooleanParameter; -import jcgp.backend.parameters.DoubleParameter; -import jcgp.backend.parameters.IntegerParameter; -import jcgp.backend.parameters.Parameter; -import jcgp.backend.parameters.ParameterStatus; +import jcgp.backend.resources.parameters.BooleanParameter; +import jcgp.backend.resources.parameters.DoubleParameter; +import jcgp.backend.resources.parameters.IntegerParameter; +import jcgp.backend.resources.parameters.Parameter; +import jcgp.backend.resources.parameters.ParameterStatus; +import jcgp.gui.GUI; import jcgp.gui.settings.SettingsPane; public abstract class GUIParameter extends HBox { + + public static final String BASE_TEXT_STYLE = "-fx-border-color: #C9C9C9; -fx-border-radius: 2; -fx-padding: 0; "; + public static final String BASE_CHECKBOX_STYLE = "-fx-padding: 0; "; + + public static final String INVALID_PARAMETER_STYLE = "-fx-background-color: " + GUI.BAD_SELECTION_COLOUR; + public static final String WARNING_PARAMETER_STYLE = "-fx-background-color: " + GUI.NEUTRAL_SELECTION_COLOUR; + public static final String VALID_PARAMETER_STYLE = "-fx-background-color: " + GUI.NEUTRAL_COLOUR; protected Parameter parameter; protected Text name; |