基本上,“正确”的方法是自定义selectionModel,它有一个要禁用的属性,并且在该状态下不做任何事情。不幸的是,selectionModels不是为被自定义类扩展/替换而设计的。此外,在表格控件中选择的共同祖先是MultipleSelectionModelBase,它完全隐藏,并且存在严重缺陷。因此,使自定义模型发挥作用的机会是。。。不是很好。
然而,这是可能的(如果投入足够的精力和资源,甚至可能可靠地工作;):实现一个自定义TableViewSelectionModel,该模型委托给默认的实现TableViewBitSelectionModel(它从TableView中获取的模型),使其自身与该模型保持同步,并将其自身安装到表中。
类似于:
public static class VetoableSelection<T> extends TableViewSelectionModel<T> {
private boolean disabled;
private TableViewSelectionModel<T> delegate;
public VetoableSelection(TableView<T> table) {
super(table);
delegate = table.getSelectionModel();
table.setSelectionModel(this);
new VetoableFocusModel<>(table);
delegate.selectedIndexProperty().addListener(c -> indexInvalidated());
}
/**
* keep selectedIndex in sync
*/
private void indexInvalidated() {
setSelectedIndex(delegate.getSelectedIndex());
}
/**
* Does nothing if disabled.
*/
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
public boolean isDisabled() {
return disabled;
}
/**
* Override all state changing methods to delegate
* if not disabled, do nothing if disabled.
* Here: row selection.
*/
@Override
public void clearAndSelect(int row) {
if (isDisabled()) return;
delegate.clearAndSelect(row);
}
@Override
public void select(int row) {
if (isDisabled()) return;
delegate.select(row);
}
/**
* Here: methods with columns
*/
@Override
public void clearAndSelect(int row, TableColumn<T, ?> column) {
if (isDisabled()) return;
delegate.clearAndSelect(row, column);
}
@Override
public void select(int row, TableColumn<T, ?> column) {
if (isDisabled()) return;
delegate.select(row, column);
}
...
对您的示例进行粗略检查似乎很有效:如果未提交修改的文本字段,则不允许更改选择。在不显示处于选定状态的单元格以及动态添加/删除人员和。。。可能还有很多其他的背景。