Drawing Hands by M.C. Escher (1948)

Jeff Mesnil


Add a filter to a TreeViewer

On February 26th, 2007 in eclipse, java, jmx

In eclipse-jmx, a plug-in to manage Java applications through JMX, I have a view which displays registered MBeans using a TreeViewer.
Since there can be many MBeans to display (e.g. more than 200 just for Tomcat), it is tedious to navigate in the Tree by expanding many nodes before finding the MBeans I want to manage. To make it more usable, I wanted to add a filter text to the view to show only the MBeans which are interesting to me. UI-wise, I wanted something like the Filtered Extensions of the PDE Editor:

Filtered Extensions in the PDE Editor

It shows only the extensions matching the filter text (and also displays the extensions categories).

Since this screenshot was from Eclipse 3.3M1 New & Noteworthy, I thought that this filter was not available for Eclipse 3.2 (or that it was specific to PDE).
It turns out that I was wrong, it works on Eclipse 3.2, and it takes only 2 lines to add such behavior to any TreeViewer using a PatternFilter and a FilteredTree (which are from the org.eclipse.ui.workbench plug-in).

Plain Old TreeViewer

The code to create the TreeViewer is straightforward:

public void createPartControl(Composite parent) {
    ...
    viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
    ...
}

which, in eclipse-jmx, gives:

MBean Explorer from eclipse-jmx 0.1.1

PatternFilter & FilteredTree

To filter the tree’s nodes, the code to change is minimal:

public void createPartControl(Composite parent) {
    ...
    PatternFilter patternFilter = new PatternFilter();
    final FilteredTree filter = new FilteredTree(parent, SWT.MULTI
            | SWT.H_SCROLL | SWT.V_SCROLL, patternFilter);
    viewer = filter.getViewer();
    ...
}

With these 2 lines, a filter widget is displayed on top of the tree and the tree’s nodes are automatically filtered based on the filter text:

MBean Explorer from eclipse-jmx 0.1.2 with filter

Screenshot has been taken on Eclipse 3.3M5 which uses native search widgets (if one is available) to display the filter control. It works also on Eclipse 3.2 but does not look so good.

By default, PatternFilter will display any nodes of the Tree whose label matches the filter text. By extending it, it is very simple to have more complex filter matching algorithm.
It is the case in eclipse-jmx: it displays any node whose descendant’s leaves have an ObjectName which matches the filter text.

Kudos to the workbench team for this little UI nugget!

3 Responses to “Add a filter to a TreeViewer”

  1. Evan Williams Says:

    Hi Jeff,

    thanks for the very informative posting … it was exactly what I needed for a current project.

    One point I’m having a problem with is getting the tree to auto expand as I’m searching.

    I’ve set the viewer with setAutoExpandLevel(TreeViewer.ALL_LEVELS) - which makes the initial tree expand ok, but after a search commences, the tree seems to revert to only showing the top level nodes.

    Are you aware of any post-filter event that I need to handle and then expand the tree myself ?

    Any suggestions ?

    thanks again,
    Evan Williams

  2. jmesnil Says:

    Hi Evan,

    I don’t really know how expanding and filtering work together.

    In eclipse-jmx, I extended PatternFilter so that nodes were revealed (and thus “expanded”) if any of their ancestors were matching the filter text.
    See MBeanExplorer and search for PatternFilter to see how I made it work.

    hope it may help you,
    jeff

  3. Evan Williams Says:

    Hi Jeff,

    well, as it always happens, just after I posted the comment - I realized that maybe I should check how the code works on my newer trial of Eclipse 3.3 M5. I was using Eclipse 3.2

    Naturally enough, it works fine on the latest release :-)

    thanks for your time, and suggestion too.

    Evan