Creating row filter "dynamic"

1

I'm using RowFilter to create filters for certain columns in my table. My intention is to pass the components I want to use as a "bar" search by parsing, creating them dynamically, and in the same way apply filters to them, that correspond to a column of the table, and finally, be able to combine these filters case if needed.

I created an example, where I have 4 columns, I want to be able to filter the first 3 columns, being able to combine the "fields" of filtering.

I took a look at this, Applying filters to a JTable , which is very similar to what I'm trying to do, but in this case it passes fixed filters.

The error is occurring when I try to capture the filter texts, it throws this exception:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1
    at pesquisa.UmTeste.setaFiltrosPesquisa(UmTeste.java:96)
    at pesquisa.UmTeste.montaTela(UmTeste.java:64)

Note 1: In the example I am only dealing with components of type JTextComponent , I know that I will have to make changes to cover the other components, besides having to treat columns that can not / should be treated with strings .

Note 2: I tried to do as simple as possible, just to illustrate the problem, in this case, the components are somewhat fixed, in the matter of quantity.

My example:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.JTextComponent;

public class UmTeste extends JFrame {

    private String[] colunas = {"0", "1", "2", "3"};

    private Object[][] dados = {
        {"1", "Estados Unidos", "USA", "true"},
        {"2", "Canada", "CNA", "true"},
        {"3", "United Kingdom", "UN", "true"},
        {"4", "Germany", "GER", "true"},
        {"5", "France", "FRA", "true"}};

    private DefaultTableModel dtm = new DefaultTableModel(dados, colunas);
    private JTable tabela = new JTable(dtm);

    private TableRowSorter<TableModel> sorter;
    private JScrollPane jsp = new JScrollPane(tabela);

    private JComponent[] componentes = {new JTextField(), new JTextField(), new JTextField()};

    public UmTeste() {
        setTitle("Teste - RowFilter");
        add(montaTela());
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public JComponent montaTela() {
        JPanel painel = new JPanel();
        painel.setLayout(new BorderLayout());

        //resgata o TableModel da sua JTable
        TableModel model = tabela.getModel();
        //Cria um RowSorter baseado no TableModel resgatado
        sorter = new TableRowSorter<>(model);
        //Aplica o RowSorte na na JTable
        tabela.setRowSorter(sorter);

        painel.add(pesquisa(), BorderLayout.NORTH);
        painel.add(jsp, BorderLayout.CENTER);
        setaFiltrosPesquisa();//seta o filtro
        return painel;
    }

    private JComponent pesquisa() {
        JPanel painelPesquisa = new JPanel();
        painelPesquisa.setLayout(new FlowLayout());

        for (int i = 0; i < componentes.length; i++) {
            if (componentes[i] != null) {
                if (componentes[i] instanceof JTextComponent) {
                    painelPesquisa.add(new JLabel("Coluna " + i));
                    painelPesquisa.add(componentes[i]);
                    componentes[i].setPreferredSize(new Dimension(80, 22));
                }
            }
        }
        return painelPesquisa;
    }

    private void setaFiltrosPesquisa() {
        String[] filtros = {""};
        for (int i = 0; i < componentes.length; i++) {
            if (componentes[i] != null) {
                if (componentes[i] instanceof JTextComponent) {
                    filtros[i] = ((JTextComponent) componentes[i]).getText().trim();
                }
                //cria uma lista para guardar os filtros de cada coluna
                List<RowFilter<Object, Object>> filters = new ArrayList<>();
                for (int ii = 0; ii < filters.size(); i++) {
                    filters.add(RowFilter.regexFilter("(?i)" + filtros[i], ii));
                    sorter.setRowFilter(RowFilter.andFilter(filters));
                }
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            UmTeste t = new UmTeste();
        });
    }
}
    
asked by anonymous 10.09.2017 / 18:06

1 answer

2

The cause of the error is in this line:

String[] filtros = {""};

Note that you initialize a String array with only an empty index and try to access it with an index based on the size of another different array and greater.

For this reason it pops ArrayIndexOutOfBoundsException , because this array only has one element, while the array of componentes has 3.

If each filter in this array is equivalent to only one component of the other, just start this with the same size as the array of components:

String[] filtros = new String[componentes.length];

There are other errors in your code such as configuring the rowFilter within the loop every time you add a filter in ArrayList , but it fades out of the question.

    
10.09.2017 / 18:11