You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JFace TreeViewer中筛选并选中首个匹配元素?

实现TreeViewer的筛选与自动选中首个匹配项

1. 修正ViewerFilter筛选逻辑

你原来的过滤器逻辑没有真正实现筛选效果——不管元素是否匹配都返回element instanceof String,等于没做过滤。正确的逻辑要保留包含搜索文本的元素,同时还要保留这些元素的父节点(确保父节点展开,能看到匹配的子元素),代码如下:

treeViewer.addFilter(new ViewerFilter() {
    @Override
    public boolean select(Viewer viewer, Object parentElement, Object element) {
        String searchText = searchFilterText.getText().trim().toLowerCase();
        // 搜索文本为空时,显示所有元素
        if (searchText.isEmpty()) {
            return true;
        }

        boolean isMatch = element.toString().toLowerCase().contains(searchText);
        
        // 当前元素是匹配项,直接显示
        if (isMatch) {
            return true;
        }

        // 如果当前元素是父节点(对应HashMap的key),检查子节点是否有匹配项,有就显示父节点
        if (parentElement instanceof HashMap && element instanceof String) {
            List<String> children = typeDefsTreeMap.get(element);
            if (children != null) {
                for (String child : children) {
                    if (child.toLowerCase().contains(searchText)) {
                        return true;
                    }
                }
            }
        }

        // 既不是匹配项也没有匹配子节点,隐藏该元素
        return false;
    }
});

2. 实现首个匹配项的自动选中

筛选完成后,需要遍历树结构找到第一个符合条件的元素,再设置选中并滚动到该元素。可以写个工具方法递归查找:

private Object findFirstMatch(TreeViewer viewer, String searchText) {
    searchText = searchText.trim().toLowerCase();
    if (searchText.isEmpty()) {
        return null;
    }

    // 获取树的根元素(这里是HashMap的keySet)
    Object root = viewer.getInput();
    if (root instanceof Set) {
        for (Object parent : (Set<?>) root) {
            // 先检查父节点是否匹配
            if (parent.toString().toLowerCase().contains(searchText)) {
                return parent;
            }

            // 再检查子节点
            List<String> children = typeDefsTreeMap.get(parent);
            if (children != null) {
                for (String child : children) {
                    if (child.toLowerCase().contains(searchText)) {
                        return child;
                    }
                }
            }
        }
    }
    return null;
}

3. 绑定搜索框触发逻辑

在搜索文本框的内容变化事件中,刷新过滤器并执行选中逻辑:

searchFilterText.addModifyListener(e -> {
    // 刷新过滤器,重新渲染树
    treeViewer.refresh();
    
    // 查找首个匹配项
    Object firstMatch = findFirstMatch(treeViewer, searchFilterText.getText());
    if (firstMatch != null) {
        // 选中元素并滚动到视图中
        treeViewer.setSelection(new StructuredSelection(firstMatch), true);
        treeViewer.reveal(firstMatch);
    } else {
        // 无匹配项时清空选中状态
        treeViewer.setSelection(StructuredSelection.EMPTY);
    }
});

注意点

  • 确保你的TreeViewer内容提供者能正确解析HashMap<String, List<String>>的结构:根元素是keySet,父节点的子元素对应HashMap里的List。
  • 如果树有更深层级,需要调整findFirstMatch的递归逻辑适配结构。
  • 大小写忽略是默认的体验优化,你可以根据需求改成大小写敏感。

内容的提问来源于stack exchange,提问作者A.Goel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 05:10:17