Question

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.

Was it helpful?

Solution

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

OTHER TIPS

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.

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top