Search code examples
javaswingabstracttablemodel

AbstractTableModel Implementation


I'm trying to view a table in a Jtable when a button is actioned.I hold the table in a two dimensional array and i implemented TableModel class but did not worked.I don't get an error but table doesn't appear.What am i missing?

Here is my code :

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.table.AbstractTableModel;

class MyTableModel extends AbstractTableModel {

/**
 * 
 */
private static final long serialVersionUID = 1L;
private ArrayList<ArrayList<Object>> list = new ArrayList<ArrayList<Object>>();
ResultSet rs;

@Override
public int getColumnCount() {
    try {
        ResultSetMetaData rsmd = rs.getMetaData();
        return rsmd.getColumnCount();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        return -1;
    }
}

@Override
public int getRowCount() {
    try {
        int rowCount = 0;
        while (rs.next())
            rowCount++;
        return rowCount;
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return -1;
    }
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {

    return list.get(columnIndex).get(rowIndex);
}

public void add(ResultSet rs) throws SQLException {
    this.rs = rs;
    list = createListData(rs);
    this.fireTableDataChanged();
}

private ArrayList<ArrayList<Object>> createListData(ResultSet rs)
        throws SQLException {
    ResultSetMetaData rsmd = rs.getMetaData();
    int column = rsmd.getColumnCount();
    ArrayList<ArrayList<Object>> myList = new ArrayList<ArrayList<Object>>();
    ArrayList<Object> temp = new ArrayList<Object>();

    while (rs.next()) {
        temp = new ArrayList<Object>();
        for (int i = 1; i <= column; i++) {
            temp.add(rs.getString(i));
        }
        myList.add(temp);
    }
    System.out.println(myList.get(1).get(2));
    return list;
}
}

And here is action method :

private void Adress_onClick(JButton button) {
    button.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {


            //model.addRegister("ADRESS_ID", "CITY", "TOWN", "DISTRICT");
            DBOperations dbOp = new DBOperations();
            try {
                Connection conn = dbOp.connect();
                ResultSet rs = dbOp.runQuery(conn, "SELECT * FROM ADRESS ORDER BY ADRESS_ID");
                MyTableModel model = new MyTableModel();
                model.add(rs);
                table.setModel(model);

            } catch (ClassNotFoundException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

        }
    });

}

Solution

  • Your code assumes that the JTable will call some of your methods in a specific order. You should not make such assumptions.

    For example, the method getRowCount() assumes that the resultset is before the first row, and goes to the last row to count the rows. If it's called a second time, or if another method doing the same thing is called before, getRowCount() will start returning 0.

    Separate your database access code from your GUI code. When you want to display the data from a database query, execute the query in a method of a separate class, and make this method return a list of objects. Then build an AbstractTableModel implementation using this list of objects. The table model shouldn't deal with result sets.

    Your code is a mixture of using the result set (in getRowCount() and getColumnCount() for example), and using a list built from this result set (in getValueAt(), for example). Build the list before creating the model, then use this list only in your table model implementation. And fix the getValueAt() method: it should be

    return list.get(rowIndex).get(columnIndex);