FilteredTree(JFace):显示所有孩子的自定义过滤器

时间:2010-10-01 14:45:19

标签: swt eclipse-rcp jface

我目前正在使用带有PatternFilter的FilteredTree来显示树中的数据 我的问题是它只显示与模式匹配的元素并隐藏它们的子节点(除了它们也匹配模式)。

例:
树:

一个
-B
--1
--2
-C
--1
--2

模式“B”给了我:

一个
-B

但我需要:

一个
-B
--1
--2

我尝试了一些东西,但没有找到一个很好/简单的方法来做到这一点。 有什么想法吗?

3 个答案:

答案 0 :(得分:1)

这是默认行为。覆盖PatternFilter.isParentMatch()和PatternFilter.isLeafMatch()以获得正确的结果。

答案 1 :(得分:1)

我遇到了同样的问题:元素被正确过滤但没有显示树节点的子节点。用户必须选择找到的节点(希望它只有一个结果)然后重置过滤器并查看选择与子项一起出现的位置。

解决此问题需要覆盖PatternFilter#isLeafMatch()并使用JavaReflection从PatternFilter检索(私有)字段缓存

public class MyPatternFilter extends PatternFilter {

    private final Map<Object, Object> patternFilterCache;

    public MyPatternFilter () {
        this.patternFilterCache = getCache();
    }

    @Override
    protected boolean isLeafMatch(final Viewer viewer, final Object element) {
        boolean result = super.isLeafMatch(viewer, element);
        if (result) { // element matches, now add all its children
            traverseChildren(((MyTreeNode) element).getChildren());
        }
        return result;
    }

    // this is to traverse the children of the element found before
    // these children need to be added to the Map 'cache' to be displayed
    void traverseChildren(List<MyTreeNode> children) {  
        // assuming that child.getChildren() is never null!
        for(MyTreeNode child : children) {
            this.patternFilterCache.put(child, child.getChildren().stream().toArray(MyTreeNode[]::new));
            traverseChildren(child.getChildren());
        }
    }

    private Map<Object, Object> getCache() {
        try {
            Field cacheField = this.getClass().getSuperclass().getDeclaredField("cache"); //$NON-NLS-1$
            cacheField.setAccessible(true);
            @SuppressWarnings("unchecked")
            Map<Object, Object> cache = (Map<Object, Object>) cacheField.get(this);
            cacheField.setAccessible(false);
            return cache;
        } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
            e.printStackTrace();
        }
        return null;
    }

}

明显的缺点是Map&#39;缓存&#39;不是API,所以 - 理论上 - 如果名称改变,这个解决方案将失败。

答案 2 :(得分:0)

发布我的第一个答案真是太好了!

覆盖isElementVisible()并添加返回条件。

public class FilePatternFilter extends PatternFilter {
    @Override
    public boolean isElementVisible(Viewer viewer, Object element) {
        File file = (File) element;
        return isParentMatch(viewer, element) || isLeafMatch(viewer, element) || isLeafMatch(viewer, file.getParent());
    }
}