Hello! I have a problem with filtering JTable (AbstractTableModel)... So, this is my code:

//Create table and filter
    public TableRowSorter<MyTableModel> sorter;
    public static MyTableModel tableModel;
...

//Define table and fill it with List "userDataList"
List<UserDataRow> userDataList = readuserdatafromfile();
        filetree.Form.tableDetails = new JTable();
        tableModel = new MyTableModel( userDataList );
        filetree.Form.tableDetails.setModel(tableModel);
        filetree.Form.tableDetails.setFillsViewportHeight(true);

// Create textfield and add DocumentListener
JTextField txtFirstName = new JTextField();
txtFirstName.getDocument().addDocumentListener(new DocumentListener() {
          public void changedUpdate(DocumentEvent e) {
              newFilter();
          }
          public void insertUpdate(DocumentEvent e) {
              newFilter();
          }
          public void removeUpdate(DocumentEvent e) {
              newFilter();
          }
        });
// Define filter
private void newFilter() {
        RowFilter<MyTableModel, Object> rf = null;
        try {
          rf = RowFilter.regexFilter("(?i)" + txtFirstName.getText());
        } catch (java.util.regex.PatternSyntaxException e) {
            System.err.println(e.getMessage());
        }
        sorter.setRowFilter(rf);
    }

When I enter a char to textfield, I get the following error message:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at filetree.FilterClass.newFilter(FilterClass.java:238)
        at filetree.FilterClass.access$000(FilterClass.java:34)
        at filetree.FilterClass$1.insertUpdate(FilterClass.java:126)
        at javax.swing.text.AbstractDocument.fireInsertUpdate(AbstractDocument.java:185)
        at javax.swing.text.AbstractDocument.handleInsertString(AbstractDocument.java:734)
        at javax.swing.text.AbstractDocument.insertString(AbstractDocument.java:693)
        at javax.swing.text.PlainDocument.insertString(PlainDocument.java:114)
        at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:655)
        at javax.swing.text.JTextComponent.replaceSelection(JTextComponent.java:1351)
        at javax.swing.text.DefaultEditorKit$DefaultKeyTypedAction.actionPerformed(DefaultEditorKit.java:859)
        at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1633)
        at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
        at javax.swing.JComponent.processKeyBindings(JComponent.java:2886)
        at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
        at java.awt.Component.processEvent(Component.java:6044)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4630)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1850)
        at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:712)
        at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:990)
        at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:855)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:676)
        at java.awt.Component.dispatchEventImpl(Component.java:4502)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Window.dispatchEventImpl(Window.java:2478)
        at java.awt.Component.dispatchEvent(Component.java:4460)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Pliz, help me understand and fix this error.

null pointer usually means a variable is not initialized. you may do assignment but its not created with new perhaps. you have

List<UserDataRow> userDataList = readuserdatafromfile();

Do you need = new userDataList() then maybe begin assigning values from a file? I cant answer 100% cause i can't see all that's going on.

Mike

What's the line in your code where you're getting the error? You posted code segments, so I can't tell what line 238 actually is.

If you're having problems, make sure that readuserdatafromfile() actually returns a List of type UserDataRow, and put a bunch of System.out.println([variable]==null) checks throughout your code if you're not sure what's happening.

Side note: For method names, generally you want to capitalize the first letter of each word, excluding the first word, for readability purposes (it's also easier to type!), and also, conciseness is valued; so, perhaps instead of readuserdatafromfile() , readData() might be better.

Edited 6 Years Ago by coil: n/a

Also this isn't complpetely safe:

#
private void newFilter() {
#
RowFilter<MyTableModel, Object> rf = null;
#
try {
#
rf = RowFilter.regexFilter("(?i)" + txtFirstName.getText());
#
} catch (java.util.regex.PatternSyntaxException e) {
#
System.err.println(e.getMessage());
#
}
#
sorter.setRowFilter(rf);
#
}

if it cant assign a value to rf, rf remains null, and it throws an exception, but you go ahead and use rf anyway after the try catch, no matter if it could actually do an assignment. thats the sort of stuff you'll be looking for. Your null pointer exception just means a variable is used that is null for some reason. the constructor may not have been called, i.e. a new statement, or an assignment like above failed.

And by the way you may be ok on this, but for that above to work, the line

RowFilter.regexFilter("(?i)" + txtFirstName.getText());

has to return a row filter object. I didn't google the api.

also stuff like this helps debug:

System.err.println(e.getMessage());

but if you don't spot the text being printed as coming from this line, i.e. you don't realize that text is e.getMessage() it slows down debugging. Sometimes you want markers on print lines like Syster.err.println("an exception assigning rf" + e.getMessage() + "end handling of rf assignment exception");


Mike

Edited 6 Years Ago by adams161: n/a

Hi guys!

Thank you for the comments! I've updated my code and now I don't have any error messages. However, when I type any char in txtFirstName, then my filter works incorrectly. For instance, when I type "a", then I could get rows with "Robert", etc. But the word "Robert" doesn't contain the char "a".

public TableRowSorter<MyTableModel> sorter;
    public static MyTableModel tableModel;
//...
        List<UserDataRow> userDataList = readData();
        filetree.Form.tableDetails = new JTable();
        tableModel = new MyTableModel( userDataList ) ;
        filetree.Form.tableDetails.setModel(tableModel);
        filetree.Form.tableDetails.setFillsViewportHeight(true);

        sorter = new TableRowSorter<MyTableModel>(tableModel);
        filetree.Form.tableDetails.setRowSorter(sorter);
//...
        CaretListener listener = new CaretListener() {
          public void caretUpdate(CaretEvent caretEvent) {
              try {
                   sorter.setRowFilter(RowFilter.regexFilter("(?i)" + txtFirstName.getText()));
                   sorter.setSortKeys(null);
                   filetree.Form.tableDetails.setRowSorter(sorter);
              }  catch (Exception e)
              {
                   System.out.println(e.getMessage());
              }
          }
        };

txtFirstName.addCaretListener(listener);

So, what could be wrong in this case?

Ups, I think I understand my problem...I'm filtering all columns of the table...However, I would like to filter based on the SECOND COLUMN of my table. Could someone remind me how to do that?

Ok, I've solved the problem. This is my code for multiple filters for JTable, maybe one day it will be useful for someone:

CaretListener listener = new CaretListener() {
          public void caretUpdate(CaretEvent caretEvent) {
              try {
                    java.util.List<RowFilter<Object,Object>> filters = new ArrayList<RowFilter<Object,Object>>(3);
                    filters.add(RowFilter.regexFilter("(?i)" + txtRegNum.getText(),0));
                    filters.add(RowFilter.regexFilter("(?i)" + txtFirstName.getText(),1));
                    filters.add(RowFilter.regexFilter("(?i)" + txtLastName.getText(),2));
                    filters.add(RowFilter.regexFilter("(?i)" + txtProfession.getText(),3));
                    filters.add(RowFilter.regexFilter("(?i)" + txtSex.getText(),4));
                    filters.add(RowFilter.regexFilter("(?i)" + txtDateofBirth.getText(),5));

                    RowFilter<Object,Object> serviceFilter = RowFilter.andFilter(filters);
                    sorter.setRowFilter(serviceFilter);
              }  catch (Exception e)
              {
                   System.out.println(e.getMessage());
              }
          }
        };

        txtRegNum.addCaretListener(listener);
        txtFirstName.addCaretListener(listener);
        txtLastName.addCaretListener(listener);
        txtProfession.addCaretListener(listener);
        txtSex.addCaretListener(listener);
        txtDateofBirth.addCaretListener(listener);

Thanks for suggestions!

maybe this is helpful

http://jtute.com/java6/0505.html

his sorter works so that "If you click one of the columns in the JTable, the data will be sorted based on the content of the clicked column."

[edit] commented before seeing you had solved it. i still like this method sorting by column clicked personally :)

Mike

Edited 6 Years Ago by adams161: n/a

This question has already been answered. Start a new discussion instead.