我有一个允许多选的TreeTableView。我有一个ContextMenu用于编辑或删除所选项目。
只有在至少有一个选择时才能启用删除和编辑。
final BooleanBinding isTableSelectionEmpty = Bindings.isEmpty(this.table.getSelectionModel().getSelectedItems());
this.menuItemDelete.disableProperty().bind(isTableSelectionEmpty);
这是按预期工作的。
但是现在我依赖于所选行的不同值。例如,该行是系统强制的,不应删除。
我尝试了以下但是它无效
final BooleanBinding invalidSelection = Bindings.and(Bindings.isEmpty(tableSelection),
Bindings.isNotEmpty(tableSelection.filtered(item -> {
this.logger.trace("filtering :" + item);
return item.getValue().getSystemProperty().get();
})));
this.menuItemDelete.disableProperty().bind(invalidSelection);
甚至不打印调试跟踪,并且绑定的值始终为false(从而启用菜单项)。现在我有点迷茫。我的错误在哪里?
答案 0 :(得分:2)
FilteredList
依赖于正确的ListIterator
,但目前ListIterator
中的selectedItems
MultipleSelectionModelBase
列表中存在错误。这可以防止过滤正常工作。要解决此问题,您可以创建一个ObservableList
实现,将除ListIterator
创建之外的所有内容委派给源ObservableList
。大多数IDE都具有自动生成此类方法的功能,将工作量降至最低(例如,在NetBeans:Generate - > Delegate Method中)。
public class ObservableListIteratorFix<T> implements ObservableList<T> {
private final ObservableList<T> list;
public ObservableListIteratorFix(ObservableList<T> list) {
this.list = list;
}
@Override
public void addListener(ListChangeListener<? super T> listener) {
list.addListener(listener);
}
@Override
public void removeListener(ListChangeListener<? super T> listener) {
list.removeListener(listener);
}
@Override
public boolean addAll(T... elements) {
return list.addAll(elements);
}
...
private class CustomListIterator implements ListIterator<T> {
private final ListIterator<T> iterator;
private int index;
public CustomListIterator(int index) {
this.iterator = list.listIterator(index);
this.index = index;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public T next() {
T t = iterator.next();
index++;
return t;
}
@Override
public boolean hasPrevious() {
return iterator.hasPrevious();
}
@Override
public T previous() {
T t = iterator.previous();
index--;
return t;
}
@Override
public int nextIndex() {
return index;
}
@Override
public int previousIndex() {
return index-1;
}
@Override
public void remove() {
iterator.remove();
}
@Override
public void set(T e) {
iterator.set(e);
}
@Override
public void add(T e) {
iterator.add(e);
}
@Override
public void forEachRemaining(Consumer<? super T> action) {
iterator.forEachRemaining(action);
}
}
@Override
public ListIterator<T> listIterator() {
return listIterator(0);
}
@Override
public ListIterator<T> listIterator(int index) {
return new CustomListIterator(index);
}
@Override
public FilteredList<T> filtered(Predicate<T> predicate) {
return new FilteredList<>(this, predicate);
}
...
这允许您将类用作selectedItems
的包装器,它应该修复过滤...
new ObservableListIteratorFix<>(tableSelection).filtered(...)