Master Noob
Master Noob

Reputation: 715

Accessing the OK button from inside the dialog controller [javaFX]

I am trying to disable the OK button in a javaFX dialog untill all of the text fields have content.

Due to the ButtonType not having FXML support it has to be added to the Dialog in the Controller class of the main Window. due to this I'm unable to (cant find a way) to link the button to a variable inside the dialog controller.

I have tried handling the process in the main Controller class as follows:

FXMLLoader loader = new FXMLLoader();
    loader.setLocation(getClass().getResource("addDialog.fxml")); 

    try {

        dialog.getDialogPane().setContent(loader.load());

    } catch(IOException e) {

        e.getStackTrace();

    }

    dialog.getDialogPane().getButtonTypes().add(ButtonType.OK);
    dialog.getDialogPane().getButtonTypes().add(ButtonType.CANCEL);

    dialog.getDialogPane().lookupButton(ButtonType.OK).setDisable(true);

    AddDialogController controller = loader.getController();

    // below calls on a getter from the addDialogController.java file to check if the input fields are full

    if (controller.getInputsFull()) {
        dialog.getDialogPane().lookupButton(ButtonType.OK).setDisable(false);
    }

unfortunately this didn't work, the above code can only be run once before or after the window is called and cant run during.

so is there a way to access the OK ButtonType that comes with javaFX inside the dialog controller if it has been declared outside?

Or is there another way to disable the button based of information from the dialog controller that is being updated by the user?

thanks for any help

Edit 1:

As requested the addDialogController, this is very bare bones and incomplete, hopefully it helps:

import data.Contact;
import data.ContactData;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;

public class AddDialogController {
    @FXML
    private TextField firstNameField;

    @FXML
    private TextField lastNameField;

    @FXML
    private TextField numberField;

    @FXML
    private TextArea notesArea;

    private boolean inputsFull;

    public void processResults() {
        String first = firstNameField.getText().trim();
        String last = lastNameField.getText().trim();
        String number =  numberField.getText().trim();
        String notes = notesArea.getText().trim();

        Contact contact = new Contact(first, last, number, notes);

    //      ContactData.add(contact);
    }



    @FXML
    public void handleKeyRelease() {
        boolean firstEmpty  = firstNameField.getText().trim().isEmpty() && firstNameField.getText().isEmpty();
        boolean lastEmpty  = lastNameField.getText().trim().isEmpty() && lastNameField.getText().isEmpty();
        boolean numberEmpty  = numberField.getText().trim().isEmpty() && numberField.getText().isEmpty();
        boolean notesEmpty  = notesArea.getText().trim().isEmpty() && notesArea.getText().isEmpty();

        inputsFull = !firstEmpty && !lastEmpty && !numberEmpty && !notesEmpty;

        System.out.println(firstEmpty);
        System.out.println(lastEmpty);
        System.out.println(numberEmpty);
        System.out.println(notesEmpty);
        System.out.println(inputsFull);
        System.out.println();


    }

    public boolean isInputsFull() {
        return this.inputsFull;
    }

Upvotes: 0

Views: 2671

Answers (1)

James_D
James_D

Reputation: 209269

First, delete your handleKeyRelease method. Never use key event handlers on text input components: for one thing they will not work if the user copies and pastes text into the text field with the mouse. Just register listeners with the textProperty() instead, if you need. Also, isn't (for example)

firstNameField.getText().trim().isEmpty() && firstNameField.getText().isEmpty()

true if and only if

firstNameField.getText().isEmpty();

is true? It's not clear what logic you are trying to implement there.

You should simply expose inputsFull as a JavaFX property:

public class AddDialogController {
    @FXML
    private TextField firstNameField;

    @FXML
    private TextField lastNameField;

    @FXML
    private TextField numberField;

    @FXML
    private TextArea notesArea;

    private BooleanBinding inputsFull ;

    public BooleanBinding inputsFullBinding() {
        return inputsFull ;
    }

    public final boolean getInputsFull() {
        return inputsFull.get();
    }

    public void initialize() {
        inputsFull = new BooleanBinding() {
            {
                bind(firstNameField.textProperty(),
                     lastNameField.textProperty(),
                     numberField.textProperty(),
                     notesArea.textProperty());
            }
            @Override
            protected boolean computeValue() {
                return ! (firstNameTextField.getText().trim().isEmpty()
                       || lastNameTextField.getText().trim().isEmpty()
                       || numberField.getText().trim().isEmpty()
                       || notesArea.getText().trim().isEmpty());
            }
        };
    }

    public void processResults() {
        String first = firstNameField.getText().trim();
        String last = lastNameField.getText().trim();
        String number =  numberField.getText().trim();
        String notes = notesArea.getText().trim();

        Contact contact = new Contact(first, last, number, notes);

    //      ContactData.add(contact);
    }

}

and then all you need is

dialog.getDialogPane().getButtonTypes().add(ButtonType.OK);
dialog.getDialogPane().getButtonTypes().add(ButtonType.CANCEL);

AddDialogController controller = loader.getController();
dialog.getDialogPane().lookupButton(ButtonType.OK)
    .disableProperty()
    .bind(controller.inputsFullBinding().not());

Upvotes: 3

Related Questions