Link to home
Start Free TrialLog in
Avatar of stanleyhuen
stanleyhuen

asked on

JTable question

I am using a TableModel for a JTable,
the cells are editable, I know I can get the new value using tm.getValueAt(int, int), How can I get the original value of it so that I can compare the two values?
Avatar of tomboshell
tomboshell

I would think that you could store an original copy of the inital parameters just before you display the table, often the values are stored in a vector of a vector or a double array.

Tom
Avatar of CEHJ
You'd have to save the original values before they change in a collection of some sort. Something like:

import javax.swing.table.TableModel;
import java.util.ArrayList;

public class TableModelSaver {

  public static void main(String[] args){
  }

  public static void saveTableModelData(TableModel tm,ArrayList al){
    for(int i= 0;i < tm.getRowCount();i++){
      for(int j= 0;j < tm.getColumnCount();j++){
        al.add(tm.getValueAt(i,j));
      }
    }
  }
}
Hi,

In the JTable you store reference to object
tm.getValueAt(int, int) return you the reference of the object you store before.

You can compare the objects (references) in the JTable if you overwrite the method equals(Object obj) or your object implement the Comparble interface, than you define order.

Best regards
Nir
Avatar of stanleyhuen

ASKER

Thanks all.
How can I get the value of an ArrayList?
get a value in ArrayList?

ArrayList array = ...
...
array.get(0) will get object at position 0 from ArrayList

> How can I get the original value of it so that I can
> compare the two values?

What do you consider the original value?
And what two values do you want to compare, and where are u trying to compare them?
The original value is the value displayed in the beginning,
and then the user can change it, so the new value is the value after change.
After the user changed it, he will press submit button, and I have to store the orignal value and the new value to DB.
Two options:

1. Store the original and current values in your table model.

2. Keep a copy of the table model holding the original state.
any more details of the solutions?
thanks.
1.

public class MyTableModel extends AbstractTableModel
{
   // Original table cell values

   private Object[][] OriginalValues;

   // Current table cell values

   private Object[][] CurrentValues;

   ....

   public Object getValueAt(int row, int col)
   {
     return CurrentValues[row][col];
   }

   public Object getOriginalValueAt(int row, int col)
   {
     return OriginalValues[row][col];
   }

   public void setValueAt(Object value, int row, int col)
   {
     CurrentValues[row][col] = value;
     ...
   }
}

2. Simply clone your table model, or the data used to initialise it, and store the clone for later reference.
 
Hi all,

      I agree all of you said. But if he wants to compare only the last modified cell, having two array will be waste of memory. Instead, the following will be use full.

    public void setValueAt( Object value, int row, int col )
    {
      tmp = ( ( Vector )getDataVector().elementAt( row ) ).get( col ) ;
   
      compare( tmp, value ) ;
     
    }

Hope this usefull!
My understanding of the problem is that the comparison needs to be done with the initial cell value (not the last value) and more importantly it needs to be done when the data is submitted to the database not when setValueAt() is called.
I am trying to use oldRows to store the old values.
But it returns that the old values are the same as the values after change, why?

import java.util.Vector;
import java.util.List;
import java.sql.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.event.TableModelEvent;

public class JDBCAdapter extends AbstractTableModel {
    Connection          connection;
    Statement           statement;
    ResultSet           resultSet;
    String[]            columnNames = {};
    Vector            rows = new Vector();
    Vector    oldRows = new Vector();
    ResultSetMetaData   metaData;

    public JDBCAdapter() {
        try {
            Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
            System.out.println("Opening db connection");

            connection = DriverManager.getConnection("jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=;User=;Password=");
            statement = connection.createStatement();
        }
        catch (ClassNotFoundException ex) {
            System.err.println("Cannot find the database driver classes.");
            System.err.println(ex);
        }
        catch (SQLException ex) {
            System.err.println("Cannot connect to this database.");
            System.err.println(ex);
        }
     }

    public void executeQuery(String query) {
        if (connection == null || statement == null) {
            System.err.println("There is no database to execute the query.");
            return;
        }
        try {
            resultSet = statement.executeQuery(query);
            metaData = resultSet.getMetaData();

            int numberOfColumns =  metaData.getColumnCount();
            columnNames = new String[numberOfColumns];
            // Get the column names and cache them.
            // Then we can close the connection.
            for(int column = 0; column < numberOfColumns; column++) {
                columnNames[column] = metaData.getColumnLabel(column+1);
            }

            // Get all rows.
            rows = new Vector();
            oldRows = new Vector();
            while (resultSet.next()) {
                Vector newRow = new Vector();
                for (int i = 1; i <= getColumnCount(); i++) {
                  newRow.addElement(resultSet.getObject(i));
                }
                rows.addElement(newRow);
                oldRows.addElement(newRow);
            }
            //  close(); Need to copy the metaData, bug in jdbc:odbc driver.
            //fireTableChanged(null); // Tell the listeners a new table has arrived.
            fireTableDataChanged();
        }
        catch (SQLException ex) {
            System.err.println(ex);
        }
    }



    public void close() throws SQLException {
        System.out.println("Closing db connection");
        resultSet.close();
        statement.close();
        connection.close();
    }

    protected void finalize() throws Throwable {
        close();
        super.finalize();
    }

    //////////////////////////////////////////////////////////////////////////
    //
    //             Implementation of the TableModel Interface
    //
    //////////////////////////////////////////////////////////////////////////

    // MetaData

    public String getColumnName(int column) {
        if (columnNames[column] != null) {
            return columnNames[column];
        } else {
            return "";
        }
    }

    public Class getColumnClass(int column) {
        int type;
        try {
            type = metaData.getColumnType(column+1);
        }
        catch (SQLException e) {
            return super.getColumnClass(column);
        }

        switch(type) {
        case Types.CHAR:
        case Types.VARCHAR:
        case Types.LONGVARCHAR:
            return String.class;

        case Types.BIT:
            return Boolean.class;

        case Types.TINYINT:
        case Types.SMALLINT:
        case Types.INTEGER:
            return Integer.class;

        case Types.BIGINT:
            return Long.class;

        case Types.FLOAT:
        case Types.DOUBLE:
            return Double.class;

        case Types.DATE:
            return java.sql.Date.class;

        default:
            return Object.class;
        }
    }

    public boolean isCellEditable(int row, int column) {
       // try {
            //return metaData.isWritable(column+1);
            if (getColumnName(column).equals("No. of Card Required")){
              System.out.println("Equal");
              return false;
            }
            else if (column == 0) {  
           //if (column == 0){
              return false;
            }
            else {
              //return metaData.isWritable(column+1);
              return true;
            }
        //}
        //catch (SQLException e) {
        //    return false;
        //}
    }

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

    // Data methods

    public int getRowCount() {
        return rows.size();

    }

    public Object getValueAt(int aRow, int aColumn) {
        Vector row = (Vector)rows.elementAt(aRow);
        return row.elementAt(aColumn);
    }

    public String dbRepresentation(int column, Object value) {
        int type;

        if (value == null) {
            return "null";
        }

        try {
            type = metaData.getColumnType(column+1);
        }
        catch (SQLException e) {
            return value.toString();
        }

        switch(type) {
        case Types.INTEGER:
        case Types.DOUBLE:
        case Types.FLOAT:
            return value.toString();
        case Types.BIT:
            return ((Boolean)value).booleanValue() ? "1" : "0";
        case Types.DATE:
            return value.toString(); // This will need some conversion.
        default:
            return "\""+value.toString()+"\"";
        }

    }

    public void setValueAt(Object value, int row, int column) {
       
        try {
            String tableName = metaData.getTableName(column+1);
            // Some of the drivers seem buggy, tableName should not be null.
            if (tableName == null) {
                System.out.println("Table name returned null.");
            }
            String columnName = getColumnName(column);
            String query =
                "update "+tableName+
                " set "+columnName+" = "+dbRepresentation(column, value)+
                " where ";
            // We don't have a model of the schema so we don't know the
            // primary keys or which columns to lock on. To demonstrate
            // that editing is possible, we'll just lock on everything.
            for(int col = 0; col<getColumnCount(); col++) {
                String colName = getColumnName(col);
                if (colName.equals("")) {
                    continue;
                }
                if (col != 0) {
                    query = query + " and ";
                }
                query = query + colName +" = "+
                    dbRepresentation(col, getValueAt(row, col));
            }
            //System.out.println(query);
            //System.out.println("Not sending update to database");
            // statement.executeQuery(query);
        }
        catch (SQLException e) {
            //     e.printStackTrace();
            System.err.println("Update failed");
        }
        Vector dataRow = (Vector)rows.elementAt(row);
        dataRow.setElementAt(value, column);

    }
}
ASKER CERTIFIED SOLUTION
Avatar of Mick Barry
Mick Barry
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial