Apply filters in a JTable

3

I have a table and in a Jpanel on it I created a textFields and combobox with the intention of using them as a filter. The method:

tableRowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + busca));

Does he expect a string as a filter? If the filter has more than one parameter how do I use it?

My screen looks like this:

ItwouldbesomethinglikeExample:

publicclassteste2extendsjavax.swing.JFrame{//Variaveisprivatejavax.swing.JButtonbtnAplicar;privatejavax.swing.JButtonbtnLimpar;privatejavax.swing.JComboBoxcomboboxCategoria;privatejavax.swing.JComboBoxcomboboxStatus;privatejavax.swing.JScrollPanejScrollPane2;privatejavax.swing.JLabellblAbertura;privatejavax.swing.JLabellblCategoria;privatejavax.swing.JLabellblCliente;privatejavax.swing.JLabellblNumero;privatejavax.swing.JLabellblResponsavel;privatejavax.swing.JLabellblStatus;privatejavax.swing.JLabellblUsuario;privatejavax.swing.JTabletableServicosAbertos;privatejavax.swing.JFormattedTextFieldtxtAbertura;privatejavax.swing.JTextFieldtxtCliente;privatejavax.swing.JFormattedTextFieldtxtNumero;privatejavax.swing.JTextFieldtxtResponsavel;privatejavax.swing.JTextFieldtxtUsuario;publicteste2(){iniciarComponentes();}privatevoidiniciarComponentes(){jScrollPane2=newjavax.swing.JScrollPane();tableServicosAbertos=newjavax.swing.JTable();comboboxStatus=newjavax.swing.JComboBox();lblCategoria=newjavax.swing.JLabel();lblStatus=newjavax.swing.JLabel();txtAbertura=newjavax.swing.JFormattedTextField();lblAbertura=newjavax.swing.JLabel();lblUsuario=newjavax.swing.JLabel();lblResponsavel=newjavax.swing.JLabel();txtUsuario=newjavax.swing.JTextField();txtResponsavel=newjavax.swing.JTextField();lblCliente=newjavax.swing.JLabel();txtCliente=newjavax.swing.JTextField();txtNumero=newjavax.swing.JFormattedTextField();lblNumero=newjavax.swing.JLabel();comboboxCategoria=newjavax.swing.JComboBox();btnAplicar=newjavax.swing.JButton();btnLimpar=newjavax.swing.JButton();setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);setTitle("SiGS - Sistema de gerenciamento de serviços");
    setMinimumSize(new java.awt.Dimension(1366, 768));
    setResizable(false);
    addWindowListener(new java.awt.event.WindowAdapter() {
        public void windowActivated(java.awt.event.WindowEvent evt) {

        }
    });

    tableServicosAbertos.setModel(new javax.swing.table.DefaultTableModel(
            new Object[][]{
                {"OS20160214", "SAS", "Redes", "20/11/2016", "Max Vargas", "Max Vargas", "Aberto"},
                {"OS20160242", "Multiserv", "Computadores", "15/07/2016", "Max Vargas", "Mateus Nascimento", "Fechado"},
                {"OS20165851", "Telecom", "CFTV", "16/07/2016", "Max Vargas", "Fabio Oliv.", "Fechado"},
                {null, null, null, null, null, null, null}
            },
            new String[]{
                "Numero", "Cliente", "Categoria", "Abertura", "Usuario", "Responável", "Status"
            }
    ));
    jScrollPane2.setViewportView(tableServicosAbertos);

    comboboxStatus.setModel(new javax.swing.DefaultComboBoxModel(new String[]{" ", "Aberto", "Fechado", "Cancelado", "Pausado"}));

    lblCategoria.setText("Categoria:");

    lblStatus.setText("Status:");

    lblAbertura.setText(" Abertura:");

    lblUsuario.setText("Usuário:");

    lblResponsavel.setText("Responsável:");

    lblCliente.setText("Cliente:");

    lblNumero.setText("Número:");

    comboboxCategoria.setModel(new javax.swing.DefaultComboBoxModel(new String[]{" ", "Computadores", "CFTV", "Redes", "Telefonia", "Outros"}));

    btnAplicar.setText("OK");

    btnLimpar.setText("Limpar");

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                    .addGap(0, 0, Short.MAX_VALUE)
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addGroup(layout.createSequentialGroup()
                                                    .addGap(10, 10, 10)
                                                    .addComponent(lblStatus)
                                                    .addGap(15, 15, 15)
                                                    .addComponent(comboboxStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                    .addGap(85, 85, 85)
                                                    .addComponent(lblResponsavel)
                                                    .addGap(5, 5, 5)
                                                    .addComponent(txtResponsavel, javax.swing.GroupLayout.PREFERRED_SIZE, 153, javax.swing.GroupLayout.PREFERRED_SIZE))
                                            .addGroup(layout.createSequentialGroup()
                                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                            .addGroup(layout.createSequentialGroup()
                                                                    .addComponent(lblCategoria)
                                                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                                                    .addComponent(comboboxCategoria, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                                    .addGap(104, 104, 104)
                                                                    .addComponent(lblUsuario)
                                                                    .addGap(10, 10, 10)
                                                                    .addComponent(txtUsuario, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE))
                                                            .addGroup(layout.createSequentialGroup()
                                                                    .addComponent(lblAbertura)
                                                                    .addGap(10, 10, 10)
                                                                    .addComponent(txtAbertura, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                                    .addGap(105, 105, 105)
                                                                    .addComponent(lblCliente)
                                                                    .addGap(13, 13, 13)
                                                                    .addComponent(txtCliente, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)))
                                                    .addGap(28, 28, 28)
                                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                            .addGroup(layout.createSequentialGroup()
                                                                    .addComponent(btnAplicar, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                                    .addComponent(btnLimpar))
                                                            .addGroup(layout.createSequentialGroup()
                                                                    .addComponent(lblNumero)
                                                                    .addGap(19, 19, 19)
                                                                    .addComponent(txtNumero, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)))))
                                    .addGap(78, 78, 78))
                            .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING))
                    .addContainerGap())
    );
    layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                    .addGap(90, 90, 90)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                    .addComponent(lblCategoria)
                                    .addComponent(comboboxCategoria, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(lblUsuario)
                            .addComponent(txtUsuario, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lblNumero)
                            .addComponent(txtNumero, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGap(10, 10, 10)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(lblStatus)
                            .addComponent(comboboxStatus, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lblResponsavel)
                            .addComponent(txtResponsavel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                    .addGap(10, 10, 10)
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(lblAbertura)
                                            .addComponent(txtAbertura, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                            .addComponent(lblCliente)
                                            .addComponent(txtCliente, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                                    .addGap(46, 46, 46)
                                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 76, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createSequentialGroup()
                                    .addGap(18, 18, 18)
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                            .addComponent(btnAplicar)
                                            .addComponent(btnLimpar))))
                    .addContainerGap(241, Short.MAX_VALUE))
    );

    pack();
    setLocationRelativeTo(null);
}
    
asked by anonymous 21.11.2016 / 23:18

2 answers

4

After a few tests, I was able to develop a solution that will search globally, covering any faults like when one of the fields is not informed, and also cleaning the filters when all the fields are deleted.

Initially, you should create a variable TableRowSorter as the class property, to be used in the table later:

private TableRowSorter<TableModel> sorter;

By the code, I realized that you are creating the screen by the netbeans editor, so you will need to add the following lines, which refer to the creation of RowSorter , in the constructor, after the method that creates your table (in this case, is iniciarComponentes(); ):

//...

iniciarComponentes();

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

The method below will do all the filtering work on the table, treating each search field to the relative column in the table:

protected void setFilterInJTable() {


    String  numero = txtNumero.getText().trim(),
            cliente = txtCliente.getText().trim(),
            categoria = comboboxCategoria.getSelectedItem().toString().trim(),
            abertura = txtAbertura.getText().trim(),
            usuario = txtUsuario.getText().trim(), 
            responsavel = txtResponsavel.getText().trim(),
            status = comboboxStatus.getSelectedItem().toString().trim();

    //cria uma lista para guardar os filtros de cada coluna
    List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>();
    filters.add(RowFilter.regexFilter("(?i)" + numero, 0));
    filters.add(RowFilter.regexFilter("(?i)" + cliente, 1));
    filters.add(RowFilter.regexFilter(categoria, 2));
    filters.add(RowFilter.regexFilter("(?i)" + abertura, 3));
    filters.add(RowFilter.regexFilter("(?i)" + usuario, 4));
    filters.add(RowFilter.regexFilter("(?i)" + responsavel, 5));
    filters.add(RowFilter.regexFilter(status, 6));
    //aplica os filtros no RowSorter que foi criado no construtor
    //utilizando o andFilter
    sorter.setRowFilter(RowFilter.andFilter(filters));

}

On the Aplicar button, simply add a ActionListener and call the setFilterInJTable() method inside the actionPerformed , which search will be active.

View a print of the search result using the fields:

TheabovemethodcodetakesallscreenfilterfieldsasString,removeswhitespace(toavoidunwantedresultsifoneofthefieldsisnotinformed),andtreatthestringsthatarebroughtfromthetextfieldssuchas case insensitive .

This filter may even fit your table, but there are fields that should not be treated as String, eg date fields, if they come from the database as date, their types should be kept in JTable .

By emphasizing what was said in the other answer, perhaps the most indicated is the search being done directly in the database, after all, the data in the table can be modified in the database by other instances of the application, and the search in this case will work with data which may not be the most current.

In this other answer there are some reference links to study about RowSorter .

    
22.11.2016 / 14:54
2

I would advise always to query the database directly, for the simple fact that at any minute, the information on the screen may have been updated / deleted and even inserted new records. But if you want to use the rowFilter, see example directly from the documentation:


List< RowFilter < Object, Object > > rfs =  new ArrayList < RowFilter < Object, Object > >);
filters.add(RowFilter.regexFilter("(?i)^Zac$"));
filters.add(RowFilter.regexFilter("(?i)^A$"));
RowFilter af = RowFilter.andFilter(rfs);

When I used it, I remember having problem with date fields. I believe you will have to do something like this:


RowFilter.dateFilter(ComparisonType.AFTER, new Date());
After that, add the rowFilter to your table. Any questions, I am available. (It's been a while since I moved with Jtable, any error, please edit my answer or correct me below.     
22.11.2016 / 13:16