How to apply a Jdatechooser two filter to a Jtable?

Asked

Viewed 294 times

1

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

I have a DATE field in the String type table and I have two JDateChooser lib Jcalendar on the interface. I need to take these dates and see if the table date is between the selected range on JDateChooser.

But I have no idea how to do this check. I made a very simple example, I didn’t even put a field to search for the name but I wrote it in the code as if 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;
    }
}

json data.

[{"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

1 answer

2


Your filter does not work due to, specifically, 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 on to the table. Obviously the filter will never work, because in addition to not having data in this local model that it received, the table model is completely different from what was passed to it.

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

First create the Tablemodel, then define it as a table model, then create the rowsorter based on that Tablemodel and set to the table, as below:

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

This way, the filter works normally:

inserir a descrição da imagem aqui

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

  • Thanks for the help.

  • 1

    @To display the date correctly, see this answer: https://answall.com/a/122302/28595

  • You solved the date format but the filter stopped working. Thank you!

  • 1

    @Nice, really for the above solution would have to adapt. But instead, look at the Tablecellrenderer that I put in this same question. In it I rescan a date field, without changing the Date type. It is called "COLUNA_DATA", only create a tablecellrenderer and apply the date column.

  • It worked perfectly, thank you very much for the tip. It was really very useful.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.