如何在对话框中将事件侦听器绑定到JavaFX TextFields。当字段为空时,“确定”按钮将被禁用,反之亦然

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在对话框中将事件侦听器绑定到JavaFX TextFields。当字段为空时,“确定”按钮将被禁用,反之亦然相关的知识,希望对你有一定的参考价值。

这是支持我想要完成的代码:

对话控制器代码:

public class DialogController {
@FXML private TextField firstName;
@FXML private TextField lastName;
@FXML private TextField phoneNumber;
@FXML private TextField notes;
@FXML private DialogPane dialogPane;

//All getters defined here

public void keyReleasedHandler(){
    Boolean firstNameEmpty = (firstName.getText().isEmpty() || firstName.getText().trim().isEmpty());
    Boolean lastNameEmpty = (lastName.getText().isEmpty() || lastName.getText().trim().isEmpty());
    Boolean phoneNumberEmpty = (phoneNumber.getText().isEmpty() || phoneNumber.getText().trim().isEmpty());
    if (firstNameEmpty || lastNameEmpty || phoneNumberEmpty){
        //When the dialog box opens and I type or a delete a letter from any of the event binded fields, a null pointer exception is thrown
        dialogPane.lookupButton(ButtonType.OK).setDisable(true);
    }
    dialogPane.lookupButton(ButtonType.OK).setDisable(false);
}

public Contact processResults(){
    String firstName = getFirstName().getText().trim();
    String lastName = getLastName().getText().trim();
    String phoneNumber = getPhoneNumber().getText().trim();
    String notes = getNotes().getText().trim();

    return new Contact(phoneNumber, firstName, lastName, notes);
}}

主控制器的相关方法和UI定义:

public class Controller {
@FXML private TableView<Contact> tableView;
@FXML private BorderPane mainBorderPane;

public void handleNewContact(){
    Dialog<ButtonType> dialog = new Dialog<>();
    dialog.initOwner(mainBorderPane.getScene().getWindow());
    dialog.setTitle("Add a new contact to your list");
    dialog.setHeaderText("Use this dialog to create a new contact");
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(getClass().getResource("dialogWindow.fxml"));
    try {
        dialog.getDialogPane().setContent(loader.load());
    } catch (IOException e) {
        System.out.println("Couldn't load the dialog");
        e.printStackTrace();
        return;
    }

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

    Optional<ButtonType> result = dialog.showAndWait();

    if (result.isPresent() && result.get() == ButtonType.OK){
        DialogController controller = loader.getController();
        Contact contact = controller.processResults();
        contactData.addContact(contact);
        tableView.getSelectionModel().select(contact);
    }
}

我在keyReleasedHandler()背后的思考过程是在我的'New Contact Dialog'中用作我的TextFields的验证。在我的主控制器中,我通过其FXML处理对话框UI的创建,并在代码中手动添加了ButtonTypes OK和Cancel。我将所有对话框TextFields onKeyReleased绑定到我的keyReleasedHandler()。每当我在'validated'字段中输入任何内容时,都会抛出空指针异常(我假设dialogPane查找方法以某种方式返回null)。

此验证功能的替代实现也将非常受欢迎。

答案

你在做什么看起来像Swing实现。绑定可以做很多事情。

无论你在keyReleasedHandler()做什么,你可以用以下代替:

dialogPane.lookupButton(ButtonType.OK).disableProperty()
    .bind(Bindings.createBooleanBinding(
        () -> firstName.getText().trim().isEmpty() ||
              lastName.getText().trim().isEmpty() ||
              phoneNumber.getText().trim().isEmpty(),
        firstName.textProperty(),
        lastName.textProperty(),
        phoneNumber.textProperty()
    ));

当3个TextField中的任何一个有空文本时,这将导致该按钮被禁用。

一些旁注(与答案没有关系):

  • getText().isEmpty()并不是真的需要,因为你有getText().trim().isEmpty(),尽管可以说包括它更快。
  • 在您的问题中,您使用Boolean来存储布尔值。使用原始的boolean类型肯定更好。

以上是关于如何在对话框中将事件侦听器绑定到JavaFX TextFields。当字段为空时,“确定”按钮将被禁用,反之亦然的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有侦听器的情况下获取 javafx 媒体元数据

javafx:如何将Enter键绑定到按钮并在单击时触发事件?

清理 JavaFX 属性侦听器和绑定(内存泄漏)

如何在 PyQt4 中将事件监听器添加到动态 QTableWidgetItem?

JavaFX UI 在事件侦听器中的 JavaFX 应用程序线程中冻结,但可与 Platform.runLater 一起使用

JavaFX TextArea 滚动条移动事件