Как лучше всего использовать ViewerFilter на TreeViewer?

я прикладываю ViewerFilter к дереву несколько ветвей, но в основном листья. Фильтр действительно применяется к листьям, используя свойства внутри листа. Все ветви остаются нетронутыми, так что их листья могут появиться.

однако я хотел бы отфильтровать ветви, которые не содержат выбранных листьев, и я не вижу никакого механизма внутри ViewerFilter, который позволяет это.

возможно ли это вообще?

например, учитывая условное дерево ниже (где b это ветка, a L - это лист)

b0
  b1
    L2
    L4
    L8
  b2
    L1
    L3
    L5

Я хотел бы применить ViewerFilter это выбирает только четные листья и ветви, которые содержат четные листья. Результирующее дерево будет ..

b0
  b1
    L2
    L4
    L8

.. где b2 не отображается, поскольку он не содержит выбранных дочерних элементов, но ветви b0 и b1 do.

4 ответов


class MyFilter extends ViewerFilter{

  private boolean isLeaf(Object element){
    // implement this
  }

  private boolean isEvenLeaf(Object leaf){
    // implement this
  }

  @Override
  public boolean select(Viewer viewer, Object parentElement, Object element){
    if (isLeaf(element))
      return isEventLeaf(element);
    else {
      StructuredViewer sviewer = (StructuredViewer) viewer;
      ITreeContentProvider provider = (ITreeContentProvider) sviewer.getContentProvider();
      for (Object child: provider.getChildren(element)){
        if (select(viewer, element, child))
          return true;
      }
      return false;
    }
  }
}

Смотрите также org.eclipse.ui.dialogs.FilteredTree что правильно в отношении ребенка оставляет.


да, если вы не отфильтруете узлы ветвей, они будут показаны, даже если в нем нет листьев. Если вы хотите, чтобы фильтр был постоянно включен, вы можете рассмотреть использование ITreeContentProvider в качестве фильтра.

поскольку поставщик контента имеет методы getChildren() и hasChildren (), у вас есть немного больше контроля.


Я не уверен, что вы подразумеваете под выбранный листьев. Если вы имеете в виду выбранный в представлении, вы можете узнать это, вызвав Viewer.getSelection(). Метод select, реализуемый в фильтре, проходит в средстве просмотра, Родительском объекте и листе. Вы должны иметь возможность использовать эту информацию, чтобы решить, выбран ли лист или нет, и отфильтровать их. Если вы можете дать дополнительную информацию, я, вероятно, смогу ответить более подробно.