Pergunta

Eu tenho um jtable com quatro colunas, a primeira contendo um número ou um texto, os outros três apenas texto. Estou tentando filtrar esta tabela com a ajuda de um rowfilter:

sorter = new TableRowSorter<TableModel>(myOwnTableModel);

A caixa de seleção que eu consegui funciona bem o suficiente:

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

Este classificador é ativado ou desativado, dependendo de uma caixa de seleção definida ou não.
A segunda filtragem acontece se um usuário colocar algum texto em um campo de texto. Por si mesmo, isso já funciona bem:

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

O que não posso fazer é ativar os dois filtros ao mesmo tempo. Talvez eu esteja pensando longe demais, minha idéia tem sido "concatenar" os dois filtros, o Filter de Cheques deve ser "e" o outro "ou". Eu tentei várias coisas, para mim o mais promissor parecia algo como:

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

Infelizmente, isso não leva a nenhum resultado utilizável. Quaisquer ideias apreciadas :)

Foi útil?

Solução

A solução é adicionar um ActionListener para o JCheckBox para atualizar o estado do filtro se a caixa de seleção for alterada e adicionar um DocumentListener para o JTextFieldO documento subjacente para atualizar o estado do filtro se o conteúdo do campo for atualizado.

O outro bug do seu código é que você está chamando de estática andFilter método em seu bookFilter instância e estão passando apenas no filtro regex recém -construído (ou seja, você está passando apenas em um parâmetro para andFilter). O uso correto é:

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

Exemplo de ouvintes de eventos

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

... e, em seguida, defina seu método updateFilters () para instalar um novo filtro com base quando a caixa de seleção é selecionada e se o campo de texto está vazio ou não.

Método de atualização de filtro de exemplo

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.
  }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top