RowFilter.regexFilter multiple columns
Asked Answered
G

3

8

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.

Griddle answered 22/3, 2010 at 18:46 Comment(0)
T
14

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) + "$";
Theone answered 23/3, 2010 at 1:2 Comment(4)
Just to be clear, you can add an AndFilter to another AndFilter correct? Also, where do I add the (?i)? Everywhere I have put it, I get an error.Griddle
An AndFilter ISA RowFilter, so I don't see why you couldn't add one to another, but I don't see a need to do that here. See my edit, which covers the (?i) as well.Theone
I got the insensitive case to work. I did not include the ^ or $ though, just the (?i) - it didn't work otherwise. Working on making the AndFilter now.Griddle
I created the AndFilter. It appears to work perfectly. Thank you for your help.Griddle
S
9

By combining the oracle's tutorial on tables and the answer from Alan, I made this:

RowFilter<PublicationTableModel, Object> rf = null;
List<RowFilter<Object,Object>> rfs = 
            new ArrayList<RowFilter<Object,Object>>();

try {
    String text = txtFilter.getText();
    String[] textArray = text.split(" ");

    for (int i = 0; i < textArray.length; i++) {
        rfs.add(RowFilter.regexFilter("(?i)" + textArray[i], 0, 1, 2, 4));
    }

    rf = RowFilter.andFilter(rfs);

} catch (java.util.regex.PatternSyntaxException e) {
        return;
}

sorter.setRowFilter(rf);

It's a pretty simple filter that takes all the text from a textbox, splits the words and dynamically creates many filters. Then, combining them with an andFilter and putting in back to the sorter for the table model.

Sarsenet answered 13/4, 2012 at 4:33 Comment(0)
O
2
RowFilter<TableModel, Object> filter =
    RowFilter.orFilter(Arrays.asList(RowFilter.regexFilter(lookup,0),
    RowFilter.regexFilter(lookup, 1)));

or

RowFilter<TableModel, Object> filter =
    RowFilter.regexFilter(Pattern.compile(lookup,Pattern.CASE_INSENSITIVE).toString(),0,1);

0 and 1 are the column numbers

Overzealous answered 5/9, 2010 at 20:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.