bboris 0 Newbie Poster

Filterable AbstractListModel uses originalModel of JList as source and
excludes those items from originalModel that matches exclude criteria specified by
given regex.

It also allows reusing same model (with filtering capability of course) for multiple JList components.

It also registers as ListDataListener to originalModel model to be able to relay
changes (by firing events) of source items at runtime to other JList that uses this filterable model.

Class code:

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.AbstractListModel;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.ListModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

public class FilterableListModel extends AbstractListModel implements  ListDataListener {

    private ListModel originalModel;
    private Pattern regexToExclude;
    private ArrayList<String> filteredItemList;

    /**
     * Filterable <tt>AbstractListModel</tt> that uses <tt>originalModel</tt> of JList as source and 
     * excludes those items from <tt>originalModel</tt> that matches exclude criteria specified by 
     * given regex.<p>
     * It also registers as <tt>ListDataListener</tt> to <tt>originalModel</tt> model to be able to relay
     * changes (by firing events) of source items at runtime to other JList that uses this filterable model. 
     * 
     * @param originalModel
     * @param regexToExcludeAsString
     */
    public FilterableListModel( 
            ListModel originalModel, 
            String regexToExcludeAsString){

        this.originalModel = originalModel;
        this.regexToExclude = Pattern.compile(regexToExcludeAsString);
        filteredItemList = new ArrayList<String>();
        originalModel.addListDataListener(this);
    }


    // ListModel methods //
    public int getSize() {      
        recreateMyFilteredItemList();       
        return filteredItemList.size();
    }


    public Object getElementAt(int index) {
        recreateMyFilteredItemList();       
        return filteredItemList.get(index);
    }


    // ListDataListener methods //
    public void intervalAdded(ListDataEvent e) {
        recreateMyFilteredItemList();
        fireIntervalAdded(e.getSource(), 0, filteredItemList.size()-1);
    }


    public void intervalRemoved(ListDataEvent e) {
        recreateMyFilteredItemList();
        fireIntervalRemoved(e.getSource(), 0, filteredItemList.size()-1);
    }

    public void contentsChanged(ListDataEvent e) {
        recreateMyFilteredItemList();
        fireContentsChanged(e.getSource(), 0, filteredItemList.size()-1);
    }

    //// private helper methods
    /**
     * Clears <tt>filteredItemList</tt> and populate it with items 
     * from originalModel that does not match exclude criteria.
     */
    private void recreateMyFilteredItemList(){
        filteredItemList.clear();
        int origSize=originalModel.getSize();
        for(int i=0; i<origSize; i++) {          
            String originalItem = originalModel.getElementAt(i).toString();
            Matcher matcher = regexToExclude.matcher(originalItem);
            if( ! matcher.find()){ 
                // does not match exclude criteria, put it into filteredItemList
                filteredItemList.add(originalItem);
            }           
        }
    }
}

Usage example:

JList filteredList = new JList();
filteredList.setModel( new FilterableListModel(
        anotherJList.getModel(),
        "system" ));
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.