Time for action – filtering items in a viewer
Another common feature of viewers is filtering. This is used both when performing a manual search, as well as for filtering specific aspects from a view. Quite often, the filtering is connected to the view's menu, which is the drop-down triangle on the top right of the view, using a common name such as Filters. The ViewerFilter
class provides a filtering method, confusingly called select
(there are some filter methods, but these are used to filter the entire array; the select is used to determine if a specific element is shown or not).
- Create a class
TimeZoneViewerFilter
in thecom.packtpub.e4.clock.ui.internal
package, which extendsViewerFilter
. It should take aString
pattern in the constructor, and returntrue
if the element is aTimeZone
with that pattern in its display name:public class TimeZoneViewerFilter extends ViewerFilter { private String pattern; public TimeZoneViewerFilter(String pattern) { this.pattern = pattern; } public boolean select(Viewer v, Object parent, Object element) { if (element instanceof ZoneId) { ZoneId zone = (ZoneId) element; String displayName = zone.getDisplayName( TextStyle.FULL, Locale.getDefault()); return displayName.contains(pattern); } else { return true; } } }
- Since views can have multiple filters, the
TimeZoneViewerFilter
is set as a single element array on the corresponding viewer. The pattern to filter is passed in to the constructor in this case, but would normally be taken from the user. Modify theTimeZoneTreeView
class at the bottom of thecreate
method:treeViewer.setFilters(new ViewerFilter[] { new TimeZoneViewerFilter("GMT")});
- To remove the triangular expand icon next to the tree items with no children, the
TreeViewer
can be configured to expand nodes automatically:treeViewer.setExpandPreCheckFilters(true);
- Now run the Eclipse instance and open the Time Zone Tree View. Only time zones in the Etc region are listed:
What just happened?
The filter class was created as a subclass of ViewerFilter
and set on the TreeViewer
. When displaying and filtering the data, the filter is called for every element in the tree including the root node.
By default, if the hasChildren
method returns true
, the expandable icon is shown. When clicked, it will iterate through the children, applying the filter to them. If all the elements are filtered, the expandable marker will be removed and display no children.
By calling setExpandPreCheckFilters(true)
on the viewer, it will verify that at least one child is left after filtration. This has no negative effect when there aren't any filters set. If there are filters set and there are large data sets, it may take some time to perform the calculation of whether they should be filtered or not.
To show all the tree's elements by default, or collapse it down to a single tree, use the expandAll
and collapseAll
methods on the viewer. This is typically bound to a local view command with a [+] and [-] icon (for example the Synchronize or the Package Explorer views).
If the data is a tree structure which only needs to show up to a specific level by default, there are expandToLevel
and collapseToLevel
methods, which take an integer and an object (use the getRoot
of the tree if not specified) and mark everything as expanded or collapsed to that level. The expandAll
method is a short-hand for expandToLevel(getRoot(), ALL_LEVELS)
.
When responding to a selection event which contains a hidden object, it is conventional to perform a reveal()
on the object to make it visible in the tree. Note that reveal()
only works when the getParent()
is correctly implemented, which isn't in this example.
Pop quiz – understanding sorting and filters
Q1. How can elements of a tree be sorted in an order which isn't its default?
Q2. What method is used to filter elements?
Q3. How can multiple filters be combined?
Have a go hero – expanding and filtering
Now that views can be sorted and filtered, try the following:
- Add a second filter which removes all
ZoneId
objects that have a negative offset. - When the view is opened, perform an
expandAll
of the elements. - Provide a sort that sorts the regions in reverse order but the time zones in ascending order.
- Provide a dialog which can be used to update the filter, and use the empty string which can be used to reset the filter.