Search code examples
javajtablerowfiltertablerowsorter

How to get the current filtered TableModel


I have this code below, in which, after a mouseClick event it filters the rows based on a JList getSelectedItem().toString(), here is the code:

try{
        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(easypath.doctorBusiness_table.getModel());
        easypath.doctorBusiness_table.setRowSorter(rowSorter);
        String selected = easypath.drname_jlist.getSelectedValue().toString();
        rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + selected));

    }

It works fine, and filters the rows based on the selected String.


But, I further I wish to filter the filtered model based on dates, although the date filtering works fine on the DefaultTableModel but when I try to pass the current table model it does not work

So, I hope I could explain my problem here as I need to pass a filtered TableModelfor date filtering. Any suggestions would help.

Thanks for your time

UPDATE

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.RowFilter;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class testFilter extends javax.swing.JFrame {

    public testFilter() {
        initComponents();
    }

public void dateSearch() {
    try {
        DateFormat format = new SimpleDateFormat("dd/MM/yyyy");

        String string1 = "01/07/2015";
        Date startDate = format.parse(string1);
        System.out.println(startDate);

        String string2 = "31/07/2015";
        Date endDate = format.parse(string2);
        System.out.println(endDate);

        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(dataTable.getModel());
        dataTable.setRowSorter(rowSorter);

        List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(2);
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.AFTER, startDate));
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.BEFORE, endDate));
        RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
        rowSorter.setRowFilter(rf);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void dateString_Search(){
    try {
        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(dataTable.getModel()); //  String Filtering 
        dataTable.setRowSorter(rowSorter);                                                 //  table here
        String selected = "Nissan SUV";                                                    //  to get
        rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + selected));                  //  current TableModel 

        JOptionPane.showMessageDialog(null, dataTable.getRowCount()); // <--- For checking current Row Count

        DateFormat format = new SimpleDateFormat("dd/MM/yyyy");

        String string1 = "01/07/2015";
        Date startDate = format.parse(string1);
        System.out.println(startDate);
        String string2 = "31/07/2015";
        Date endDate = format.parse(string2);
        System.out.println(endDate);

        TableRowSorter<TableModel> filteredRowSorter = new TableRowSorter<>(dataTable.getModel()); //<-- Getting the current table Model After String Search
        dataTable.setRowSorter(filteredRowSorter); 
        List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(2);
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.AFTER, startDate));
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.BEFORE, endDate));
        RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
        filteredRowSorter.setRowFilter(rf);


    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
}



private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    dataTable = new javax.swing.JTable();
    dateSearch_btn = new javax.swing.JButton();
    stringSearch_btn = new javax.swing.JButton();
    dateStringSearch_btn = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setResizable(false);

    dataTable.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {
            {"Nissan Micra", new Date(), "20000"},
            {"Nissan SUV", new Date(), "30000"},
            {"Nissan SUV", new Date(), "40000"},
            {"Nissan SUV", new Date(), "50000"},
            {"Nissan SUV", new Date(), "50000"},
            {"Ford Mustang", new Date(), "70000"},
            {"Ford Cobra", new Date(), "70000"},
            {"Nissan SUV", new Date(), "40000"},
            {"Nissan SUV", new Date(), "60000"},
            {"Nissan SUV", new Date(), "65000"},
            {"Nissan SUV", new Date(), "70000"},
            {"Tata Sumo", new Date(), "70000"}
        },
        new String [] {
            "Name", "Date", "Rate"
        }
    ));
    putDateInTable();
    jScrollPane1.setViewportView(dataTable);

    dateSearch_btn.setText("Date Search");
    dateSearch_btn.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            dateSearch_btnActionPerformed(evt);
        }
    });

    stringSearch_btn.setText("String Search");
    stringSearch_btn.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            stringSearch_btnActionPerformed(evt);
        }
    });

    dateStringSearch_btn.setText("Date+String");
    dateStringSearch_btn.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            dateStringSearch_btnActionPerformed(evt);
        }
    });

    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)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(dateSearch_btn)
                    .addGap(90, 90, 90)
                    .addComponent(stringSearch_btn)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(dateStringSearch_btn)))
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 223, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(dateSearch_btn)
                .addComponent(stringSearch_btn)
                .addComponent(dateStringSearch_btn))
            .addContainerGap(25, Short.MAX_VALUE))
    );

    pack();
}

private void stringSearch_btnActionPerformed(java.awt.event.ActionEvent evt) {                                                 
    try {
        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(dataTable.getModel());
        dataTable.setRowSorter(rowSorter);
        String selected = "Nissan SUV";
        rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + selected));
        JOptionPane.showMessageDialog(null, dataTable.getRowCount());

    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
}

private void dateSearch_btnActionPerformed(java.awt.event.ActionEvent evt) {                                               
    dateSearch();
}

private void dateStringSearch_btnActionPerformed(java.awt.event.ActionEvent evt) {                                                     
    dateString_Search();
}

private void putDateInTable() {
    Date formatDate = new Date();
    Calendar c = Calendar.getInstance();
    c.setTime(formatDate);
    c.add(Calendar.DATE, - 1);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 0, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +5);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 1, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +1);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 2, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, - 16);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 3, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +30);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 4, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +55);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 5, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +155);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 6, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -23);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 7, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -22);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 8, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -21);
    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 9, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -29);
    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 10, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -50);
    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 11, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +100);


}

public static void main(String args[]) {

    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new testFilter().setVisible(true);
        }
    });
}
private javax.swing.JTable dataTable;
private javax.swing.JButton dateSearch_btn;
private javax.swing.JButton dateStringSearch_btn;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JButton stringSearch_btn;
}

Here is the modified code for the filtering, Created the eventListeners dateSearch, stringSearch and dateStringSearch. First two works fine but the third one is not working properly even if I try to create a get the current model. Please suggest, Thanks


Solution

  • Why are you trying to get the TableModel after the string search? I said you can't do this unless you want to copy all the data and create a new TableModel.

    The TableModel doesn't change when you do filtering on the JTable. All the data is still stored in the TableModel. What changes is the View. The JTable only displays the filtered rows.

    Why does your filter code not look like the code from the Swing tutorial on filtering? In your code you create a new TableRowSorter and add it to the table. In the Swing tutorial they just reset the filter on the TableRowSorter using the setRowFilter(...) method. This is minor, but it demonstrates to me that you haven't read the tutorial or if you did, why did you modify the code to make is more complex?

    In my comments I suggested you have an "andFilter" with 3 conditions. I tried to explain this multiple ways comparing it to an if statement with 3 conditions. Why does your "andFilter" only have two conditions when you do the "date/string search"?

    I copied the code from the "date search" and made the following changes to create your date/string filter:

    List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(3);
    String selected = "Nissan SUV";
    filters.add(RowFilter.regexFilter("(?i)" + selected)); // added the string filter
    filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.AFTER, startDate));
    filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.BEFORE, endDate));
    RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
    rowSorter.setRowFilter(rf);
    

    Now you have an "andFilter" with 3 conditions.

    However a better design would be to create methods like getStartDateFilter(), getEndDateFilter(), getStringFilter() so you don't duplicate code. Then you can build the filter like:

    List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(3);
    filters.add(getStringFilter());
    filters.add(getStartDateFilter());
    filters.add(getEndDateFilter();
    RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
    rowSorter.setRowFilter(rf);