When you use the FilteredTree with a PatternFilter, the visible nodes include the leaves as well as their parents in the tree that match the filter text. However if your usecase requires that a matched node's children also be shown then you need to use a custom PatternFilter which will select an element if any of its ancestors are a match.
Here is how I did it:
Now from a good UI design perspective we should also show the actual pattern matches in a bold font similar to how the default Preferences Dialog filtered tree works.
public class ShowChildrenPatternFilter extends PatternFilter {
protected boolean isChildMatch(Viewer viewer, Object element) {
System.out.println("inchildmatch");
Object parent = ((ITreeContentProvider) ((AbstractTreeViewer) viewer)
.getContentProvider()).getParent(element);
if(parent!=null){
return (isLeafMatch(viewer, parent)?true:isChildMatch(viewer,parent));
}
return false;
}
@Override
protected boolean isLeafMatch(Viewer viewer, Object element) {
String labelText = ((ILabelProvider) ((StructuredViewer) viewer)
.getLabelProvider()).getText(element);
if(labelText == null) {
return false;
}
return (wordMatches(labelText)?true:isChildMatch(viewer, element));
}
}
For that we need our ILabelProvider to implement IFontProvider and in the getFont method we need to call the FilteredTree.getBoldFont method. This method takes a PatternFilter as an argument. This is the filter that is used to select which elements are shown in bold. Since we just want our true matches ( and not their children) to be bolded, we cannot use our modified ShowChildrenPatterFilter. Instead we can just use the regular PatternFilter here. Here is how your LabelProvider class will look:
public class MyFilteredTreeLabelProvider implements ILabelProvider,IFontProvider {
2 comments:
The solution did work for me. But I have to collapse all the child nodes if it does not match the filtered text. Do you have any solution for that?
Post a Comment