У меня была та же проблема: элемент был отфильтрован правильно, но дочерние элементы узла дерева не отображались.Пользователь должен был выбрать найденный узел (в надежде, что это был только один результат), затем сбросить фильтр и посмотреть, где появился выбор вместе с дочерними элементами.
Для решения этой проблемы требуется перезапись PatternFilter#isLeafMatch()
и извлечение (частного) поля кеш из PatternFilter
с JavaReflection:
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;
}
}
Очевидным недостатком является то, что«кэш» карты - это не API, поэтому - в теории - если имя поменяется, это решение потерпит неудачу.