在 JavaFX 的 TableView 中禁用某些 TableRow 项目的选择

Disable Selection of certain TableRow items within TableView in JavaFX

起点

我想实现一个 TableView,其中将检查每个 TableRow 项的特定布尔值。如果此值成立,则此行将被禁用 selection.

例如,我有一个 TableView 和 3 个 TableRows(每个都有一个 Person 对象)。现在,我希望 TableView 使那些 Person 对象 属性 超过 18 岁的行 not-selectable。

假设 第二行 满足上述条件,因此呈现为 not-selectable。因此,如果我的光标当前集中在 第一行 并且我按下向下箭头键,TableView 将 skip 任何 not-select 行(此处:第二行 )和 select 下一个可用的 select行(此处:第3行

我的方法

tblLineitems.setRowFactory(new Callback<TableView<Lineitem>, TableRow<Lineitem>>() {
    public TableRow<Lineitem> call(TableView<Lineitem> tableview) {
        return new TableRow<Lineitem>() {
            @Override
            protected void updateItem(Lineitem item, boolean empty) {
                super.updateItem(item, empty);

                if (item == null || empty) {
                } else {
                    itemProperty().addListener((ObservableValue<? extends Lineitem> observable, Lineitem oldValue, Lineitem newValue) -> {
                        if (newValue.isOlderThan18()) {
                            setDisable(true);
                        } else {
                            setDisable(false);
                        }
                    });
                }
            }
        };
    }
});

我的问题

虽然我设法 setDisable(true) 受影响的行,但我仍然可以 select/mark 使用向下和向上箭头键。

我试过实现自定义选择模型和焦点模型,但最终使用了 hack(适用于我的用例)。在我的情况下,我一次最多只能跳过一行。因此,在 selectedItemPropertyChangeListener 中,我最终使用了以下函数。

如果遇到项目行,我会触发回调,否则我会跳过类别行。

private fun MyListView.skipCategoryRow(
  previousSelectionIndex: Int,
  currentSelectionIndex: Int
) {
  when {
    currentSelectionIndex > previousSelectionIndex -> selectionModel.selectNext()
    currentSelectionIndex > 1 -> selectionModel.selectPrevious()

    /* prevent moving the selection to index 0, which is always a category row */
    else -> selectionModel.selectNext()
  }
}