1

I'm following this example code to create my own tableModel class to display data from a db using cachedRowSet, and use rowSetEvent to refresh the table when insert a row and delete a row to the cachedRowSet. https://github.com/abissell/jdbctutorial/blob/master/src/com/oracle/tutorial/jdbc/CoffeesTableModel.java

public void rowChanged(RowSetEvent event) {
        try {
            tm.rs.moveToCurrentRow();
            tm = new MyTableModel(tm.rs); // to get right row nums
            table.setModel(tm);
        } catch (SQLException er) {
            er.printStackTrace();
        }
    }

public class MyTableModel extends AbstractTableModel {

CachedRowSet rs;
ResultSetMetaData meta;
int cols, rows;

public MyTableModel(CachedRowSet r) {
    rs = r;
    try {
        meta = rs.getMetaData();
        cols = meta.getColumnCount();
        rs.beforeFirst();
        rows = 0;
        while (rs.next()) {
            rows++;
        }
        rs.beforeFirst();
    } catch(SQLException e) {
        e.printStackTrace();
    }          
}

public void insert(String[] info) {
    try {
        rs.moveToInsertRow();
        for(int i = 0;i < cols;i++) {
            rs.updateString(i+1, info[i]);
        }
        rs.insertRow();
        rs.moveToCurrentRow();
    } catch(SQLException e) {
        e.printStackTrace();
    } 
}

public void delete(int id) {
    try {
        rs.beforeFirst();
        while(rs.next()) {
            if(Integer.parseInt(rs.getString(1))==id) {
                rs.deleteRow();
                break;
            }
        }
    } catch (SQLException ex) {
        ex.printStackTrace();
    }
}

@Override
public int getRowCount() {
    return rows;
}

@Override
public int getColumnCount() {
    return cols;
}

@Override
public String getColumnName(int col) {
    try {
        return meta.getColumnLabel(col + 1);
    } catch (SQLException e) {
        return e.toString();
    }
}

@Override
public Class<?> getColumnClass(int columnIndex) {
    return String.class;
}

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
    return false;
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    try {
        if (!rs.absolute(rowIndex + 1)) {
            return null;
        }
        rs.absolute(rowIndex + 1);
        Object o = rs.getObject(columnIndex + 1);
        if (o == null) {
            return null;
        } else {
            return o.toString();
        }
    } catch (SQLException e) {
        e.printStackTrace();
        return e.toString();
    }
}

@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
}

@Override
public void addTableModelListener(TableModelListener l) {
}

@Override
public void removeTableModelListener(TableModelListener l) {
}

}

con = DriverManager.getConnection(url);
        st = con.prepareStatement("SELECT id,name,sex,age,cell FROM PATIENTS");
        rs = st.executeQuery();
        crs = new CachedRowSetImpl();
        crs.setType(ResultSet.TYPE_SCROLL_SENSITIVE);
        crs.setConcurrency(ResultSet.CONCUR_UPDATABLE);
        crs.populate(rs);

tm is the tableModel. The table will refresh immediately after a row deleted from the cachedRowSet, but when i insert a new row into cachedRowSet, then the table can't show the newly added row immediately. And i checked the rowChanged() been called and the row inserted inside the db.
Even tried to refetch the table data each time or repaint() still not working. I couldn't figure out why.
Maybe cause swing process racing then it can't refresh immediately? I just opened another JFrame to fill out the data and then insert.

Also, what if i use the resultSet directly inside the model? Will the table automatically updated when you insert a row in the db if i didn't close the connection. Or it's just used to get the initial data and you have to run query again to refresh.

Thank you
=================update==================
I tried to change the table model to use ArrayList to store and update db results, then the insert will be update the table immediately. Maybe cause cachedRowSet update slower?
Confused, don't know why.

dsfdf
  • 106
  • 2
  • 7
  • Consider to post a [SSCCE](http://sscce.org) for better help soon – nachokk Jan 04 '14 at 01:33
  • Actually a sscce , is something that you only have to copy paste (it means only one class with one main) to see your problem, if you make a good question you'll get better answer :D, and for sure you earn reputation cause your question is good! – nachokk Jan 04 '14 at 01:44
  • @nachokk yeah, i pasted the main code about the table – dsfdf Jan 04 '14 at 01:53
  • 2
    A SSCCE is a very simple *executable* program that demonstrates the problem that you are facing. That way we can take the SSCCE, execute it, diagnose the problem and test solutions. This is very convenient for us which makes it convenient for you. Without an SSCCE you either have to hope for a user that can find your error just by looking at your code, or we have to build our own SSCCE but that is asking for a lot more of our time, thus you'll get less help. More importantly if you make an SSCCE you'll get to the core of your problem, and you will probably solve it. – DSquare Jan 04 '14 at 02:20
  • To go into your problem, the model is not something you should need to change as your content changes. The model is the responsible for handling the changes and accesing the data. Then the JTable displays the data provided by the model. Try to start over and do what you are trying to do with a simple little table independent of the rest of your program. Look at the tutorials and examples to know how to make changes in the data and properly notify the table of them. In the AbstractTableModel there are even `fireTableXXX()` to notifiy the table. – DSquare Jan 04 '14 at 02:31
  • 2
    For [example](http://stackoverflow.com/a/8260663/230513) – trashgod Jan 04 '14 at 05:59
  • @trashgod thank you. So i guess it does have something to do with the thread racing conditions? But why the delete could refresh immediately rather than the insert by using rowSetEvent(which i checked it detects the insert row change event) – dsfdf Jan 04 '14 at 13:59
  • Hard to say without an [sscce](http://sscce.org/); `EventQueue` ensures execution in the order posted, but you have to manage posting order. – trashgod Jan 04 '14 at 18:43

0 Answers0