One limitation of filtering with just Matcher
s is that they don't provide a way to change the filtering logic. For example, in our TextFilterList, the filter logic is different for each character that is typed in the filter edit text field. For our users filter, we would like to change the filtering logic each time a user is selected or deselected.
To implement dynamic filtering, we create a MatcherEditor
. This interface provides a simple mechanism for the FilterList
to listen for changes to the filtering logic. Whenever the filtering logic is changed, the MatcherEditor
creates a new Matcher
that models the new logic and fires an event to the listening MatcherEditorListener
s. This can be implemented quickly by extending the AbstractMatcherEditor
interface.
For our users filter, we create a new IssuesForUsersMatcher
whenever the selection changes.
import javax.swing.event.*; import javax.swing.*; // glazed lists import ca.odell.glazedlists.*; import ca.odell.glazedlists.matchers.*; import ca.odell.glazedlists.swing.*; // a simple issues library import ca.odell.issuezilla.*; /** * This {@link MatcherEditor} matches issues if their user is selected. * * @author <a href="mailto:jesse@odel.on.ca">Jesse Wilson</a> */ public class UsersSelect extends AbstractMatcherEditor implements ListSelectionListener { /** a list of users */ EventList usersEventList; EventList usersSelectedList; /** a widget for selecting users */ JList usersJList; /** * Create a {@link IssuesForUsersMatcherEditor} that matches users from the * specified {@link EventList} of {@link Issue}s. */ public UsersSelect(EventList source) { // derive the users list from the issues list EventList usersNonUnique = new IssueToUserList(source); usersEventList = new UniqueList(usersNonUnique); // create a JList that contains users EventListModel usersListModel = new EventListModel(usersEventList); usersJList = new JList(usersListModel); // create an EventList containing the JList's selection EventSelectionModel userSelectionModel = new EventSelectionModel(usersEventList); usersJList.setSelectionModel(userSelectionModel); usersSelectedList = userSelectionModel.getSelected(); // handle changes to the list's selection usersJList.addListSelectionListener(this); } /** * Get the widget for selecting users. */ public JList getJList() { return usersJList; } /** * When the JList selection changes, create a new Matcher and fire * an event. */ public void valueChanged(ListSelectionEvent e) { Matcher newMatcher = new IssuesForUsersMatcher(usersSelectedList); fireChanged(newMatcher); } }
Finally, we must configure our new MatcherEditor
to be used by a FilterList
. For this, we specify our MatcherEditor
as an argument to the FilterList
's constructor.
EventList issues = ... UsersSelect usersSelect = new UsersSelect(issues); FilterList userFilteredIssues = new FilterList(issues, usersSelect);