Combine filters on a JTable

Published on Saturday, 01 June 2013 in Java ; tagged with project, swing, java, awt, jtable, filter, regex, trick ; text version

Since few days, I'm working on a school project. Its goal is to use Java and Swing to create an interface for the Crew Scheduling Problem.

Dealing with a list of tasks, I choose to use a JTable as the graphical view.
One feature I want to implement is some filters to display/hide the tasks.

If you read the Java doc, you will see a lot of examples on how to use filters.
My problem here is that these examples only deals with simple filter, i.e. one filter for the whole row.
What I need is several filters, each one for a specific cell on a row. At this point, the doc becomes useless.

Hopefully, while looking for some similar issues on the Internet, I stumble on really few topics which explain how to perform a more advanced filtering system.
Therefore I am writing this post to sum them up.

With a JTable, you can not straightfully create several filters and ask Swing to appy each one on a specific cell (lame!).
But what you can do is create a list of RowFilter and then combine them using a RowFilter.andFilter.

/* Match the filter with the column 0 */
final RowFilter<TableModel, Object> firstFilter = RowFilter.regexFilter(firstFilter, 0);
/* Match the filter with the column 1 */
final RowFilter<TableModel, Object> secondFilter = RowFilter.regexFilter(secondFilter, 1);
/* Match the filter with the column 2 */
final RowFilter<TableModel, Object> thirdFilter = RowFilter.regexFilter(thirdFilter, 2);

final List<RowFilter<TableModel, Object>> filters = new ArrayList<RowFilter<TableModel, Object>>();
filters.add(firstFilter);
filters.add(secondFilter);
filters.add(thirdFilter);

/* The row must match every filters */
final RowFilter<TableModel, Object>  compoundRowFilter = RowFilter.andFilter(filters);

final TableRowSorter sorter = new TableRowSorter<TableModel>();
sorter.setRowFilter(compoundRowFilter);

final JTable tasksTable = new JTable();
tasksTable.setRowSorter(sorter);

The code above shows the principle using three filters and an 'and' clause.
Hence only the row matching every filters will be shown.

In my project, I use JComboBox to let the user decides. Using this system of multiple filters, a result may look like below.

JTable without filter

JTable with two filters

JTable with three filters

Hopefully, I don't have to filter tons of columns \o/


contactdepier.re License WTFPL2