«Конкатенация» и «Фильтр» и «orFilter» для RowFilter - PullRequest
3 голосов
/ 19 ноября 2010

У меня есть JTable с четырьмя столбцами, первый из которых содержит либо число, либо текст, а остальные три - только текст. Я пытаюсь отфильтровать эту таблицу с помощью RowFilter:

sorter = new TableRowSorter<TableModel>(myOwnTableModel);

Флажок Фильтр, который я получил, работает достаточно хорошо:

sorter.setRowFilter(RowFilter.regexFilter("^[0-9]$", 0));

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

String regex = "(?i)" + Pattern.quote(s); // s = input Text of user
sorter.setRowFilter(RowFilter.regexFilter(regex, 1,2,3));

Что я не могу сделать, так это активировать оба фильтра одновременно. Может быть, я слишком далеко задумываюсь, моя идея состояла в том, чтобы "объединить" два фильтра, флажок должен быть "и" другой "или". Я перепробовал несколько вещей, для меня самый многообещающий выглядел примерно так:

String regex = "(?i)" + Pattern.quote(s);
bookFilter = RowFilter.regexFilter(regex, 1,2,3);
sorter.setRowFilter(bookFilter.andFilter(Arrays.asList(
                    RowFilter.regexFilter("^[0-9]$", 0))));

К сожалению, это не приводит к какому-либо полезному результату. Любые идеи приветствуются:)

1 Ответ

4 голосов
/ 19 ноября 2010

Решение состоит в том, чтобы добавить ActionListener к JCheckBox, чтобы обновить состояние фильтра, если флажок установлен, и добавить DocumentListener к базовому документу JTextField, чтобы обновить состояние фильтра, если содержимое поля обновлено.

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

RowFilter andFilter = RowFilter.andFilter(filter1, filter2, etc);

Пример прослушивателей событий

JCheckBox cb = ...
cb.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent evt) {
    updateFilters();
  }
});

JTextField tf = ...
tf.getDocument().addDocumentListener(new DocumentListener() {
  public void insertUpdate(DocumentEvent e) { updateFilters(); }
  public void removeUpdate(DocumentEvent e) { updateFilters(); }
  publci void changedUpdate(DocumentEvent e) { updateFilters(); }
});

... и затем определите свой метод updateFilters () для установки нового фильтра на основе того, когда установлен флажок, и является ли текстовое поле пустым или нет.

Пример метода обновления фильтра

public void updateFilters() {
  if (cb.isSelected()) {
    if (tf.getText().length() > 0) {
       // Both filters active so construct an and filter.
       sorter.setRowFilter(RowFilter.andFilter(bookFilter, checkBoxFilter));
    } else {
       // Checkbox selected but text field empty.
       sorter.setRowFilter(checkBoxFilter);
    }
  } else if (tf.getText().length() > 0) {
    // Checkbox deselected but text field non-empty.
    sorter.setRowFilter(bookFilter);
  } else {
    // Neither filter "active" so remove filter from sorter.
    sorter.setRowFilter(null); // Will cause table to re-filter.
  }
}
...