RowFilter.атрибут regexfilter, так несколько столбцов

в настоящее время я использую следующий фильтр JTable

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

Как отформатировать мой textField или фильтр, поэтому, если я хочу фильтровать несколько столбцов, я могу это сделать. Сейчас я могу фильтровать несколько столбцов, но мой фильтр может быть только один из столбцов

пример может помочь моему объяснению лучше:

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

текстовое поле будет содержать Zac A или что-то подобное, и он покажет первую строку Zac, если columns был int[]{0, 1}. Прямо сейчас, если я сделаю это, я ничего не получу. Фильтр Zac работает, но я получаю как Zac'ы. A также работает, но я бы тогда получил Zac A 4.0 и Mike A 3.0.

надеюсь, я хорошо объяснил свою проблему. Пожалуйста, дайте мне знать, если вы не поняли.

3 ответов


Похоже, вам либо нужно создать отдельный фильтр для каждого столбца и объединить их с AndFilter, или напишите свой собственный фильтр, переопределив включить() метод. Для RegexFilter требуется только один из указанных столбцов, и, похоже, нет способа изменить это.

кстати, если вы хотите заставить регулярное выражение игнорировать случай, вы должны добавить (?i) к началу этого. Строке вы создаете такой же как тот, с которого вы начали, несмотря на использование флага CASE_INSENSITIVE.

EDIT: документ, с которым я связан, содержит пример создания AndFilter из двух RegexFilters, но пример довольно глупый. Он создает фильтр, который ищет foo в любой колонке или bar в любом столбце--который точно такой же, как один RegexFilter с foo|bar как regex и нет столбцов. Хороший пример AndFilter должен делать то, что может сделать только AndFilter: принудительно условия на двух или более столбцах одновременно, как вы пытаетесь сделать. Вот как я бы фильтровал case-нечувствительно для Zac в первой колонке и A во втором:

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);

кроме того, если бы я принимал текст фильтра в качестве пользовательского ввода (что вы, похоже, делаете), я бы, вероятно, процитировал его первым:

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

объединив учебник oracle по таблицы и ответ Алан, Я сделал это:

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);

Это довольно простой фильтр, который берет весь текст из текстового поля, разбивает слова и динамически создает много фильтров. После этого, совмещающ их с andFilter и кладущ внутри назад к сортировщику для модели таблицы.


RowFilter<TableModel, Object> filter =
    RowFilter.orFilter(Arrays.asList(RowFilter.regexFilter(lookup,0),
    RowFilter.regexFilter(lookup, 1)));

или

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

0 и 1-это количество столбцов