-2

I want something similar to this:

public void changeSceneOnBtnClick(ActionEvent event, String fxmlFile, TextField playerName){ 
...
...
}

@FXML Button button;
button.setOnAction(changeSceneOnBtnClick(event, "stage1.fxml", playerName1));

but the only parameter allowed in the setOnAction-method is the event. My goal is to use the function with parameters to prevent duplicate code that only has some values changed like the fxml-filename.

  • 4
    This does not make any sense. There is no need to pass any other parameters in this case. If you want to use variables in the setOnAction method, make sure they are final or effectively final. – SedJ601 Jun 14 '22 at 18:41
  • 2
    You also may need to give your variables a wider scope. Given the limited code you provided, it's hard to give any direct answer. – SedJ601 Jun 14 '22 at 18:43
  • 3
    This is just plain wrong. You can do `button.setOnAction(event -> { /* arbitrary code here */});`. So, e.g. `button.setOnAction(event -> changeSceneOnBtnClick(event, "stage1.fxml", playerName1));` You probably don't need your method to have an `ActionEvent` parameter, as you probably aren't using it in this context. – James_D Jun 14 '22 at 19:07

1 Answers1

2

…the only parameter allowed in the setOnAction() method is the event.

No: the sole parameter to the setOnAction() method is an EventHandler, a functional interface defining a method that will be invoked whenever the button is fired. That method, named handle(), will receive an ActionEvent as its parameter when called.

Is there a way to pass additional parameters to the setOnAction method?

Yes: given a method with parameters such as this:

private void changeSceneOnBtnClick(ActionEvent event,
    String fileName, TextField playerName) {
    …
}

You can tell the button to invoke that method with parameters when clicked like this:

button.setOnAction((event) -> changeSceneOnBtnClick(
    event, "stage1.fxml", new TextField("Player 1")));

As outlined here, this is shorthand for this:

button.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        changeSceneOnBtnClick(
            event, "stage1.fxml", new TextField("Player 1"));
    }
});

Maybe: although I haven't seen a use-case for it, you can also aggregate attributes in your own EventHandler and use it like this:

button.setOnAction(new MyEventHandler("stage1.fxml", new TextField("Player 1")));
…
private static final class MyEventHandler implements EventHandler<ActionEvent> {

    private final String fileName;
    private final TextField playerName;

    public MyEventHandler(String fileName, TextField playerName) {
        this.fileName = fileName;
        this.playerName = playerName;
    }

    @Override
    public void handle(ActionEvent event) {
        …
    }
}

Definitely: review your design critically, knowing that many schemes end up in the trash. Search for designs that meet your goals: for example, study this approach to adding nodes dynamically.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045