2016-08-19 3 views
1

У меня есть TreeTableView, который позволяет многопользовательский режим. Я получил ContextMenu для редактирования или удаления выбранных элементов.Отключить ContextMenu с зависимостью от выбора TreeTableView

Удаление и редактирование должны включаться только в том случае, если имеется хотя бы один выбор.

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); 

Не даже отладки трассировки распечатана и значение привязки всегда ложно (что позволяет пункт меню). Теперь я немного потерян. Где моя ошибка?

ответ

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(...) 
+0

Спасибо. Работает как шарм. Вы случайно говорите об этой ошибке (https://bugs.openjdk.java.net/browse/JDK-8145887)? – semTex

+1

@semTex Да, кажется, эта ошибка, но я разместил ее на другой странице ... Но, очевидно, они не хотят, чтобы я добавлял дополнительные данные, не заставляя меня регистрироваться ... В противном случае они уже знали бы, что проблема - странная реализация 'ListIterator':' com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList' внутренний класс 'SelectionListIterator', который довольно очевиден BTW, если сравнить индексы, используемые методами' previous'/'next', с индексами возвращаются 'previousIndex' /' nextIndex' и сравнивают все с контрактом 'ListIterator', описанным в документе. – fabian

Смежные вопросы