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