Edit/Update MySQL JTable

Hello experts,
I have a JTable that displays a MySQL database.
The JTable is constructed from a table model that uses a ResultSet.
I'm trying to make the table editable and reflect the changes in the MySQL database with a TableModelListener.
I'm able to "edit" the cells but nothing gets saved on the JTable.
I construct my JTable as follows:

ResultSet rs = stat.executeQuery("SELECT * FROM main");
ResultSetTableModel model = new ResultSetTableModel(rs);  
table = new JTable(model);
table.setColumnSelectionAllowed(true);
table.setRowSelectionAllowed(true);
table.getModel().addTableModelListener(new MyTableModelListener(table));
scrollPane = new JScrollPane(table);
pane.add(scrollPane, BorderLayout.CENTER);
validate();

And here's my table model and the listener:

/**
This class is the superclass for the  result set table model.
It stores the result set and its metadata.
*/
class ResultSetTableModel extends AbstractTableModel
{  
/**
   Constructs the table model.
   @param aResultSet the result set to display.
*/
public ResultSetTableModel(ResultSet aResultSet)
{  
   rs = aResultSet;
   try
   {  
      rsmd = rs.getMetaData();
   }
   catch (SQLException e)
   {  
      e.printStackTrace();
   }
}


public String getColumnName(int c)
{  
   try
   {  
      return rsmd.getColumnName(c + 1);
   }
   catch (SQLException e)
   {  
      e.printStackTrace();
      return "";
   }
}

public boolean isCellEditable(int row, int col){
      return true;
}

public int getColumnCount()
{  
   try
   {  
      return rsmd.getColumnCount();
   }
   catch (SQLException e)
   {  
      e.printStackTrace();
      return 0;
   }
}

public Object getValueAt(int r, int c)
{  
   try
   {  
      rs.absolute(r + 1);
      return rs.getObject(c + 1);
   }
   catch(SQLException e)
   {  
      e.printStackTrace();
      return null;
   }
}

public int getRowCount()
{  
   try
   {  
      rs.last();
      return rs.getRow();
   }
   catch(SQLException e)
   {  
      e.printStackTrace();
      return 0;
   }
}

private ResultSetMetaData rsmd;
}

//Table Listener
public class MyTableModelListener implements TableModelListener {
    JTable table;

    // It is necessary to keep the table since it is not possible
    // to determine the table from the event's source
    MyTableModelListener(JTable table) {
        this.table = table;
    }

    public void tableChanged(TableModelEvent e) {
        int firstRow = e.getFirstRow();
        int lastRow = e.getLastRow();
        int mColIndex = e.getColumn();

        switch (e.getType()) {
          case TableModelEvent.INSERT:
            // The inserted rows are in the range [firstRow, lastRow]
            for (int r=firstRow; r<=lastRow; r++) {
                // Row r was inserted
            }
            break;
          case TableModelEvent.UPDATE:
            if (firstRow == TableModelEvent.HEADER_ROW) {
                if (mColIndex == TableModelEvent.ALL_COLUMNS) {
                    // A column was added
                } else {
                    // Column mColIndex in header changed
                }
            } else {
                // The rows in the range [firstRow, lastRow] changed
                for (int r=firstRow; r<=lastRow; r++) {
                    // Row r was changed
                    if (mColIndex == TableModelEvent.ALL_COLUMNS) {
                        // All columns in the range of rows have changed
                    } else {
                        // Column mColIndex changed
                    }
                }
            }
            break;
          case TableModelEvent.DELETE:
            // The rows in the range [firstRow, lastRow] changed
            for (int r=firstRow; r<=lastRow; r++) {
                // Row r was deleted
            }
            break;
        }
    }
}

********************************************************************

Am I on the right track? Is my table model stopping me from allowing changes in the JTable?
My goal is to make the JTable editable and be able to save the changes in the GUI
and in the MySQL DB. Please help.

Thanks in advance,
Wojciech.

LVL 2
wdunskiAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

hoomanvCommented:
you have to derive setValueAt(Object aValue, int rowIndex, int columnIndex) in your TableModel too. only there you should reflect the results.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
wdunskiAuthor Commented:
OK, makes sense.
I made the ResultSet updatable and added the following code to the table model:
public void setValueAt(Object aValue, int rowIndex, int columnIndex){
      try
         {  
            rs.absolute(rowIndex + 1);
            rs.updateString(columnIndex+1, (String)aValue);
         }
         catch(SQLException e)
         {  
            e.printStackTrace();
         }
}

Still doesn't work... Any suggestions?

Thanks
0
wdunskiAuthor Commented:
Nevermind.. I'm missing the rs.updateRow() method call at the end. My fault.

For anyone interested I'm going to post the working code for displaying a MySQL table in an updatable JTable : )

You would create the table as follows:

           conn = getConnection();
           stat = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                             ResultSet.CONCUR_UPDATABLE);
           ResultSet rs = stat.executeQuery("SELECT * FROM main");
           ResultSetTableModel model = new ResultSetTableModel(rs);            
           table = new JTable(model);
           table.setColumnSelectionAllowed(true);
           table.setRowSelectionAllowed(true);
           scrollPane = new JScrollPane(table);
           pane.add(scrollPane, BorderLayout.CENTER);
           validate();

And here is the working table model I use:

/**
This class is the superclass for the  result set table model.
It stores the result set and its metadata.
*/
class ResultSetTableModel extends AbstractTableModel
{  
/**
   Constructs the table model.
   @param aResultSet the result set to display.
*/
public ResultSetTableModel(ResultSet aResultSet)
{  
   rs = aResultSet;
   
   try
   {  
      rsmd = rs.getMetaData();
   }
   catch (SQLException e)
   {  
      e.printStackTrace();
   }
}


public String getColumnName(int c)
{  
   try
   {  
      return rsmd.getColumnName(c + 1);
   }
   catch (SQLException e)
   {  
      e.printStackTrace();
      return "";
   }
}

public boolean isCellEditable(int row, int col){
      return true;
}

public int getColumnCount()
{  
   try
   {  
      return rsmd.getColumnCount();
   }
   catch (SQLException e)
   {  
      e.printStackTrace();
      return 0;
   }
}

public Object getValueAt(int r, int c)
{  
   try
   {  
      rs.absolute(r + 1);
      return rs.getObject(c + 1);
   }
   catch(SQLException e)
   {  
      e.printStackTrace();
      return null;
   }
}

public void setValueAt(Object aValue, int rowIndex, int columnIndex){
      try
         {  
            rs.absolute(rowIndex + 1);
            System.out.println("I got here... row: "+ rowIndex + ", " + columnIndex);
            rs.updateString(columnIndex+1, (String)aValue);
            rs.updateRow();
         }
         catch(SQLException e)
         {  
            e.printStackTrace();
         }
}

public int getRowCount()
{  
   try
   {  
      rs.last();
      return rs.getRow();
   }
   catch(SQLException e)
   {  
      e.printStackTrace();
      return 0;
   }
}

private ResultSetMetaData rsmd;
}
0
wdunskiAuthor Commented:
Exclude the  System.out.println("I got here... row: "+ rowIndex + ", " + columnIndex);
from the setValueAt method..
No need for that :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.