0

I have a school project or something like that and I am trying to make a sign up panel for users. This panel opens when user clicks on sign up. It looks like this.

Sign Up Dialog

What I am trying to do is I want to disable that Create Button and It will be enabled only if there are 3 checks on the dialog.

I am using a GridPane on Dialog and I was thinking about returning those certain nodes (Checks which are ImageViews) at those cells and check whether the condition is true. However, I could not figure out how to return a node from GridPane. If you have any other approach for this problem it is fine too.

This is the code's relevant part.

public void SignUp(){

    //Create the custom dialog.
    Dialog signUpDialog = new Dialog();
    //Dialog Title
    signUpDialog.setTitle("Sign Up");

    //Setting "OK" button type.
    ButtonType buttonTypeCreate = new ButtonType("Create", ButtonBar.ButtonData.OK_DONE);
    //Adding Button types.
    signUpDialog.getDialogPane().getButtonTypes().addAll(buttonTypeCreate, ButtonType.CANCEL);

    //Creating the GridPane.
    GridPane gridPane = new GridPane();
    gridPane.setHgap(10);
    gridPane.setVgap(10);
    gridPane.setPadding(new Insets(20, 150, 10, 10));

    //Setting the Check Icon.
    Image imageCheck = new Image("resources/check_icon.png");
    //Setting 3 different ImageViews for Check Icon because can't add duplicates to GridPane.
    ImageView imageViewCheck1 = new ImageView(imageCheck);
    ImageView imageViewCheck2 = new ImageView(imageCheck);
    ImageView imageViewCheck3 = new ImageView(imageCheck);

    //Setting the X Icon.
    Image imageX = new Image("resources/x_icon.png");
    //Setting 3 different ImageViews for X Icon because can't add duplicates to GridPane.
    ImageView imageViewX1 = new ImageView(imageX);
    ImageView imageViewX2 = new ImageView(imageX);
    ImageView imageViewX3 = new ImageView(imageX);

    //TextField for User ID.
    TextField textFieldDialogUserID = new TextField();
    textFieldDialogUserID.setPromptText("User ID");
    textFieldDialogUserID.setAlignment(Pos.CENTER_RIGHT);

    //PasswordField for Password.
    PasswordField passwordFieldDialogPassword = new PasswordField();
    passwordFieldDialogPassword.setPromptText("Password");
    passwordFieldDialogPassword.setAlignment(Pos.CENTER_RIGHT);

    //PasswordField for Confirm Password.
    PasswordField passwordFieldDialogConfirmPassword = new PasswordField();
    passwordFieldDialogConfirmPassword.setPromptText("Confirm Password");
    passwordFieldDialogConfirmPassword.setAlignment(Pos.CENTER_RIGHT);

    gridPane.add(new Label("User ID"), 0, 0);
    gridPane.add(textFieldDialogUserID, 1, 0);

    gridPane.add(new Label("Password"), 0, 1);
    gridPane.add(passwordFieldDialogPassword, 1, 1);

    gridPane.add(new Label("Confirm Password"), 0, 2);
    gridPane.add(passwordFieldDialogConfirmPassword, 1, 2);

    gridPane.add(imageViewX1,2,0);
    gridPane.add(imageViewX2,2,1);
    gridPane.add(imageViewX3,2,2);


    signUpDialog.getDialogPane().setContent(gridPane);

    Stage signUpStage = (Stage) signUpDialog.getDialogPane().getScene().getWindow();
    signUpStage.getIcons().add(new Image("resources/application_icon.png"));

    Optional<Pair<String, String>> result = signUpDialog.showAndWait();


}
gunesevitan
  • 882
  • 10
  • 25
  • Use the bindings approach: https://stackoverflow.com/questions/23040531/how-to-disable-button-when-textfield-is-empty – Loic Mouchard Oct 04 '17 at 10:10
  • You can use bindings or you can create a boolean method that checks if User ID's `TextField` has a min length. This boolean method should also check if the two password `TextField`s have a min length and are equal. Then inside of your three `TextField`s' `onkeyReleased` you can do something like: `yourButton.disableProperty().set(yourBooleanCheckMethod());` Your button should be set to disabled from the start. – SedJ601 Oct 04 '17 at 13:31
  • Yes, I did it with 3 booleans like locks for each TextField and they will be true when the condition is met. It works fine but still the question remains unanswered tho. – gunesevitan Oct 04 '17 at 16:59

2 Answers2

1

I could not figure out how to return a node from GridPane.

    gridPane.getChildren() 

provides the list of nodes, but you already have your components textFieldDialogUserID, passwordFieldDialogPassword, passwordFieldDialogConfirmPassword.

=> Add an action listener for each of them, that checks the values when its value is changed. depending on the result, enable/disable the Create button (per default, it should be disabled).

you can have an example : http://docs.oracle.com/javafx/2/ui_controls/text-field.htm

Loic Mouchard
  • 1,121
  • 7
  • 22
  • I already have ChangeListener on those 3 fields but didnt post that part because it is too messy. First I did it that way (enable/disable button after the input is changed). The problem with that approach was in some scenarios Create Button can be enabled even though there are no 3 checks. So I have to enable it after 3 checks are present. – gunesevitan Oct 04 '17 at 09:54
  • What I'm asking is something like; if(node at row 2==checkImage){enable button} – gunesevitan Oct 04 '17 at 09:56
  • Sorry, I don't understand your comment. Did you use a common validation method that check the value of the 3 fields? – Loic Mouchard Oct 04 '17 at 09:57
  • Yes I did. TextFields and their OnChange methods are working fine. I don't have problems with them. But disabling/enabling create button inside those methods had some problems so I'm trying to enable the button after those methods called by looking at check icons. – gunesevitan Oct 04 '17 at 10:01
  • check image is not a good idea (it is a sort of hack, difficult to maintain). Prefer something link binding: https://stackoverflow.com/questions/23040531/how-to-disable-button-when-textfield-is-empty , https://stackoverflow.com/questions/23040531/how-to-disable-button-when-textfield-is-empty – Loic Mouchard Oct 04 '17 at 10:08
  • But it's not actually checking image. It's like checking the node is at that position in gridpane. But if you say so, i'll try something else. – gunesevitan Oct 04 '17 at 10:16
  • Imagine that someone need to change the viewing, let's say having a 4th column with hint (rule for password), could you easily make the change? – Loic Mouchard Oct 04 '17 at 10:23
  • Yeah, you are right. I'll do it your way. Thanks. :D – gunesevitan Oct 04 '17 at 10:39
1

Create an appropriate BooleanBinding which expresses when the button should be disabled. You can use the Bindings utility class to create the expression, including comparison, ands and ors. To make the code more readable do a static import of the functions.

Get the create button from your panel and bind the boolean expression to the disable property of your button.

If any of the values change the JavaFX framework will automatically reevaluate the bindings and update the button's state accordingly.

import static javafx.beans.binding.Bindings.*;

BooleanBinding notComplete = or(
  equal(textFieldDialogUserID.textProperty(), null),
  equal(passwordFieldDialogPassword.textProperty(), null));

Node createButton = signUpDialog.getDialogPane().lookupButton(buttonTypeCreate);
createButton.disableProperty().bind(notComplete);

You can use the same mechanism to control the visibility of each checkmark. Create a 'incomplete' BooleanBinding for each textfield and bind it with a not binding to the visible property of the checkmark. Use all these BooleanBindings in a compound or to determine the button state. This way the button state and checkmarks will always be in sync.

M. le Rutte
  • 3,525
  • 3
  • 18
  • 31
  • I did everything same except I used boolean variable instead of BooleanBinding. What is the difference? Is it worth changing? – gunesevitan Oct 05 '17 at 19:24
  • Yes: bindings (and not only boolean bindings) are *the* method in JavaFX to keep your user interface synchronized and consistent with the data model. – M. le Rutte Oct 05 '17 at 19:46