Search code examples
javaswingrowfilter

JTable row filtering based on values of two different columns that Have same data


i have JTable that has a data like follow :

------------------------
| Name | Num 1 | Num 2 |
------------------------
| Data |    9  |  0    |
| Data |   17  |  24   |
| Data |    0  |  0    |
| Data |    0  |  5    |
------------------------

i have a RowFilter that Must be hide a Rows that Includes 0 on row Num 1 and Num 2 !

sorter = new TableRowSorter<>(((model)));

List<RowFilter<Object, Object>> rfs = new ArrayList<>(2);

String regexHider1 = "(?i)^" + "0" + "$";
String regexHider2 = "(?i)^" + "0" + "$";

rfs.add(RowFilter.notFilter(RowFilter.regexFilter(regexHider1, 1)));
rfs.add(RowFilter.notFilter(RowFilter.regexFilter(regexHider1, 2)));

RowFilter<Object, Object> af = RowFilter.andFilter(rfs);

sorter.setRowFilter(af);

jTable1.setRowSorter(sorter);

the output was :

------------------------
| Name | Num 1 | Num 2 |
------------------------
| Data |   17  |  24   |
------------------------

but what i need is to hide if the Num 1 And Num 2 both Includes 0 !

What i need is like the following :

------------------------
| Name | Num 1 | Num 2 |
------------------------
| Data |    9  |  0    |
| Data |   17  |  24   |
| Data |    0  |  5    |
------------------------

Only 1 row hided because only 1 row include 0 on Bothe Num1 and Num2

Example Code :

package Classes;

import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.RowSorter;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class JTableExample {

    DefaultTableModel model = new DefaultTableModel();

    public JFrame frame = new JFrame();

    public RowSorter<TableModel> sortert = new TableRowSorter<>(model);

    public TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(((model)));

    public JTableExample() {

        String[] cols = {"Name", "Num 1", "Num 2"};

        JTable table = new JTable(model);

        table.setModel(model);
        model.setColumnIdentifiers(cols);

        model.addRow(new Object[]{"Data", 9, 0});
        model.addRow(new Object[]{"Data", 17, 24});
        model.addRow(new Object[]{"Data", 0, 0});
        model.addRow(new Object[]{"Data", 0, 5});

        JButton btn = new JButton();

        btn.setText("Filter");

        btn.addActionListener((e) -> {

            sorter = new TableRowSorter<>(((model)));

            List<RowFilter<Object, Object>> rfs = new ArrayList<>(2);

            String regexHider1 = "(?i)^" + "0" + "$";
            String regexHider2 = "(?i)^" + "0" + "$";

            rfs.add(RowFilter.notFilter(RowFilter.regexFilter(regexHider1, 1)));
            rfs.add(RowFilter.notFilter(RowFilter.regexFilter(regexHider2, 2)));

            RowFilter<Object, Object> af = RowFilter.andFilter(rfs);

            sorter.setRowFilter(af);

            table.setRowSorter(sorter);

        });

        JPanel jdb = new JPanel();

        jdb.setLayout(new FlowLayout());

        jdb.add(table);
        jdb.add(btn);
        jdb.add(table);

        frame.add(jdb);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new JTableExample();
            }
        });
    }
}

Solution

  • Looks like the "notFilter" was used in the wrong place. This seems to work:

    List<RowFilter<Object, Object>> rfs = new ArrayList<>(2);
    rfs.add(RowFilter.numberFilter(RowFilter.ComparisonType.EQUAL, 0, 1));
    rfs.add(RowFilter.numberFilter(RowFilter.ComparisonType.EQUAL, 0, 2));
    RowFilter<Object, Object> af = RowFilter.andFilter(rfs);
    
    sorter = new TableRowSorter<>(((model)));
    sorter.setRowFilter(  RowFilter.notFilter(af) );
    table.setRowSorter(sorter);
    

    I also played around with using a custom RowFilter:

    RowFilter<Object,Object> rf = new RowFilter<Object,Object>()
    {
        public boolean include(Entry<? extends Object, ? extends Object> entry)
        {
            Integer column1 = (Integer)entry.getValue(1);
            Integer column2 = (Integer)entry.getValue(2);
    
            if (column1.intValue() == 0 && column2.intValue() == 0)
                return false;
            else
                return true;
        }
    };
    
    sorter = new TableRowSorter<>(((model)));
    sorter.setRowFilter(rf);
    table.setRowSorter(sorter);
    

    Note: in both cases the filter expects Integer data so it won't work if you edit a column and change the value to 0, because the model will be updated with a String value. I would assume your real TableModel would override the getColumnClass() method to return Integer.class for the last 2 columns.