Tenho uma JTable (DefaultTableModel) contendo várias linhas de dados que gostaria de filtrar. O programa descobre corretamente quais linhas filtrar e adiciona a string regex (correspondente aos dados de uma coluna específica, já que nenhuma string corresponde a todas) a uma ArrayList de RowFilters. Essa ArrayList é então definida como RowFilter.andFilter. Mas onde deveria haver dados para exibir, geralmente não há nada ou há algum tipo de dado corrompido. Tentei várias abordagens nos últimos 2 dias e li inúmeras coisas online, mas não consigo fazer o filtro funcionar corretamente. Onde está o erro?
Na função que deve acionar o filtro, fica assim:
TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel());
sorter.setRowFilter(null);
table.setRowSorter(sorter);
List<RowFilter<Object, Object>> filterList = new ArrayList<RowFilter<Object, Object>>();
boolean missing = false;
//some logic to set missing to true/false depending on whether to filter or not
if (missing)
filterList.add(RowFilter.regexFilter(dataString)); //dataString is the exact string in a specific column of the row to be filtered
E depois que os cálculos estiverem concluídos, o filtro deve ser executado:
sorter.setRowFilter(RowFilter.andFilter(filterList, 5));
Agora a tabela está ficando em branco. Nenhum dado. O booleano ausente está sempre correto (depurei)...
Tentei estender a string regex com ^ no início e $ no final ou . ... . ou colocá-la entre parênteses, "(" + dataString + ")"
mas não adiantou. Até tentei sem o índice da coluna. O resultado é sempre o mesmo, desde que pelo menos 6 linhas permaneçam.
Agradeço sua ajuda.
Este é um MCVE. O programa está calculando corretamente os valores que não devem ser mostrados na tabela, mas o resultado é uma tabela em branco...
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.RowFilter;
import javax.swing.table.*;
public class mainTable extends javax.swing.JFrame {
private TableRowSorter<TableModel> sorter;
public mainTable() {
initComponents();
sorter = new TableRowSorter<>(table.getModel());
sorter.setRowFilter(null);
table.setRowSorter(sorter);
setTable();
setCombo();
}
private void initComponents() {
jPanel = new JPanel();
table = new javax.swing.JTable();
comboBox = new javax.swing.JComboBox<>();
jButton1 = new javax.swing.JButton();
setLayout(new FlowLayout());
setSize(400, 400);
DefaultTableModel tableModel = new DefaultTableModel();
tableModel.addColumn("Stadt");
tableModel.addColumn("Landkreis");
table.setModel(tableModel);
jButton1.setText("Filter");
jButton1.addActionListener(this::jButton1ActionPerformed);
jPanel.add(comboBox);
jPanel.add(jButton1);
jPanel.add(table);
getContentPane().add(jPanel);
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
filter();
}
public static void main(String args[]) {
new mainTable().setVisible(true);
}
private void setTable() {
ArrayList<String> cities = new ArrayList<>();
ArrayList<String> landkreise = new ArrayList<>();
String[] rows = new String[2];
DefaultTableModel tbm = (DefaultTableModel) table.getModel();
cities.add("Husum");
cities.add("Westerland");
cities.add("Hannover");
cities.add("Uelzen");
cities.add("Rotenburg");
cities.add("Verden");
cities.add("Nienburg");
landkreise.add("Nordfriesland");
landkreise.add("Nordfriesland");
landkreise.add("Region Hannover");
landkreise.add("Uelzen");
landkreise.add("Rotenburg");
landkreise.add("Verden");
landkreise.add("Nienburg");
for (int i = 0; i < cities.size(); i++) {
rows[0] = cities.get(i);
rows[1] = landkreise.get(i);
tbm.addRow(rows);
}
}
private void setCombo() {
DefaultTableModel tbm = (DefaultTableModel) table.getModel();
for (int i = 0; i < tbm.getRowCount(); i++)
comboBox.addItem(tbm.getValueAt(i, 1).toString());
}
private void filter() {
sorter.setRowFilter(null);
String filterText = comboBox.getSelectedItem().toString();
List<RowFilter<Object, Object>> filterLandkreis = new ArrayList<RowFilter<Object, Object>>();
for (int i = table.getRowCount(); i > 0; i--) {
boolean filter = false;
filter = !table.getValueAt(i-1, 1).toString().equals(filterText); //the value of the combo shall not be shown in the table
if (filter)
filterLandkreis.add(RowFilter.regexFilter(table.getValueAt(i-1, 1).toString()));
}
sorter.setRowFilter(RowFilter.andFilter(filterLandkreis));
}
private javax.swing.JComboBox<String> comboBox;
private javax.swing.JButton jButton1;
private JPanel jPanel;
private javax.swing.JTable table;
}
Se entendi corretamente suas necessidades, você quer criar um RowFilter que exclua um valor específico. Não precisa
RowFilter.andFilter
disso. Basta criar um filtro que mostre todas as linhas, exceto as que contêm esse valor:Esse código literalmente cria um filtro que permite qualquer linha que não corresponda a uma expressão regular que consiste no
filterText
valor literal.O problema é que eu entendi errado a lógica por trás do
RowFilter.andFilter()
. Mudei paraRowFilter.orFilter()
e ele funciona corretamente.Se houver vários
RowFilter
e você quiser que eles sejam filtrados de forma independente, é um OU lógico, não um E...