如何为原本是 BooleanProperty 列的 CheckBoxTableCell 设置事件监听器以确保值实际更新?

问题描述 投票:0回答:1

我有一个可事件的 TableView,并且我有一个 StudentGuardian 类,其中包含:

        private SimpleStringProperty studentName;
        private BooleanProperty hasGuardian;
        private SimpleStringProperty guardianName;

在我的控制器中,我已将其设置为将 BooleanProperty 变成复选框,如下所示:

    public void setupCheckbox(){
        hasGuardianTableColumn.setCellValueFactory(c -> new SimpleBooleanProperty(c.getValue().getHasGuardian()));
        hasGuardianTableColumn.setCellFactory(tc -> new CheckBoxTableCell<>());

        eventtable.setEditable(true);
    }

它实际上工作正常,复选框出现,我可以选中/取消选中它。但当用户单击复选框时,它实际上并没有更新 BooleanProperty 的值。

我尝试使用与 setupCheckbox 相同的方法来执行此操作:

hasGuardianTableColumn.setCellFactory(CheckBoxTableCell.forTableColumn(hasGuardianTableColumn));
        hasGuardianTableColumn.setOnEditCommit(
                (TableColumn.CellEditEvent<StudentGuardian, Boolean> t)
                -> (t.getTableView().getItems().get(
                        t.getTablePosition().getRow())).setHasGuardian(t.getNewValue())
        );

但它不起作用,我知道这一点,因为它不是事件侦听器。我真的不确定如何为 CheckBox 设置事件侦听器,因为它似乎只包含在该方法中,所以我不知道如何引用它。我找到了这个thread,但同样,我无法引用新的CheckBoxTableCell。我还想知道是否应该将其放在@Override中,或者也许我设置它的方式是错误的(或者我问了错误的问题)。任何事情都有帮助。

java javafx
1个回答
0
投票

A

CheckBoxTableCell
无法通过“正常”编辑机制工作。这是其文档所说的:

要构造此类的实例,需要提供一个

Callback
,给定类型为
T
的对象,将返回一个
ObservableProperty<Boolean>
表示是否选择了给定项目。该
ObservableValue
将双向绑定(意味着单元格中的
CheckBox
将根据用户交互设置/取消设置此属性,并且
CheckBox
将反映
ObservableValue
的状态(如果外部发生更改))。

注意:我认为

ObservableProperty<Boolean>
只是一个错字,而
ObservableValue<Boolean>
才是真正的意图。

但是,该文档与实现或 API 不太匹配。 API的设计也不是最好的。

  1. 回调未定义为接受

    T
    ,而是接受
    Integer
    (项目/单元格的索引)。

  2. 双向绑定仅在

    Property
    对象之间起作用,因此回调实际上应该定义为返回
    Property<Boolean>

  3. 该实现实际上仅在回调返回

    BooleanProperty
    时才有效(文档中未提及,API 也未暗示)。

  4. 定义回调实际上并不是“必要的”,因为如果没有给出回调,实现将回退到列的单元格值工厂。与第二点一样,单元值工厂必须返回

    BooleanProperty
    的实例,而不仅仅是
    ObservableValue<Boolean>
    的任何实例,才能使实现正常工作。

由于您的模型类本身定义了您想要与单元格链接的

BooleanProperty
,最简单的解决方案是定义一个返回属性的单元格值工厂:

column.setCellValueFactory(data -> data.getValue().hasGuardianProperty());

但是你可以使用回调:

column.setCellFactory(CheckBoxTableCell.forTableColumn(
        index -> table.getItems().get(index).hasGuardianProperty()));

请注意,这两个代码片段都假设您的模型类遵循“JavaFX Bean”约定(即,它们假设模型类具有所谓的“属性获取器”,每次都会返回相同的属性对象)。

© www.soinside.com 2019 - 2024. All rights reserved.