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?
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?
You'd have to save the original values before they change in a collection of some sort. Something like:
import javax.swing.table.TableMod el;
import java.util.ArrayList;
public class TableModelSaver {
public static void main(String[] args){
}
public static void saveTableModelData(TableMo del 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)) ;
}
}
}
}
import javax.swing.table.TableMod
import java.util.ArrayList;
public class TableModelSaver {
public static void main(String[] args){
}
public static void saveTableModelData(TableMo
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
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
ASKER
Thanks all.
How can I get the value of an ArrayList?
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
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?
> 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?
ASKER
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.
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.
1. Store the original and current values in your table model.
2. Keep a copy of the table model holding the original state.
ASKER
any more details of the solutions?
thanks.
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.
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!
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
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.
ASKER
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.Abstract TableModel ;
import javax.swing.event.TableMod elEvent;
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.microso ft.jdbc.sq lserver.SQ LServerDri ver");
System.out.println("Openin g db connection");
connection = DriverManager.getConnectio n("jdbc:mi crosoft:sq lserver:// 127.0.0.1: 1433;Datab aseName=;U ser=;Passw ord=");
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(que ry);
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(co lumn+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(resultSe t.getObjec t(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("Closin g 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(col umn+1);
}
catch (SQLException e) {
return super.getColumnClass(colum n);
}
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).equ als("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(aRo w);
return row.elementAt(aColumn);
}
public String dbRepresentation(int column, Object value) {
int type;
if (value == null) {
return "null";
}
try {
type = metaData.getColumnType(col umn+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).booleanVa lue() ? "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(colu mn+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(que ry);
}
catch (SQLException e) {
// e.printStackTrace();
System.err.println("Update failed");
}
Vector dataRow = (Vector)rows.elementAt(row );
dataRow.setElementAt(value , column);
}
}
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.Abstract
import javax.swing.event.TableMod
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.microso
System.out.println("Openin
connection = DriverManager.getConnectio
statement = connection.createStatement
}
catch (ClassNotFoundException ex) {
System.err.println("Cannot
System.err.println(ex);
}
catch (SQLException ex) {
System.err.println("Cannot
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(que
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(co
}
// 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(resultSe
}
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("Closin
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(col
}
catch (SQLException e) {
return super.getColumnClass(colum
}
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
if (getColumnName(column).equ
System.out.println("Equal"
return false;
}
else if (column == 0) {
//if (column == 0){
return false;
}
else {
//return metaData.isWritable(column
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(aRo
return row.elementAt(aColumn);
}
public String dbRepresentation(int column, Object value) {
int type;
if (value == null) {
return "null";
}
try {
type = metaData.getColumnType(col
}
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).booleanVa
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(colu
// 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,
" 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(que
}
catch (SQLException e) {
// e.printStackTrace();
System.err.println("Update
}
Vector dataRow = (Vector)rows.elementAt(row
dataRow.setElementAt(value
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Tom