2

我有一个显示许多节点的 FilteredTree,其中每个节点可以有多个子节点和子节点(n 深度)。

过滤器过滤与模式匹配的所有节点(以及任何深度的子节点)。

现在我想添加另一个搜索功能:

每个节点代表一个对象,每个对象都有一些字段,所以我想列出具有与文本匹配的字段的节点。

我厌倦了使用 ViewerFilter。

它的问题是它不会只为当前打开的分支调用树中的每个节点。

public class TheFilter extends ViewerFilter {

          private String searchString;

          public void setSearchText(String s) {

          }


          public boolean select(Viewer viewer, 
              Object parentElement, 
              Object element) { //triggered Only for one level


            return true;
          }
        } 

更新:

当找到搜索的项目时,我不仅要显示包含搜索项目的节点,还要显示它的父节点(所有父节点)。

4

2 回答 2

1

据我了解,您希望将搜索应用于所有元素,无论它们当前是否已扩展。虽然我不确定你为什么希望过滤也应用于最深的叶子,是因为你想要不显示任何子节点的根节点也消失吗?

这里可能有几种方法,如果您想强制将过滤器应用于所有元素,您可以使用 展开树中的所有项目TreeViewer#expandAll,除非您使用的是惰性内容提供程序,否则它应该对所有元素调用过滤。如果您不想让它保持展开,您可以再次折叠树(可能希望在展开和折叠时禁用绘图以避免闪烁Tree#setRedraw(boolean))。通常在树中搜索某些内容时,所有过滤的内容都显示为展开状态,因此也可以看到也符合搜索条件的最深叶子。如果您想像用户所做的那样维护每个元素的树的展开状态,则需要更多的工作来展开所有然后恢复展开。

另一种方法是在内容提供者中实现搜索。因此,您的内容提供者可以采用当前搜索条件并仅返回与其匹配的元素。这意味着您必须自己管理某个父级是否应该可见。因此,在更改搜索字段时,您只需刷新树,您的内容提供商将确保过滤。

于 2012-11-14T15:33:50.887 回答
1

FilteredTree接受一个org.eclipse.ui.dialogs.PatternFilteras 参数来确定它的过滤策略。

isLeafMatch您可以通过继承 PatternFilter 并覆盖它的方法来实现所需的结果。

例如:

PatternFilter filter = new PatternFilter() {
    @Override
    protected boolean isLeafMatch(Viewer viewer, Object element) {
        String field = ((Node) element).getField();
        if(field== null) {
            return false;
        }
        return wordMatches(field);
    }
};
FilteredTree tree = new FilteredTree(parent, SWT.MULTI | SWT.H_SCROLL
            | SWT.V_SCROLL, filter, true);
于 2012-11-11T23:44:40.707 回答