Dynamic filtering using MatcherEditors

Static filtering with just Matchers means that the filtering logic is fixed. We need the filtering logic to change as the selection in the users list changes.

For this, there's MatcherEditor. It provides the mechanics for FilterLists to observe changes to the filtering logic. In your MatcherEditor implementation, you change the filtering logic by creating a new Matcher that implements the new logic. Then fire an event to all listening MatcherEditorListeners. You can implement this quickly by extending our AbstractMatcherEditor.

To implement the users filter, create an IssuesForUsersMatcher each time the selection changes. Then notify all your MatcherEditor's listeners using the method fireChanged() inherited from AbstractMatcherEditor.

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);
    }
}

Configure the new MatcherEditor to be used by your FilterList:

        EventList issues = ...
        UsersSelect usersSelect = new UsersSelect(issues);
        FilterList userFilteredIssues = new FilterList(issues, usersSelect);