thanili
thanili

Reputation: 617

On javafx dialog action edit parent stage elements

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?

Upvotes: 1

Views: 1117

Answers (2)

ItachiUchiha
ItachiUchiha

Reputation: 36792

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

Upvotes: 2

thanili
thanili

Reputation: 617

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

Upvotes: 0

Related Questions