package jcgp.gui.settings; import java.util.ArrayList; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import javafx.beans.property.SimpleIntegerProperty; 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; import javafx.scene.layout.VBox; import javafx.scene.text.Font; import javafx.scene.text.FontSmoothingType; import javafx.scene.text.Text; import jcgp.GUI; import jcgp.JCGP; import jcgp.function.FunctionSet; import jcgp.gui.settings.parameters.*; import jcgp.modules.ea.EvolutionaryAlgorithm; import jcgp.modules.fitness.FitnessFunction; import jcgp.modules.mutator.Mutator; import jcgp.parameters.*; public class SettingsPane extends AnchorPane { private VBox mainContainer; private VBox bpPane, eaPane, mutatorPane, ffPane, nfPane; private ArrayList parameters = new ArrayList(); 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)); setMinWidth(GUI.SETTINGS_WIDTH); setPrefWidth(GUI.SETTINGS_WIDTH); initialiseBaseParameters(cgp, gui); initialiseEAParameters(cgp); initialiseMutatorParameters(cgp); initialiseFitnessFunctionParameters(cgp); initialiseNodeFunctionParameters(cgp); createControls(cgp, gui); ScrollPane scroll = new ScrollPane(); scroll.setFitToWidth(true); scroll.setContent(mainContainer); scroll.setStyle("-fx-background-color: #FFFFFF"); AnchorPane.setTopAnchor(scroll, 0.0); AnchorPane.setBottomAnchor(scroll, 0.0); AnchorPane.setRightAnchor(scroll, 0.0); AnchorPane.setLeftAnchor(scroll, GUI.RESIZE_MARGIN); getChildren().add(scroll); } private void initialiseBaseParameters(JCGP cgp, GUI gui) { bpPane = new VBox(2); Text header = new Text("Base Parameters"); header.setFont(Font.font("Arial", 14)); header.setUnderline(true); bpPane.getChildren().add(header); final GUIIntegerParameter generation = new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("currentGen")); final GUIIntegerParameter run = new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("currentRun")); parameters.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("rows"))); parameters.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("columns"))); parameters.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("inputs"))); parameters.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("outputs"))); parameters.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("levelsBack"))); parameters.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("popSize"))); parameters.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("generations"))); parameters.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("runs"))); parameters.add(generation); parameters.add(run); parameters.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("seed"))); parameters.add(new GUIIntegerParameter((IntegerParameter) cgp.getResources().getParameter("report"))); parameters.add(new GUIBooleanParameter((BooleanParameter) cgp.getResources().getParameter("verbose"))); bpPane.getChildren().addAll(parameters); mainContainer.getChildren().add(bpPane); generation.getTextField().textProperty().bind(((SimpleIntegerProperty) cgp.getResources().getParameter("currentGen").valueProperty()).asString()); } private void initialiseEAParameters(final JCGP cgp) { eaPane = new VBox(2); Text header = new Text("Evolutionary Algorithm"); header.setFont(Font.font("Arial", 14)); header.setUnderline(true); final ComboBox eaCBox = new ComboBox(); eaCBox.getItems().addAll(cgp.getEvolutionaryAlgorithms()); eaCBox.getSelectionModel().select(cgp.getEvolutionaryAlgorithm()); eaCBox.prefWidthProperty().bind(mainContainer.widthProperty()); final VBox eaParameters = new VBox(); eaParameters.setSpacing(2); if (cgp.getEvolutionaryAlgorithm().getLocalParameters() != null) { refreshParameters(cgp.getEvolutionaryAlgorithm().getLocalParameters().entrySet().iterator(), eaParameters); } eaCBox.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { cgp.setEvolutionaryAlgorithm(eaCBox.getSelectionModel().getSelectedIndex()); if (eaCBox.getSelectionModel().getSelectedItem().getLocalParameters() != null) { refreshParameters(eaCBox.getSelectionModel().getSelectedItem().getLocalParameters().entrySet().iterator(), eaParameters); } } }); eaPane.getChildren().addAll(header, eaCBox, eaParameters); mainContainer.getChildren().add(eaPane); } private void initialiseMutatorParameters(final JCGP cgp) { mutatorPane = new VBox(2); Text header = new Text("Mutator"); header.setFontSmoothingType(FontSmoothingType.LCD); header.setFont(Font.font("Arial", 14)); header.setUnderline(true); final ComboBox mutatorCBox = new ComboBox(); mutatorCBox.getItems().addAll(cgp.getMutators()); mutatorCBox.getSelectionModel().select(cgp.getMutator()); mutatorCBox.prefWidthProperty().bind(mainContainer.widthProperty()); final VBox mutatorParameters = new VBox(); mutatorParameters.setSpacing(2); if (cgp.getEvolutionaryAlgorithm().getLocalParameters() != null) { refreshParameters(cgp.getMutator().getLocalParameters().entrySet().iterator(), mutatorParameters); } mutatorCBox.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { cgp.setEvolutionaryAlgorithm(mutatorCBox.getSelectionModel().getSelectedIndex()); if (mutatorCBox.getSelectionModel().getSelectedItem().getLocalParameters() != null) { refreshParameters(mutatorCBox.getSelectionModel().getSelectedItem().getLocalParameters().entrySet().iterator(), mutatorParameters); } } }); mutatorPane.getChildren().addAll(header, mutatorCBox, mutatorParameters); mainContainer.getChildren().add(mutatorPane); } private void initialiseFitnessFunctionParameters(final JCGP cgp) { ffPane= new VBox(2); Text header = new Text("Fitness Function"); header.setFont(Font.font("Arial", 14)); header.setUnderline(true); final ComboBox ffCBox = new ComboBox(); ffCBox.getItems().addAll(cgp.getFitnessFunctions()); ffCBox.getSelectionModel().select(cgp.getFitnessFunction()); ffCBox.prefWidthProperty().bind(mainContainer.widthProperty()); final VBox ffParameters = new VBox(); ffParameters.setSpacing(2); if (cgp.getFitnessFunction().getLocalParameters() != null) { refreshParameters(cgp.getFitnessFunction().getLocalParameters().entrySet().iterator(), ffParameters); } ffCBox.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { cgp.setEvolutionaryAlgorithm(ffCBox.getSelectionModel().getSelectedIndex()); if (ffCBox.getSelectionModel().getSelectedItem().getLocalParameters() != null) { refreshParameters(ffCBox.getSelectionModel().getSelectedItem().getLocalParameters().entrySet().iterator(), ffParameters); } } }); 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 nfCBox = new ComboBox(); 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); nfCBox.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { refreshFunctions(nfCBox.getSelectionModel().getSelectedItem(), nfParameters); } }); nfPane.getChildren().addAll(header, nfCBox, nfParameters); mainContainer.getChildren().add(nfPane); } private void createControls(final JCGP cgp, final GUI gui) { final VBox controls = new VBox(2); controls.setFillWidth(true); final HBox flowButtons = new HBox(2); final Button play = new Button("Run"); play.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { gui.playPause(); if (gui.isEvolving()) { play.setText("Pause"); } else { play.setText("Run"); } } }); Button step = new Button("Step"); step.setOnAction(new EventHandler() { @Override public void handle(ActionEvent event) { gui.step(); } }); flowButtons.getChildren().addAll(play, step); HBox.setHgrow(play, Priority.ALWAYS); play.setMaxWidth(Double.MAX_VALUE); HBox.setHgrow(step, Priority.ALWAYS); step.setMaxWidth(Double.MAX_VALUE); controls.getChildren().add(flowButtons); mainContainer.getChildren().add(controls); } /** * @param cgp * @param vb */ private void refreshParameters(Iterator> it, VBox vb) { parameters.removeAll(vb.getChildren()); vb.getChildren().clear(); while (it.hasNext()) { Parameter parameter = ((Map.Entry) it.next()).getValue(); if (parameter instanceof IntegerParameter) { GUIIntegerParameter gip = new GUIIntegerParameter((IntegerParameter) parameter); parameters.add(gip); vb.getChildren().add(gip); } else if (parameter instanceof DoubleParameter) { GUIDoubleParameter gdp = new GUIDoubleParameter((DoubleParameter) parameter); parameters.add(gdp); vb.getChildren().add(gdp); } else if (parameter instanceof BooleanParameter) { GUIBooleanParameter gbp = new GUIBooleanParameter((BooleanParameter) parameter); parameters.add(gbp); vb.getChildren().add(gbp); } } } private void refreshFunctions(final FunctionSet fs, VBox vb) { vb.getChildren().clear(); CheckBox cb; for (int i = 0; i < fs.getTotalFunctionCount(); i++) { cb = new CheckBox(fs.getFunction(i).getName()); cb.setId(String.valueOf(i)); cb.setSelected(fs.isEnabled(fs.getFunction(i))); 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); } public void refreshValues() { for (GUIParameter parameter : parameters) { parameter.refreshValue(); } //parent.updateNodeGrids(); } // public void bindParameters() { // for (GUIParameter parameter : parameters) { // parameter.doBindings(); // } // } // // public void unbindParameters() { // for (GUIParameter parameter : parameters) { // parameter.undoBindings(); // } // } public void toggleSettings(boolean value) { bpPane.setDisable(value); eaPane.setDisable(value); mutatorPane.setDisable(value); ffPane.setDisable(value); nfPane.setDisable(value); } }