How to apply a filter of two JDateChooser to a JTable?

1

I need to simultaneously filter the data to be displayed in a JTable . Querying some old questions I was able to solve part of my problem.

I have a DATA field in the table of type String and I have two JDateChooser of the JCalendar lib in the interface. I need to get these dates and see if the table date is between the selected range in JDateChooser .

But I have no idea how to do this verification. I made a very simple example, nor put field to search by name but I wrote in the code as if it had to see how I implemented the search and it worked.

Enrollment

import java.awt.Dimension;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.RowFilter.ComparisonType;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class Matricula extends JFrame {

    private static final int ITENS_POR_PAG = 5;

    public Matricula() {
        initComponents();
    }

    private void initComponents() {

        jScrollPane = new javax.swing.JScrollPane();
        table = new javax.swing.JTable();
        btnFirst = new javax.swing.JButton();
        btnPrevious = new javax.swing.JButton();
        btnNext = new javax.swing.JButton();
        btnLast = new javax.swing.JButton();
        btnFiltrar = new javax.swing.JButton();
        jdcDataDeInicio = new com.toedter.calendar.JDateChooser();
        lblDe = new javax.swing.JLabel();
        lblAte = new javax.swing.JLabel();
        jdcDataDeFim = new com.toedter.calendar.JDateChooser();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jdcDataDeInicio.setDateFormatString("dd/MM/yyyy");
        jdcDataDeFim.setDateFormatString("dd/MM/yyyy");

        TableModel tableModel = table.getModel();
        sorter = new TableRowSorter<TableModel>(tableModel);
        table.setRowSorter(sorter);

        model = new MatriculaTableModel(JSONUtils.JSONtoList());

        table = new JTable(model);

        jScrollPane = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        jScrollPane.setPreferredSize(new Dimension(getPreferredSize().width - 20, table.getRowHeight() * ITENS_POR_PAG + table.getTableHeader().getPreferredSize().height));

        jScrollPane.setViewportView(table);

        btnFirst.setText("<<");

        btnPrevious.setText("<");

        btnNext.setText(">");

        btnLast.setText(">>");

        btnFiltrar.setText("Filtrar");

        lblDe.setText("De");

        lblAte.setText("Até");

        btnFirst = new JButton("<<");
        btnFirst.addActionListener(e -> {
            JScrollBar bar = jScrollPane.getVerticalScrollBar();
            bar.setValue(0);
        });

        btnPrevious = new JButton("<");
        btnPrevious.addActionListener(e -> {
            int height = table.getRowHeight() * (ITENS_POR_PAG);
            JScrollBar bar = jScrollPane.getVerticalScrollBar();
            bar.setValue(bar.getValue() - height);
        });

        btnNext = new JButton(">");
        btnNext.addActionListener(e -> {
            int height = table.getRowHeight() * (ITENS_POR_PAG);
            JScrollBar bar = jScrollPane.getVerticalScrollBar();
            bar.setValue(bar.getValue() + height);
        });

        btnLast = new JButton(">>");
        btnLast.addActionListener(e -> {
            JScrollBar bar = jScrollPane.getVerticalScrollBar();
            bar.setValue(bar.getMaximum());
        });

        btnFiltrar.addActionListener(e -> {
            aplicaFiltros();
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(btnFirst)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(lblDe)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jdcDataDeInicio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(btnPrevious)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnNext)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnLast)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(lblAte)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jdcDataDeFim, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 87, Short.MAX_VALUE)
                        .addComponent(btnFiltrar)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 207, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnFirst)
                    .addComponent(btnPrevious)
                    .addComponent(btnNext)
                    .addComponent(btnLast))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 30, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(btnFiltrar)
                        .addComponent(lblAte))
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(lblDe)
                        .addComponent(jdcDataDeInicio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(jdcDataDeFim, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        pack();
    }                      

    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Matricula.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Matricula.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Matricula.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Matricula.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Matricula().setVisible(true);
            }
        });
    }

    public void aplicaFiltros(){

        //String nome = txtNome.getText().trim();
      Date dataInicio = jdcDataDeInicio.getDate(),
              dataFim = jdcDataDeFim.getDate();

        Set<RowFilter<Object, Object>> filtrosTabela = new HashSet<>();
        //filtrosTabela.add(RowFilter.regexFilter(nome, 1));

        filtrosTabela.add( RowFilter.dateFilter(ComparisonType.AFTER, dataInicio, 2));
        filtrosTabela.add( RowFilter.dateFilter(ComparisonType.BEFORE, dataFim, 2));


        sorter.setRowFilter(RowFilter.andFilter(filtrosTabela));

    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton btnFiltrar;
    private javax.swing.JButton btnFirst;
    private javax.swing.JButton btnLast;
    private javax.swing.JButton btnNext;
    private javax.swing.JButton btnPrevious;
    private JScrollPane jScrollPane;
    private com.toedter.calendar.JDateChooser jdcDataDeFim;
    private com.toedter.calendar.JDateChooser jdcDataDeInicio;
    private javax.swing.JLabel lblAte;
    private javax.swing.JLabel lblDe;
    private javax.swing.JTable table;
    private MatriculaTableModel model;
    private TableRowSorter<TableModel> sorter;
    // End of variables declaration                   
}

MatriculaModel

public class MatriculaModel {
    private boolean selecionado;
    private String nome;
    private Date data;

    public boolean getSelecionado() {
        return selecionado;
    }

    public void setSelecionado(boolean selecionado) {
        this.selecionado = selecionado;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public Date getData() {
        return data;
    }

    public void setData(Date data) {
        this.data = data;
    }


}

MatriculaTableModel

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

public class MatriculaTableModel extends AbstractTableModel {


    private List<MatriculaModel> dados = new ArrayList<>();
    private String[] colunas = {"Selecionar", "Nome", "Data"};

    public MatriculaTableModel(List<MatriculaModel> model) {
        this.dados = model;
    }


    public Class<?> getColumnClass(int columnIndex) {
        return columnIndex == 0 ? Boolean.class : super.getColumnClass(columnIndex);
    }

    @Override
    public String getColumnName(int column){
        return colunas[column];
    }

    @Override
    public int getColumnCount() {
        return colunas.length;
    }

    @Override
    public int getRowCount() {
        return dados.size();
    }

    @Override
    public Object getValueAt(int linha, int coluna) {
        switch(coluna){
            case 0:
                return dados.get(linha).getSelecionado();
            case 1:
                return dados.get(linha).getNome();
            case 2:
                return dados.get(linha).getData();
        }

        return null;
    }

    public void setValueAt(Object valor, int linha, int coluna) {
        MatriculaModel tm = dados.get(linha);
        switch (coluna) {
        case 0:
            tm.setSelecionado(new Boolean((Boolean) valor));
            break;
        }
        fireTableDataChanged();
    }

    public void addRow(MatriculaModel tm) {
        this.dados.add(tm);
        this.fireTableDataChanged();    
    }

    public void removeRow(int linha){
        this.dados.remove(linha);
        this.fireTableRowsDeleted(linha, linha);
    }

    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return columnIndex == 0; 
    }

    public void deletarLinhas() {
        this.dados.clear();
        this.fireTableDataChanged();
    }

}

JSONUtils

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

public class JSONUtils {

    private static String strjson = null;

    private JSONUtils() {

        if (strjson == null)
            strjson = lerArquivo();
    }

    public static List<MatriculaModel> JSONtoList() {
        String str = lerArquivo();
        Type type = new TypeToken<List<MatriculaModel>>() {
        }.getType();

        Gson gson = new GsonBuilder().setDateFormat("dd/MM/yyyy").create();
        List<MatriculaModel> lista = gson.fromJson(str, type);

        for (MatriculaModel teste : lista) {
            System.out.println(teste.getSelecionado());
            System.out.println(teste.getNome());
        }
        return lista;
    }

    private static String lerArquivo() {
        String linha = "";

        try {
            FileReader arq = new FileReader("C:\Users\maily\Documents\NetBeansProjects\Matricula\src\matricula\dados.json");
            BufferedReader lerArq = new BufferedReader(arq);

            linha = lerArq.readLine();
            /*
             * while (linha != null) { System.out.printf(linha); linha = lerArq.readLine();
             * // lê da segunda até a última linha }
             */
            arq.close();

        } catch (IOException e) {
            System.err.printf("Erro na abertura do arquivo: %s.\n", e.getMessage());
        }
        // System.out.println(linha);
        return linha;
    }
}

data.json

[{"selecionado": false, "nome": "João", "data": "23/10/2000"}, {"selecionado": false, "nome": "Maria", "data": "03/05/2006"}, {"selecionado": false, "nome": "Pedro", "data": "30/02/2002"}, {"selecionado": false, "nome": "Laura", "data": "03/07/2008"}, {"selecionado": false, "nome": "Manoel", "data": "05/11/2018"}, {"selecionado": false, "nome": "João", "data": "23/10/2000"}, {"selecionado": false, "nome": "Maria", "data": "03/05/2006"}, {"selecionado": false, "nome": "Pedro", "data": "30/02/2002"}, {"selecionado": false, "nome": "Laura", "data": "03/07/2008"}, {"selecionado": false, "nome": "Manoel", "data": "05/11/2018"}, {"selecionado": false, "nome": "João", "data": "23/10/2000"}, {"selecionado": false, "nome": "Maria", "data": "03/05/2006"}, {"selecionado": false, "nome": "Pedro", "data": "30/02/2002"}, {"selecionado": false, "nome": "Laura", "data": "03/07/2008"}, {"selecionado": false, "nome": "Manoel", "data": "05/11/2018"}]

Download libs: JCalendar , Gson

    
asked by anonymous 08.11.2018 / 20:13

1 answer

2

Your filter does not work because of this snippet:

TableModel tableModel = table.getModel();
sorter = new TableRowSorter<TableModel>(tableModel);
table.setRowSorter(sorter);

model = new MatriculaTableModel(JSONUtils.JSONtoList());

table = new JTable(model);

You are creating an empty local model and passing it to your RowSorter , and just below you create another one and move to the table. Obviously the filter will never work, because in addition to not having data in this local model that it received, the model of the table is completely different from what was passed to it.

Another error is that you are setting the rowsorter for the table created empty and then create another one on top.

First you must create the TableModel, then set it as the table model, then create the rowsorter based on that TableModel and set it to the table, as below:

model = new MatriculaTableModel(JSONUtils.JSONtoList());
table.setModel(model);
sorter = new TableRowSorter<TableModel>(model);
table.setRowSorter(sorter);

That way, the filter works normally:

A code should not be just copied, it should be understood, otherwise you will always make the same mistakes as in the previous question, of using components without even understanding how they work. And to understand how it works, it is always important to visit the class documentation page.

    
09.11.2018 / 14:19