On javafx dialog action edit parent stage elements

你说的曾经没有我的故事 提交于 2019-12-11 09:53:42

问题


I have a JavaFX application with two buttons: "Edit" and "Save" and a textfield "textField1".

Initially the textfield "textField1" and the "Save" button are disabled (fxml build with scene builder, so editable is set to false over there).

When a user clicks the button "Edit" a login dialog pop ups. If the user enters the correct credentials then i want to hide the popup and unlock (editable) both textfield "textField1" and button "Save" so the user could be able to edit textfields value and save it to the database.

After saving i would like to lock again (not editable) "Save" button and textfield "textField1".

Here is my Main application class:

public class Main extends Application {
    ...
    private Stage theStage;
    ...
    public static void main(String[] args) throws IOException {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws IOException {
        //setTheStage(primaryStage);
        try {
            AnchorPane page = (AnchorPane) FXMLLoader.load(Main.class.getResource("FXMLDocument.fxml"));
            Scene scene = new Scene(page, initWidth, initHeight);
            primaryStage.setScene(scene);

            currentPane(scene, page);

            primaryStage.show();

        } catch (IOException ex) {
            log.log(Level.INFO, null, ex);            
        }
    }

Here is my main scene (FXMLDocument.fxml controller):

public class FXMLDocumentController implements Initializable {
    @FXML
    private Button save;
    @FXML 
    private Button edit;
    @FXML
    private TextField textField1;
    ...
    private Stage primaryStage;
    @Override
    @FXML
    public void initialize(URL url, ResourceBundle rb) {
        ...
        //to do?
    }
    ...
    //edit button action
    @FXML
    private void onConfigParametersEdit(ActionEvent event) throws IOException, SchedulerException {

        log.info("You clicked me!");
        FXMLLoader fl = new FXMLLoader();
        fl.setLocation(getClass().getResource("LoginDialog.fxml"));
        fl.load();
        Parent root = fl.getRoot();

        Stage modal_dialog = new Stage(StageStyle.DECORATED);
        modal_dialog.initModality(Modality.WINDOW_MODAL);
        modal_dialog.initOwner(primaryStage);
        Scene scene = new Scene(root);

        LoginDialogController t1 = (LoginDialogController)fl.getController();
        t1.setStage(modal_dialog);
        modal_dialog.setScene(scene);
        modal_dialog.show();
    }

    public void onConfigParametersSave(ActionEvent event) throws IOException {
        String textField1Str = textField1.getText();
        //some code to save it to the database
    }
    ...
}

And finally here is the LoginDialog.fxml controller:

public class LoginDialogController implements Initializable {

    @FXML
    private Button login;
    @FXML 
    private Button cancel;

    @FXML
    private TextField username;
    @FXML
    private TextField password;

    private Stage parentStage;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        //to do
    }

    void setStage(Stage temp) {
         parentStage = temp;
    }

    @FXML
    private void onCancelActionEvent(ActionEvent event) {
        log.info("You clicked cancel!");
        parentStage.close();
    }

    @FXML
    private void onLoginActionEvent(ActionEvent event) {
        String usernameStr = username.getText();
        String passwordStr = password.getText();
        log.info("You have entered username: " + usernameStr + " and password: " + passwordStr);
        if(usernameStr.equals("admin") && passwordStr.equals("admin")) {
            log.info("login correct");
            parentStage.close();
            // how am i going to unlock Save button & textField1 into my "parent" scene?
        } else {
            log.info("login error");
        }
    }

The question is how am i going to go back to FXMLDocument.fxml and unlock Save button and textField1 after succesfull login?


回答1:


There are few ways to do it. This one suggests you to create an extra field in your LoginDialogController which keeps the state of whether the user credentials are correct or not and bind it to the controls already defined in FXMLDocumentController.

public class LoginDialogController implements Initializable {

   ...
   private BooleanProperty loginSuccessful = new SimpleBooleanProperty();

   public loginSuccessfulProperty() {
        return loginSuccessful;
   }

   ...

}

Then when the user successfully logs in update this field.

@FXML
private void onLoginActionEvent(ActionEvent event) {
    ...
    if(usernameStr.equals("admin") && passwordStr.equals("admin")) {
        log.info("login correct");
        parentStage.close();
        loginSuccessful.set(true);
    } else {
        log.info("login error");
    }
}

From your FXMLDocumentController, let the controls editableProperty() bind to this newly defined propety.

public class FXMLDocumentController implements Initializable {

    private void onConfigParametersEdit(ActionEvent event) 
         LoginDialogController t1 = (LoginDialogController)fl.getController();
        t1.setStage(modal_dialog);
        textField1.editableProperty().bind(t1.loginSuccessfulProperty());
        save.editableProperty().bind(t1.loginSuccessfulProperty());
    }
}



回答2:


OK I do not know if it is optimum solution however i managed to bind textField1 textField and Save button between these two scenes and achieve requested funcionality this way:

In FXMLDocument.fxml Controller i added:

@FXML
private void onConfigParametersEdit(ActionEvent event) throws IOException, SchedulerException {

    scheduler.shutdown();

    log.info("You clicked me!");
    FXMLLoader fl = new FXMLLoader();
    fl.setLocation(getClass().getResource("LoginDialog.fxml"));
    fl.load();
    Parent root = fl.getRoot();

    Stage modal_dialog = new Stage(StageStyle.DECORATED);
    modal_dialog.initModality(Modality.WINDOW_MODAL);
    modal_dialog.initOwner(primaryStage);
    Scene scene = new Scene(root);

    LoginDialogController t1 = (LoginDialogController)fl.getController();

    //added these two lines to bind 2nd controller property values
    t1.save2nd = save;
    t1.textField12nd = textField1;

    t1.setStage(modal_dialog);
    modal_dialog.setScene(scene);
    modal_dialog.show();

}

And in the second controller i just added two properties: textField1 and save2nd and setDisable(false) on succesfull login:

public class LoginDialogController implements Initializable {
    ...
    //just adding the additional fields - other remains the same
    public Button save2nd;
    public TextField workstationIp2nd;
    ...
    @FXML
    private void onLoginActionEvent(ActionEvent event) {

        String usernameStr = username.getText();
        String passwordStr = password.getText();
        log.info("You have entered username: " + usernameStr + " and password: " + passwordStr);
        if(usernameStr.equals("admin") && passwordStr.equals("admin")) {
            log.info("login correct");

            save2nd.setDisable(false);
            workstationIp2nd.setDisable(false);

            parentStage.close();

        } else {
            log.info("login error");
        }
    }


来源:https://stackoverflow.com/questions/33169334/on-javafx-dialog-action-edit-parent-stage-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!