我目前正在使用带有PatternFilter的FilteredTree来显示树中的数据 我的问题是它只显示与模式匹配的元素并隐藏它们的子节点(除了它们也匹配模式)。
例:
树:
一个
-B
--1
--2
-C
--1
--2
模式“B”给了我:
一个
-B
但我需要:
一个
-B
--1
--2
我尝试了一些东西,但没有找到一个很好/简单的方法来做到这一点。 有什么想法吗?
答案 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());
}
}