Foros del Web » Programación para mayores de 30 ;) » Java »

JTable y Eventos

Estas en el tema de JTable y Eventos en el foro de Java en Foros del Web. hola ! Me gustaría capturar el evento de una tabla cuando algún elemento de ella es modificado. Lo q he hecho es crear una tabla ...
  #1 (permalink)  
Antiguo 07/07/2005, 02:19
 
Fecha de Ingreso: mayo-2004
Mensajes: 85
Antigüedad: 19 años, 11 meses
Puntos: 1
JTable y Eventos

hola !

Me gustaría capturar el evento de una tabla cuando algún elemento de ella es modificado. Lo q he hecho es crear una tabla a partir de recoger un resulset de la base de datos y hacer de el dos vectores, 1 para el nombre de columnas y otro de datos de las filas.

JTable table = new JTable((Vector)Lista.get(0),(Vector)Lista.get(1));

De esta manera se crea perfectamente la tabla con sus datos, pero creándolo así como puedo capturar sus eventos ?. En concreto me gustaría capturar el evento cuando se modifica la tabla y saber q fila es y q datos tiene para modificarlo a base de datos

salu2 y gracias.
  #2 (permalink)  
Antiguo 08/07/2005, 05:35
 
Fecha de Ingreso: mayo-2004
Mensajes: 85
Antigüedad: 19 años, 11 meses
Puntos: 1
Me contesto yo mismo por si a alguien le puede servir de ayuda.
Al crear un JTable pasandole en su constructor los datos, se crea rapidamente una tabla, pero limita mucho las posibilidades a la hora de capturar eventos. Lo mejor para ello, es crear una clase q extienda de AbstractTableModel en la q redefiniremos los metodos tales como "setValueAt" en el cual jugaremos con los datos de la fila seleccionada y con el dato de la columna de esa fila modificada.
Este es un ejemplo de un clase q extiende de la clase AbstractTableModel q una vez construida, solo tendremos q hacer: Jtable tabla = new JTable(new JDBCAdapter()); para construir la tabla.
La clase JDBCAdapter va a la base de datos(SQL Server) a recoger los datos,pero tb se lo podemos pasar construyendo un Object[][], o con 2 vectores (1 con el nombre de columnas y otro con los objetos de cada fila ).

import java.util.Vector;
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();
ResultSetMetaData metaData;

public JDBCAdapter(String url, String driverName,
String user, String passwd) {
try {
Class.forName(driverName);
System.out.println("Opening db connection");

connection = DriverManager.getConnection(url, user, passwd);
statement = connection.createStatement();

executeQuery();
}
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();
while (resultSet.next()) {
Vector newRow = new Vector();
for (int i = 1; i <= getColumnCount(); i++) {
newRow.addElement(resultSet.getObject(i));
}
rows.addElement(newRow);
}
// close(); Need to copy the metaData, bug in jdbc:odbc driver.
fireTableChanged(null); // Tell the listeners a new table has arrived.
}
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);
}
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 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);

}
}
  #3 (permalink)  
Antiguo 14/08/2007, 11:41
 
Fecha de Ingreso: junio-2007
Mensajes: 2
Antigüedad: 16 años, 10 meses
Puntos: 0
Re: JTable y Eventos

hola ferblaca , esta clase es justo lo q estaba buscando .. pero tengo un problema al construir la tabla con : Jtable1 tabla = new JTable1(new JDBCAdapter());
al compilar me sale el siguiente error
symbol : class jTable1
location: class clientes.JFrame_clientes
jTable1 tabla = new JTable1(jdbca);

que estoy haciendo mal ?
  #4 (permalink)  
Antiguo 05/10/2007, 15:52
 
Fecha de Ingreso: octubre-2007
Mensajes: 1
Antigüedad: 16 años, 6 meses
Puntos: 0
Re: JTable y Eventos

pues deberia ser

JTable tabla = new JTable(new JDBCAdapter()));
  #5 (permalink)  
Antiguo 31/10/2007, 13:59
 
Fecha de Ingreso: octubre-2007
Mensajes: 1
Antigüedad: 16 años, 5 meses
Puntos: 0
Re: JTable y Eventos

Cita:
Iniciado por ferblaca Ver Mensaje
Me contesto yo mismo por si a alguien le puede servir de ayuda.
Al crear un JTable pasandole en su constructor los datos, se crea rapidamente una tabla, pero limita mucho las posibilidades a la hora de capturar eventos. Lo mejor para ello, es crear una clase q extienda de AbstractTableModel en la q redefiniremos los metodos tales como "setValueAt" en el cual jugaremos con los datos de la fila seleccionada y con el dato de la columna de esa fila modificada.
Este es un ejemplo de un clase q extiende de la clase AbstractTableModel q una vez construida, solo tendremos q hacer: Jtable tabla = new JTable(new JDBCAdapter()); para construir la tabla.
La clase JDBCAdapter va a la base de datos(SQL Server) a recoger los datos,pero tb se lo podemos pasar construyendo un Object[][], o con 2 vectores (1 con el nombre de columnas y otro con los objetos de cada fila ).

import java.util.Vector;
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();
ResultSetMetaData metaData;

public JDBCAdapter(String url, String driverName,
String user, String passwd) {
try {
Class.forName(driverName);
System.out.println("Opening db connection");

connection = DriverManager.getConnection(url, user, passwd);
statement = connection.createStatement();

executeQuery();
}
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();
while (resultSet.next()) {
Vector newRow = new Vector();
for (int i = 1; i <= getColumnCount(); i++) {
newRow.addElement(resultSet.getObject(i));
}
rows.addElement(newRow);
}
// close(); Need to copy the metaData, bug in jdbc:odbc driver.
fireTableChanged(null); // Tell the listeners a new table has arrived.
}
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);
}
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 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);

}
}
me parecio interesante tu articulo, yo hice una clase bastante parecida excepto por la devolcion de tipo de dato de la columnoa....pero aun no veo claro lo de la captura de eventos...como tu dices es dificil que al insertar tu objeto tabla en una ventana puedas capturar por ejemplo un evento de mouseClicked...por ejemplo yo cree una clase panel Tabla (Jtable dentro de un JPanel) que recibe un ResultSet con una clasecita insertada que deriva de AbstractTableModel, cuando inserto mi PanelTabla en un frame como podria por ejemplo para capturar el evento del usuario haciendo doble click en una fila...te agradeceria una sugerencia...


gracias
Ing. de Sistemas Carlos Puente
Lima - Peru
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 02:00.