Bruno Battaglia Bruno Battaglia - 5 months ago 44
Java Question

Lambda function in JavaFX8

I'm working to an invader game in JavaFX with Scene Builder (I have to shoot planes whit a cannon) but I have got problems with lambda function. I'm sure code is right because if I associate the code through Scene Builder's option (On action) it works, but, when I try to use lambda function, I can't change my scene. Where am I wrong?

public class SchermataGiocoController {

private Parent Menu, Avvio;
private TranslateTransition tt;
private Cannone cannone; //cannone = cannon
private Aereo aereo; //aereo = plane
private Proiettile proiettile; //proiettile = bullet
private RotateTransition rt;

@FXML
private Button down;

@FXML
private Circle circle;

@FXML
private Button su;

@FXML
private Button exit;

@FXML
private ImageView cannone_im;

@FXML
private AnchorPane SchermataGioco;

@FXML
private ImageView aereo_im;

@FXML
private Button menu;

@FXML
private Button home;

@FXML
void initialize() {
assert exit != null : "fx:id=\"exit\" was not injected: check your FXML file 'SchermataGioco.fxml'.";
assert cannone_im != null : "fx:id=\"cannone_im\" was not injected: check your FXML file 'SchermataGioco.fxml'.";
assert su != null : "fx:id=\"su\" was not injected: check your FXML file 'SchermataGioco.fxml'.";
assert SchermataGioco != null : "fx:id=\"SchermataGioco\" was not injected: check your FXML file 'SchermataGioco.fxml'.";
assert aereo_im != null : "fx:id=\"aereo_im\" was not injected: check your FXML file 'SchermataGioco.fxml'.";
assert menu != null : "fx:id=\"menu\" was not injected: check your FXML file 'SchermataGioco.fxml'.";
assert down != null : "fx:id=\"down\" was not injected: check your FXML file 'SchermataGioco.fxml'.";
assert home != null : "fx:id=\"home\" was not injected: check your FXML file 'SchermataGioco.fxml'.";
cannone = new Cannone(141, 104, 14, 362);
proiettile = new Proiettile(16, 16, 14, 362);
TranslateTransition();
}


@FXML
public void vaiMenu() {
menu.setOnAction((ActionEvent event) -> {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Game.class.getResource("/game/view/Menu.fxml"));
Menu = (Parent) loader.load();
menu.getScene().getWindow().hide();
} catch (IOException ioe) {
ioe.getMessage();
}
Stage stage = new Stage();
stage.setScene(new Scene(Menu));
stage.show();
});
}

Answer

If you associate vaiMenu() with the "On Action" in SceneBuilder, then (as it is expected), on e.g. when a click is performed on the Button, the vaiMenu() method will be executed, which will just do: assign a listener (through your lambda) for the action event of the Button, therefore it never will be executed, just added again-and-again.

If you want to assign the listener through SceneBuilder like:

<Button fx:id="menu" onAction="#vaiMenu" />

you cannot use lambdas (anonymous functions) as you need a named function to be referenced in your FXML file (in the onAction attribute).

If you insert your current lambda in e.g. the initialize() method of your controller, it will work without any problems, but in this case you shall not define this attribute in your FXML file.