I have a project that has a table and items to be filtered. They are a JComboBox
category, a JTextField
, and a JDateCooser
date range.
I made all the filters separately with RowFilter.andFilter
and now I need to put them together in a RowFilter.orFilter
so that anyone can happen at any time.
I need to be able to filter the table data using different combinations of filled fields:
- Category, Name, and Date Range Simultaneously (AndAnd Filters)
- category only (FilterCateg)
- only name (filterId, yes the name is the same)
- only the date range (datafilter)
- name and date range simultaneously (filterIdData)
- category and name simultaneously (filterIdCateg)
- category and date range simultaneously (FilterDatacateg)
They all need to be possible to happen according to what the program user decides to fill at the time of pressing the filter button.
Representing category by C, name by N, and date range by D What I need to happen would look like this:
((C && N && D) || (C) || (N) || (D) || (N && D) || (C && N) || (C && D))
Filters
import java.awt.Dimension;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.RowFilter;
import javax.swing.RowFilter.ComparisonType;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class Filtros extends javax.swing.JFrame {
private final int ITENS_POR_PAG = 5;
public Filtros() {
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();
lblCategoria = new javax.swing.JLabel();
cbxCategoria = new javax.swing.JComboBox<>();
jLabel1 = new javax.swing.JLabel();
txtNome = new javax.swing.JTextField();
btnFiltrar = new javax.swing.JButton();
lblDataDeInicio = new javax.swing.JLabel();
jdcDataDeInicio = new com.toedter.calendar.JDateChooser();
lblDataDeFim = 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");
model = new MatriculaTableModel(JSONUtils.JSONtoList());
table.setModel(model);
sorter = new TableRowSorter<TableModel>(model);
table.setRowSorter(sorter);
table.setDefaultRenderer(Date.class, new MatriculaTableRenderer());
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 = 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();
});
lblCategoria.setText("Categoria");
cbxCategoria.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Todas", "Fundamental", "Médio" }));
jLabel1.setText("Nome:");
btnFiltrar.setText("Filtrar");
lblDataDeInicio.setText("De:");
lblDataDeFim.setText("Até:");
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(94, 94, 94)
.addComponent(btnFirst)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnPrevious)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnNext)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnLast))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(lblDataDeInicio)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jdcDataDeInicio, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(lblDataDeFim)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jdcDataDeFim, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(0, 16, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(lblCategoria)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cbxCategoria, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txtNome)
.addGap(18, 18, 18)
.addComponent(btnFiltrar)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 176, 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, 21, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(cbxCategoria, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblCategoria)
.addComponent(jLabel1)
.addComponent(txtNome, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btnFiltrar))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lblDataDeInicio)
.addComponent(jdcDataDeInicio, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lblDataDeFim)
.addComponent(jdcDataDeFim, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(20, 20, 20))
);
pack();
}// </editor-fold>
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(Filtros.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Filtros.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Filtros.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Filtros.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 Filtros().setVisible(true);
}
});
}
public void aplicaFiltros(){
String nome = txtNome.getText().trim(),
categoria = cbxCategoria.getSelectedItem().toString().trim();
Date dataInicio = jdcDataDeInicio.getDate(),
dataFim = jdcDataDeFim.getDate();
//Filtra Categoria, nome e intervalo de data (AND)
Set<RowFilter<Object, Object>> filtrosAnd = new HashSet<>();
String frmNome = String.format("^%s$", nome);
filtrosAnd.add(RowFilter.regexFilter(frmNome, 1));
if(!categoria.equals("Todas")) {
String frmCateg = String.format("^%s$", categoria);
filtrosAnd.add(RowFilter.regexFilter(frmCateg, 3));
}
filtrosAnd.add(RowFilter.dateFilter(ComparisonType.AFTER, dataInicio, 2));
filtrosAnd.add(RowFilter.dateFilter(ComparisonType.BEFORE, dataFim, 2));
sorter.setRowFilter(RowFilter.andFilter(filtrosAnd));
/*
//Filtra só categoria
Set<RowFilter<Object, Object>> filtroCateg = new HashSet<>();
if(!categoria.equals("Todas")) {
String frmCateg = String.format("^%s$", categoria);
filtroCateg.add(RowFilter.regexFilter(frmCateg, 3));
}
sorter.setRowFilter(RowFilter.andFilter(filtroCateg));
//Filtra só nome
Set<RowFilter<Object, Object>> filtroId = new HashSet<>();
frmNome = String.format("^%s$", nome);
filtroId.add(RowFilter.regexFilter(frmNome, 1));
sorter.setRowFilter(RowFilter.andFilter(filtroId));
//Filtra só intervalo de data
Set<RowFilter<Object, Object>> filtroData = new HashSet<>();
filtroData.add(RowFilter.dateFilter(ComparisonType.AFTER, dataInicio, 2));
filtroData.add(RowFilter.dateFilter(ComparisonType.BEFORE, dataFim, 2));
sorter.setRowFilter(RowFilter.andFilter(filtroData));
//Filtra nome e intervalo de data
Set<RowFilter<Object, Object>> filtroIdData = new HashSet<>();
frmNome = String.format("^%s$", nome);
filtroId.add(RowFilter.regexFilter(frmNome, 1));
filtroIdData.add(RowFilter.dateFilter(ComparisonType.AFTER, dataInicio, 2));
filtroIdData.add(RowFilter.dateFilter(ComparisonType.BEFORE, dataFim, 2));
sorter.setRowFilter(RowFilter.andFilter(filtroIdData));
//Filtra categoria e nome
Set<RowFilter<Object, Object>> filtroIdCateg = new HashSet<>();
frmNome = String.format("^%s$", nome);
filtroIdCateg.add(RowFilter.regexFilter(frmNome, 1));
if(!categoria.equals("Todas")) {
String frmCateg = String.format("^%s$", categoria);
filtroIdCateg.add(RowFilter.regexFilter(frmCateg, 3));
}
sorter.setRowFilter(RowFilter.andFilter(filtroIdCateg));
//Filtra categoria e intervalo de data
Set<RowFilter<Object, Object>> filtroDataCateg = new HashSet<>();
filtroDataCateg.add(RowFilter.dateFilter(ComparisonType.AFTER, dataInicio, 2));
filtroDataCateg.add(RowFilter.dateFilter(ComparisonType.BEFORE, dataFim, 2));
if(!categoria.equals("Todas")) {
String frmCateg = String.format("^%s$", categoria);
filtroDataCateg.add(RowFilter.regexFilter(frmCateg, 3));
}
sorter.setRowFilter(RowFilter.andFilter(filtroDataCateg)); */
}
// 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 javax.swing.JComboBox<String> cbxCategoria;
private com.toedter.calendar.JDateChooser jdcDataDeFim;
private javax.swing.JLabel jLabel1;
private JScrollPane jScrollPane;
private com.toedter.calendar.JDateChooser jdcDataDeInicio;
private javax.swing.JLabel lblCategoria;
private javax.swing.JLabel lblDataDeFim;
private javax.swing.JLabel lblDataDeInicio;
private javax.swing.JTable table;
private javax.swing.JTextField txtNome;
private MatriculaTableModel model;
private TableRowSorter<TableModel> sorter;
// End of variables declaration
}
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());
System.out.println(teste.getData());
}
return lista;
}
private static String lerArquivo() {
String linha = "";
try {
FileReader arq = new FileReader("C:\Users\maily\Documents\NetBeansProjects\Filtros\src\filtros\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;
}
}
MatriculaModel
import java.util.Date;
public class MatriculaModel {
private boolean selecionado;
private String nome;
private Date data;
private String categoria;
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;
}
public String getCategoria() {
return categoria;
}
public void setCategoria(String categoria) {
this.categoria = categoria;
}
}
MatriculaTableModel
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.table.AbstractTableModel;
public class MatriculaTableModel extends AbstractTableModel {
private List<MatriculaModel> dados = new ArrayList<>();
private final String[] colunas = {"Selecionar", "Nome", "Data", "Categoria"};
public MatriculaTableModel(List<MatriculaModel> model) {
this.dados = model;
}
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return Boolean.class;
case 2:
return Date.class;
default:
return 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();
case 3:
return dados.get(linha).getCategoria();
}
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();
}
}
MatriculaTableRenderer
import java.awt.Component;
import java.text.SimpleDateFormat;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
public class MatriculaTableRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
switch (column) {
case 2:
setText(new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(value));
break;
default:
break;
}
return this;
}
@Override
protected void setValue(Object value) {
super.setValue(value);
}
}
data.json
[{"selecionado": false, "nome": "João", "data": "23/10/2000 00:00:00", "categoria": "Fundamental"}, {"selecionado": false, "nome": "Maria", "data": "03/05/2006 00:00:00", "categoria": "Médio"}, {"selecionado": false, "nome": "Pedro", "data": "30/02/2002 00:00:00", "categoria": "Fundamental"}, {"selecionado": false, "nome": "Laura", "data": "03/07/2008 00:00:00", "categoria": "Médio"}, {"selecionado": false, "nome": "Manoel", "data": "05/11/2018 00:00:00", "categoria": "Fundamental"},{"selecionado": false, "nome": "João", "data": "23/10/2000 00:00:00", "categoria": "Fundamental"}, {"selecionado": false, "nome": "Maria", "data": "03/05/2006 00:00:00", "categoria": "Médio"}, {"selecionado": false, "nome": "Pedro", "data": "30/02/2002 00:00:00", "categoria": "Fundamental"}, {"selecionado": false, "nome": "Laura", "data": "03/07/2008 00:00:00", "categoria": "Médio"}, {"selecionado": false, "nome": "Manoel", "data": "05/11/2018 00:00:00", "categoria": "Fundamental"},{"selecionado": false, "nome": "João", "data": "23/10/2000 00:00:00", "categoria": "Fundamental"}, {"selecionado": false, "nome": "Maria", "data": "03/05/2006 00:00:00", "categoria": "Médio"}, {"selecionado": false, "nome": "Pedro", "data": "30/02/2002 00:00:00", "categoria": "Fundamental"}, {"selecionado": false, "nome": "Laura", "data": "03/07/2008 00:00:00", "categoria": "Médio"}, {"selecionado": false, "nome": "Manoel", "data": "05/11/2018 00:00:00", "categoria": "Fundamental"}]