RowFilter.regexFilter multiple columns
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 woul开发者_C百科d 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.
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) + "$";
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
精彩评论