【问题标题】:How to bind an event listener to JavaFX TextFields in a dialog box. When the fields are empty, the OK button becomes disabled and vice versa如何在对话框中将事件侦听器绑定到 JavaFX 文本字段。当字段为空时,确定按钮变为禁用,反之亦然
【发布时间】:2023-03-16 01:01:01
【问题描述】:

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

对话框控制器代码:

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() 背后的思考过程是在我的“新联系人对话框”中验证我的 TextField。在我的主控制器中,我通过其 FXML 处理了对话框 UI 的创建,并在代码中手动添加了 ButtonTypes OK 和 Cancel。我将所有对话框 TextFields onKeyReleased 绑定到我的 keyReleasedHandler()。每当我在“已验证”字段中键入任何内容时,都会引发空指针异常(我假设 dialogPane 查找方法以某种方式返回 null)。

此验证功能的替代实现也将不胜感激。

【问题讨论】:

    标签: java javafx nullpointerexception dialog event-handling


    【解决方案1】:

    你所做的看起来像是一个 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 类型肯定会更好。

    【讨论】:

    • 您好,感谢您回复我的问题。我实现了您在我的 keyReleasedHandler() 中提供的代码,但它仍然抛出空指针异常。知道是什么原因造成的吗?
    • @JustinHernandez 你需要告诉我们它发生在哪里(在代码中)。另请注意,既然您正在使用绑定,那么您应该真正删除您的关键事件。
    • @JustinHernandez 可能会发生空指针异常,因为您将按钮添加到主控制器中的对话框中,因此直到调用对话框控制器的 initialize() 方法之后才会添加这些按钮。是否有一个原因?在对话框控制器中添加这些按钮似乎更自然。
    • @JustinHernandez 见the tutorial。绑定只是注册所需的侦听器以确保一个属性始终包含与另一个可观察值相同的值。
    • @JustinHernandez 属性和绑定不是一两句话就能解释的话题。 James_D 提供的教程链接绝对是一个很好的起点。花时间了解这两者绝对是一项很好的投资,因为它们是 JavaFX 相对于 Swing 等旧 API 所具有的一些最重要/最有用的特性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    相关资源
    最近更新 更多