JavaFX button reacting on second click not first

2019-01-27 11:37发布

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();
    }
}

1条回答
一纸荒年 Trace。
2楼-- · 2019-01-27 12:11

Most likely you have the following in your FXML:

<Button fx:id="forgot" onAction="#forgetPasswordClicked" />

This makes your button forgot call your method forgetPasswordClicked(). 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 an action event on my button which will call setUpWindow()"

forgot.setOnAction(e -> ForgotPassword.setUpWindow());

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:

public void forgetPasswordClicked() {
    ForgotPassword.setUpWindow();
}

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:

public class ControllerSignIn implements Initializable {
    @FXML
    private Button forgot;
    @FXML
    private Button back;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        forgot.setOnAction(e -> ForgotPassword.setUpWindow());
        back.setOnAction(e -> ForgotPassword.closeWindow());
    }
}

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.

查看更多
登录 后发表回答