-1

I have a JavaFX program in which I am looking to assign an event handler for a button but I want the event to trigger an action in a parent unit.

I have a GridPane as my main pane. When I start my program, I have another Group of shapes (Called a Block) embedded in this gridpane at a fixed location (0,0). As part of my Block, I have a Triangle button called DownArrow. My Plan is that when this button is pressed, the Doc controller will place a new Block beneath the one where the triangle was pressed.

I am looking at using the DownArrow.setOnMouseClicked event handler and map this back to the routine in the Controller to Add a new Block... However, I need some sort of info callback to let the controller know what Block was pressed.

I'm Stumped.

I was looking at maybe creating a custom event handler that I can pass more parameters but it seems clumsy - is there something else I should be doing?

How to pass paremeter with an event in javafx?

See Code Below in full:

package editorscratchpad;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.Font;
import javafx.stage.Stage;

/**
 *
 * @author a_curley
 */
public class EditorScratchPad extends Application {

    HBox mainPanel;
    VBox flowChart;
    GridPane flowchartGrid;
    VBox controlPanel;
    Integer stepCount;
    TextField descData;

    @Override
    public void start(Stage primaryStage) {
        Button btn = new Button();
        descData = new TextField();
        stepCount = 0;

        btn.setText("Add Step");
        btn.setOnAction((ActionEvent event) -> {
            buttonClicked(event);
        });

        ScrollPane sp = new ScrollPane();
        mainPanel = new HBox(20);
        //mainPanel.setPrefWidth(400);
        controlPanel = new VBox(5);
        controlPanel.setAlignment(Pos.CENTER);

        flowChart = new VBox();
        flowChart.setPrefWidth(600);
        flowChart.setAlignment(Pos.CENTER);

        flowchartGrid = new GridPane();
        flowchartGrid.setPrefWidth(600);
        flowchartGrid.setHgap(10);
        flowchartGrid.setVgap(10);
        flowchartGrid.setPadding(new Insets(0, 10, 0, 10));

        //sp.setContent(flowChart);
        sp.setContent(flowchartGrid);

        controlPanel.getChildren().add(btn);
        controlPanel.getChildren().add(descData);
        mainPanel.getChildren().add(sp);
        mainPanel.getChildren().add(controlPanel);

        Scene scene = new Scene(mainPanel, 800, 500);
        primaryStage.sizeToScene();

        primaryStage.setTitle("Flow chart");
        primaryStage.setScene(scene);

        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    public void buttonClicked(ActionEvent event) {
        //Integer Step = stepCount*10;        
        //Integer Step = (flowChart.getChildren().size()+1)*10;
        Integer Step = (flowchartGrid.getChildren().size() + 1);
        String stateDesc = descData.getText();
        if (stateDesc.length() < 3) {
            stateDesc = "State " + Step.toString();
        }

        blockComponent newBlock = new blockComponent("S" + Integer.toString(Step * 10), stateDesc, Step); //<<<< Create the Block.
        //flowChart.getChildren().add(newBlock.getComponent());
        flowchartGrid.add(newBlock.getComponent(), 0, Step);
        System.out.println("Added S" + Integer.toString(Step * 10));
        stepCount++;
    }

    public void addNewBlock(ActionEvent event) {
        Integer Step = (flowchartGrid.getChildren().size() + 1);
        String stateDesc = "Step " + Integer.toString(Step * 10);
    }

    /**
     * Subclass representing a Block Graphics only.
     */
    public class blockComponent {

        String Name;
        String Desc;
        Integer StateNo;
        Integer XLoc;
        Integer YLoc;
        Integer blockHeight;
        Integer blockWidth;
        Integer stLabRad;

        public blockComponent(String newName, String newDesc, Integer newSt) {
            Name = newName;
            Desc = newDesc;
            StateNo = newSt;
            XLoc = 0;
            YLoc = 0;
            blockHeight = 60;
            blockWidth = 120;
            stLabRad = 10;
        }

        public blockComponent(String newName, String newDesc, Integer newSt, Integer xCoOrd, Integer yCoOrd) {
            this(newName, newDesc, newSt);
            XLoc = xCoOrd;
            YLoc = yCoOrd;
        }

        public Group getComponent() {
            Group thisGroup = new Group();
            // Define Rectangle
            Rectangle Block = new Rectangle();
            Block.setY(stLabRad);
            Block.setX(stLabRad);
            Block.setHeight(blockHeight);
            Block.setWidth(blockWidth);
            Block.setStroke(Color.BLACK);
            Block.setStrokeWidth(2);
            Block.setFill(Color.WHITESMOKE);

            // Define state label
            Circle stLab = new Circle();
            stLab.setCenterX(stLabRad);
            stLab.setCenterY(stLabRad);
            stLab.setRadius(stLabRad);
            stLab.setStroke(Color.PALEGREEN);
            stLab.setFill(Color.PALEGREEN);

            // Define State No.
            Label stNo = new Label();
            stNo.setFont(Font.font("Impact"));
            stNo.setTextFill(Color.WHITE);
            stNo.setLayoutX(0);
            stNo.setLayoutY(0);
            stNo.setText(StateNo.toString());

            // Define the description
            Label stD = new Label();
            stD.setFont(Font.font("Impact"));
            stD.setTextFill(Color.BLACK);
            stD.setLayoutX(15);
            stD.setLayoutY(15);
            stD.setText(Desc.toString());

            //---- Three Triangles for drawing. ----
            // Down Arrow
            Polygon downArrow = new Polygon();
            downArrow.getPoints().addAll(new Double[]{
                //X                                         //Y
                (blockWidth.doubleValue() / 2) + stLabRad, (blockHeight.doubleValue()),
                ((blockWidth.doubleValue() / 2) + 10) + stLabRad, (blockHeight.doubleValue() - 10),
                ((blockWidth.doubleValue() / 2) - 10) + stLabRad, (blockHeight.doubleValue() - 10)
//                70.0,60.0,
//                60.0,50.0,
//                80.0,50.0
            });
            downArrow.setStroke(Color.BLACK);
            downArrow.setStrokeWidth(1);
            downArrow.setFill(Color.LIGHTCYAN);
            downArrow.setOnMouseEntered(new EventHandler<MouseEvent>() {
                public void handle(MouseEvent me) {
                    downArrow.setStroke(Color.BLACK);
                    downArrow.setFill(Color.LIGHTCYAN);
                }
            });
            downArrow.setOnMouseExited(new EventHandler<MouseEvent>() {
                public void handle(MouseEvent me) {
                    downArrow.setStroke(Color.WHITESMOKE);
                    downArrow.setFill(Color.WHITESMOKE);
                }
            });

            // try: https://stackoverflow.com/questions/35372236/how-to-pass-paremeter-with-an-event-in-javafx
            //add all components to the group to display
            thisGroup.getChildren().add(Block);
            thisGroup.getChildren().add(stD);
            thisGroup.getChildren().add(stLab);
            thisGroup.getChildren().add(stNo);
            thisGroup.getChildren().add(downArrow);
            return thisGroup;
        }
    }

}
deadlyBuzz
  • 125
  • 2
  • 11
  • 1
    Have you tried `event.getSource()` and retrieve info about it, like `((Button) event.getSource()).getText()`? – 0009laH Sep 30 '20 at 10:43
  • [mcve] - strip it down to the barest minimum to demonstrate what you are after (no need for going fancy with fonts ans similar unrelated stuff). And stick to java naming conventions! – kleopatra Sep 30 '20 at 10:53
  • all that said: why do you need the event at all? just expose api to do what you need and let the button's action use that api .. – kleopatra Sep 30 '20 at 10:56
  • 1
    I'll try getSource thank you 0009lah – deadlyBuzz Sep 30 '20 at 14:32
  • I'm not sure what angle to approach @kleopatra so I canont provide a simple example. To give an example of what the blocks produce I included the whole routine. I appreciate it might be too much but its small enough so I thought it was more helpful to include it. – deadlyBuzz Sep 30 '20 at 14:35

1 Answers1

0

Not sure if this was the correct approach I was looking for but @0009laH response above for getSource() was the best that worked for me.

deadlyBuzz
  • 125
  • 2
  • 11