I am trying to create my very first application in JavaFX and I have a problem with Button that calls a method (for example to open another window) - I always have to click it twice in order to trigger action.
Here's my code from the Controller:
import javafx.fxml.FXML;
import javafx.scene.control.Button;
public class ControllerSignIn {
@FXML
private Button forgot;
@FXML
private Button back;
@FXML
private Button signin;
public void forgetPasswordClicked() {
forgot.setOnAction(e -> ForgotPassword.setUpWindow()); //works on 2nd click
}
public void backClicked() {
back.setOnAction(e -> ForgotPassword.closeWindow()); //works on 2nd click
}
public void signInClicked() {
System.out.println("Sign In CLICKED"); //works on first click
}
}
My methods are implemented here:
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
public class ForgotPassword {
static Stage window;
static Scene scene;
static Parent root;
private static void loadFXML() {
try {
root = FXMLLoader.load(ForgotPassword.class.getResource("ForgotPassword.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void setUpWindow() {
loadFXML();
scene = new Scene(root);
scene.getStylesheets().add("signin/SignIn.css");
window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle("Forgot Password?");
window.setScene(scene);
window.showAndWait();
}
public static void closeWindow() {
window.close();
}
}
Most likely you have the following in your FXML:
This makes your button
forgot
call your methodforgetPasswordClicked()
. But instead of defining your logic to be executed when your button is clicked, the first time you say: "When this button is clicked, place anaction event
on my button which will callsetUpWindow()
"Therefore, your first click "sets up" the logic of your button. The second click, actually executes it. To solve this, either immediately use your logic as such:
or don't define the method to be called in your fxml, and move the initialization of your button (setting the action listener) to your initialization as following:
This is also why your
signInClicked()
method works from the first click, because it actually executes the logic instead of setting up the handler first.