javatablemodel

How to use Class construct a TableModel in Java


I want use a class to construct a TableModel. I know how to use method return a TableModel. But I wonder how to use class to construct a TableModel. So far I failed. The dataset did not get all the value through data. So dataset is null. Similarly columnNamesCount also is null.

Exception in thread "main" java.lang.NullPointerException: Cannot read the array length because "this.columnNamesCount" is null
    at MyTableModel.getColumnCount(castToModel.java:57)
    at java.desktop/javax.swing.JTable.createDefaultColumnsFromModel(JTable.java:1297)
    at java.desktop/javax.swing.JTable.tableChanged(JTable.java:4391)
    at java.desktop/javax.swing.JTable.setModel(JTable.java:3693)
    at java.desktop/javax.swing.JTable.<init>(JTable.java:647)
    at java.desktop/javax.swing.JTable.<init>(JTable.java:588)
    at castToModel.<init>(castToModel.java:14)
    at Main.main(Main.java:54)

After the while loop the data is stored all the value.

class MyTableModel extends AbstractTableModel {
    public Object[][] dataset;
    public int columnCount;
    public String[] columnNames;
    public String[] columnNamesCount;
    String query = "select * from emp";
    void MyTableModel() throws SQLException {
        Statement stmt = Main.connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
        //PreparedStatement stmt = Main.connection.prepareStatement(query);
        ResultSet resultSet = stmt.executeQuery(query);
        ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
        columnCount = resultSetMetaData.getColumnCount();
        columnNames = new String[columnCount];
        for (int ii = 1; ii <= columnCount; ii++) {
            columnNames[ii-1] = resultSetMetaData.getColumnName(ii);
        }
        resultSet.last();
        int rowCount = resultSet.getRow();
        resultSet.beforeFirst();
        Object[][] data = new Object[rowCount][columnCount];
        int currentRow = 0;
        while (resultSet.next()) {
            for (int currentColumn = 1; currentColumn <= columnCount; currentColumn++) {
                data[currentRow][currentColumn - 1] = resultSet.getObject(currentColumn);
            }
            currentRow++;
        }
        dataset = data;
        columnNamesCount=columnNames;
    }

    @Override
    public int getRowCount() {return dataset.length;}
    @Override
    public int getColumnCount() {return columnNamesCount.length;}
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {return dataset[rowIndex][columnIndex];}
    public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); }
    public boolean isCellEditable(int row, int col) {return true;}
}

Edit1: My casttoModel code:

public class castToModel {
    public castToModel(){
        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        TableModel model = new MyTableModel();
        JTable table = new JTable(model);
        frame.add(table);
        frame.pack();
        frame.setVisible(true);}
}

Solution

  • From the code in your question:

    void MyTableModel() throws SQLException {
    

    This is not a constructor.

    This is a constructor:

    public MyTableModel() throws SQLException {
    

    The java compiler treats void MyTableModel() as a regular method that does not return a value and has package access. This means that class MyTableModel does not declare a constructor. In that case, the compiler will add an empty constructor like below:

    public MyTableModel() {
        super();
    }
    

    You need to remove the word void and replace it with the appropriate access modifier.

    Also, in the code in your question, you never initialize columnNamesCount. Hence it is null and hence method getColumnCount() throws NullPointerException. I think method getColumnCount() should be as follows:

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }