RowFilter.regexFilter multiple columns

twodayslate picture twodayslate · Mar 22, 2010 · Viewed 21.6k times · Source

I am currently using the following to filter my JTable

RowFilter.regexFilter( 
         Pattern.compile(textField.getText(), 
         Pattern.CASE_INSENSITIVE).toString(),     columns );

How do I format my textField or filter so if I want to filter multiple columns I can do that. Right now I can filter multiple columns but my filter can only be of one of the columns

An example might help my explanation better:

Name Grade GPA
Zac   A    4.0
Zac   F    1.0
Mike  A    4.0
Dan   C    2.0

The text field would contain Zac A or something similar and it would show the first Zac row if columns was int[]{0, 1}. Right now if I do the above I get nothing. The filter Zac works but I get both Zac's. A also works but I would then get Zac A 4.0 and Mike A 3.0.

I hope I have explained my problem well. Please let me know if you do not understand.

Answer

Alan Moore picture Alan Moore · Mar 23, 2010

Looks like you either need to create a separate filter for each column and combine them with an AndFilter, or write your own filter by overriding the include() method. A RegexFilter only requires one of the specified columns to match, and there doesn't seem to be a way to change that.

By the way, if you want to force the regex to ignore case, you should add (?i) to the beginning of it. The string you're generating is the same as the one you started with, despite your use of the CASE_INSENSITIVE flag.

EDIT: The doc I linked to contains an example of creating an AndFilter from two RegexFilters, but the example is pretty silly. It creates a filter that looks for foo in any column or bar in any column--which is exactly the same as a single RegexFilter with foo|bar as the regex and no columns specified. A good AndFilter example should do something only an AndFilter can do: enforce conditions on two or more columns at once, like you're trying to do. Here's how I would filter case-insensitively for Zac in the first column and A in the second:

List<RowFilter<Object,Object>> rfs = 
    new ArrayList<RowFilter<Object,Object>>(2);
filters.add(RowFilter.regexFilter("(?i)^Zac$", 0));
filters.add(RowFilter.regexFilter("(?i)^A$", 1));
RowFilter<Object,Object> af = RowFilter.andFilter(rfs);

Also, if I were accepting the filter text as user input (which you seem to be doing), I would probably quote it first:

String regex = "(?i)^" + Pattern.quote(input) + "$";