-1

I am trying to create a table that can be filtered but I keep getting a null pointer exception for the getRowCount() method in my table model class.

HomePagePanel(where my table is)

public class homepagePanel extends JPanel implements ActionListener {
private JButton uploadEmail, viewEmail, logout, delete;
private JLabel userLog;
private JLabel tableLabel;
private JScrollPane scrollPane;
private EmailTableListener emailTableListener;
//private EmailTablePanel EmailPanel;
private HomePagePanelListener homepagePanelListener;
private List<Item> dc;
private Controller controller;
private JTable table;
private EmailTableModel emailModel;
private JPopupMenu popup;
private JTextField filterText;
private JLabel filterLabel;
private TableRowSorter<EmailTableModel> sorter;




public homepagePanel() {



    controller = new Controller();

    userLog = new JLabel("Logged in:");

    uploadEmail = new JButton("Upload");
    viewEmail = new JButton("View");
    delete = new JButton("Delete");
    logout = new JButton("Log Out");
    tableLabel = new JLabel("Emails stored");

    //Email stuff
    emailModel = new EmailTableModel();
    sorter = new TableRowSorter<EmailTableModel>(emailModel);
    table = new JTable(emailModel);
    table.setRowSorter(sorter);

    //
    filterLabel = new JLabel("Filter Text: ", SwingConstants.TRAILING);
    filterText = new JTextField(10);
    filterLabel.setLabelFor(filterText);

    //documenet listener
    filterText.getDocument().addDocumentListener(new DocumentListener(){

        @Override
        public void changedUpdate(DocumentEvent e) {
            // TODO Auto-generated method stub
            newFilter();
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            // TODO Auto-generated method stub
            newFilter();
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            // TODO Auto-generated method stub
            newFilter();
        }
     });






    // Adds the table to a scrollpane
    scrollPane = new JScrollPane(table);
    scrollPane
            .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    scrollPane
            .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    popup = new JPopupMenu();

    JMenuItem removeItem = new JMenuItem("Delete row");
    popup.add(removeItem);


    //adds mouse listener to show 
    table.addMouseListener(new MouseAdapter(){

        public void mousePressed(MouseEvent e) {
            int row = table.rowAtPoint(e.getPoint());
            table.getSelectionModel().setSelectionInterval(row, row);
            if(e.getButton() == MouseEvent.BUTTON3){
                popup.show(table, e.getX(), e.getY());//shows popup

            }
        }

    });
    //removeitem actionlistener
    removeItem.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            int row = table.getSelectedRow();

            if(emailTableListener != null){
                emailTableListener.rowDeleted(row);
                emailModel.fireTableRowsDeleted(row, row);
            }
        }

    });
    // EmailPanel = new EmailTablePanel();



    layoutComponents();

    viewEmail.addActionListener(this);
    uploadEmail.addActionListener(this);
    logout.addActionListener(this);

private void newFilter(){
    RowFilter<EmailTableModel, Object> rf = null;

    try{
        rf = RowFilter.regexFilter(filterText.getText());
    }catch(java.util.regex.PatternSyntaxException e){
        return;
    }
    sorter.setRowFilter(rf);
}

TableModel

package view;

import java.util.List;

import javax.swing.table.AbstractTableModel;

import model.Item;

public class EmailTableModel extends AbstractTableModel {

private List<Item> dc;
private String[] colNames = {"ID", "To", "From", "Subject", "Topic", "Message Content", "Comments", "Attachments"};

public EmailTableModel(){
    //System.out.println(dc.size());
}

public String getColumnName(int column) {
    // TODO Auto-generated method stub
    return colNames[column];
}


public void setData(List<Item> dc){
    this.dc = dc;
}
@Override
public int getColumnCount() {
    // TODO Auto-generated method stub
    return 8;
}

@Override
public int getRowCount() {
    // TODO Auto-generated method stub
    return dc.size();
}

@Override
public Object getValueAt(int row, int column) {
    Item item = dc.get(row);

    switch(column){
    case 0: 
        return item.getId();
    case 1:
        return item.getTo();
    case 2:
        return item.getFrom();
    case 3:
        return item.getSubject();
    case 4:
        return item.getTopic();
    case 5:
        return item.getMessageContent();
    case 6:
        return item.getComments();
    case 7:
        return item.getAttachments();

    }
    return null;
}

public Class getColumnClass(int column) {
    Class returnValue;
    // Verifying that the column exists(index > 0 && index < number of
    // columns
    if ((column >= 0) && (column < getColumnCount())) {
        returnValue = getValueAt(0, column).getClass();
    } else {
        // Returns the class for the item in the column
        returnValue = Object.class;
    }
    return returnValue;
};

}

database class(retriving data for jtable)

    public void loadItems() throws SQLException {
    //connects to the database
    getConnected();
    Items.clear();//clears the linked list
    String sql = "Select Id, Reciever, Sender, Subject, topic, Email_Content, Comments, Attachments from item order by Id";//querly for select statement
    Statement selectStatement = con.createStatement();
    ResultSet results = selectStatement.executeQuery(sql);

    while (results.next()) {
        int id = results.getInt("Id");
        String To = results.getString("Reciever");
        String From = results.getString("Sender");
        String Subject = results.getString("Subject");
        String topic = results.getString("topic");
        String Email_Content = results.getString("Email_Content");
        String Comments = results.getString("Comments");
        String Attachments = results.getString("Attachments");

        Item item = new Item(id, To, From, Subject, topic, Email_Content,
                Comments, Attachments);
        Items.add(item);//add item to linked list

    }

}

mainframe(where I set the data

loadItems(); //method used to load the data from the database
HomepagePanel.setData(controller.getItems());//sets data 
Kerpal
  • 48
  • 2
  • 9
  • yes I understood that but I'm not understanding why it is null since I set the data for it in my mainframe class. – Kerpal Jul 21 '14 at 13:51
  • Sorry about that. I fixed the code that was not formatted properly. The code that is shown here only shows what is relevant to the table functionality of the table. I didn't enter in the code that lays out the homepagepanel because I thought it would be too much. Also loadItems() method is calling the controller's loaditem() method which is calling the method in my database class. – Kerpal Jul 21 '14 at 14:03

1 Answers1

0

Here:

public class HomePagePanel { // note code conventios!
    ...
    public HomePagePanel() {
        ...
        emailModel = new EmailTableModel();
        sorter = new TableRowSorter<EmailTableModel>(emailModel);
        table = new JTable(emailModel);
        ...
    }
}

You don't call emailModel.setData() right before creating the table. It means your table model's data never is initialized and dc still being null at this point. Consequently when getRowCount() method is called during JTable creation it throws the NPE you're facing.

IMHO you should consider remove setData() method and add the items list to the EmailTableModel constructor instead, and better organize your code to avoid this kind of situation:

  1. Do database call and get items list
  2. Create a new table model
  3. Create new JTable

Edit

"Should i just call fireTableDataChanged when I insert or delete an item?"

No, you just need to provide methods to add/delete items to your table model and then notify TableModelListeners about such events. For instance:

public class EmailTableModel extends AbstractTableModel {
    ...
    public void addRow(Item item) {
        int rowIndex = dc.size();
        dc.add(item);
        fireTableRowsInserted(rowIndex, rowIndex);
    }
    ...
    public void deleteRow(Item item) {
        int rowIndex = dc.indexOf(item);
        if(rowIndex > -1) {
            dc.remove(item);
            fireTableRowsDeleted(rowIndex, rowIndex);
        }
    }
    ...
}

See AbstractTableModel API:

dic19
  • 17,821
  • 6
  • 40
  • 69
  • thanks, I did remove setdata and I did as you said. the only problem now is updating the table to show the updated result. I have to exit out of my program and run it again for this to happen. Should i just call fireTableDataChanged when I insert or delete an item? – Kerpal Jul 21 '14 at 15:00
  • or do I have to set the emailModel again each time I update the table? – Kerpal Jul 21 '14 at 15:19