javaswingjtablerowsorter

Java JTable - show rows only which matches the string


I have a JTable populated with data from a database. I have added a search function that display the rows, if word matched to some rows when the data is typed into a JTextField. But at the minute as you type a string or word that do not matches any of the rows data, what I want to do is to hide all the rows, and the JTable will show just the column names. Just like when something matches IT, shows those rows only which has the string that user typed and hide others.

Here is my code that I am using:

               if (text.length() == 0) {
                 sorter.setRowFilter(null);
               } else {
                 try {
                   sorter.setRowFilter(
                       RowFilter.regexFilter(text));
                 } catch (PatternSyntaxException pse) {
                   System.err.println("Bad regex pattern");
                 }
               }
             }

Solution

  • You want to use a DocumentListener, along with the row filter. You can see how to Write a DocumentListener.

    Basically the listener listens for changes in the underlying document of the text field. From the methods you override in the DocumentListener, you can get the text, like you're currently doing, and set the regex ex filter like you're currently doing

    Here's simple example (disregard the applet. I just got the boilerplate code from this post and added the document listener). Note: that same post has an answer provided that will allow you to filter in a case-insensitive way, if you're looking for that functionality

    import javax.swing.JApplet;
    import javax.swing.JButton;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JTextField;
    import javax.swing.RowFilter;
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    import javax.swing.table.TableModel;
    import javax.swing.table.TableRowSorter;
    
    public class TestTableSorterFilter extends JApplet {
    
        private String[] columnNames
                = {"Country", "Capital", "Population in Millions", "Democracy"};
    
        private Object[][] data = {
            {"USA", "Washington DC", 280, true},
            {"Canada", "Ottawa", 32, true},
            {"United Kingdom", "London", 60, true},
            {"Germany", "Berlin", 83, true},
            {"France", "Paris", 60, true},
            {"Norway", "Oslo", 4.5, true},
            {"India", "New Delhi", 1046, true}
        };
    
        private JTable jTable = new JTable(data, columnNames);
    
        private TableRowSorter<TableModel> rowSorter
                = new TableRowSorter<>(jTable.getModel());
    
        private JTextField jtfFilter = new JTextField();
        private JButton jbtFilter = new JButton("Filter");
    
        public TestTableSorterFilter() {
            jTable.setRowSorter(rowSorter);
    
            JPanel panel = new JPanel(new BorderLayout());
            panel.add(new JLabel("Specify a word to match:"),
                    BorderLayout.WEST);
            panel.add(jtfFilter, BorderLayout.CENTER);
    
            add(panel, BorderLayout.SOUTH);
            add(new JScrollPane(jTable), BorderLayout.CENTER);
    
            jtfFilter.getDocument().addDocumentListener(new DocumentListener(){
    
                @Override
                public void changedUpdate(DocumentEvent arg0) {}
    
                @Override
                public void insertUpdate(DocumentEvent arg0) {
                    String text = jtfFilter.getText();
    
                    if (text.trim().length() == 0) {
                        rowSorter.setRowFilter(null);
                    } else {
                        rowSorter.setRowFilter(RowFilter.regexFilter(text));
                    }   
                }
    
                @Override
                public void removeUpdate(DocumentEvent arg0) {
                    String text = jtfFilter.getText();
                    if (text.trim().length() == 0) {
                        rowSorter.setRowFilter(null);
                    } else {
                        rowSorter.setRowFilter(RowFilter.regexFilter(text));
                    }   
                }
            });
        }
    }