Un JTable es un componente visual de java que nos permite dibujar una tabla, de forma que en cada fila/columna de la tabla podamos poner el dato que queramos; un nombre, un apellido, una edad, un número, etc, etc.
Como muchos componentes de java, se ha seguido una separación modelo-vista .La vista es el componente visual que vemos en pantalla, el modelo es una clase que contiene los datos que luego se verán en pantalla. El modelo de datos únicamente contiene los datos, nosabe nada de quién va a visulizar los datos ni como.
La forma más rápida y sencilla
Aparte de usar otros constructores que hay en JTable, una de las mejores formas de manejar JTable teniendo toda su funcionalidad, consiste en instanciar como modelo de datos un DefaultTableModel y luego un JTable , pasándole el modelo en el constructor. El código quedaría:
Como muchos componentes de java, se ha seguido una separación modelo-vista .La vista es el componente visual que vemos en pantalla, el modelo es una clase que contiene los datos que luego se verán en pantalla. El modelo de datos únicamente contiene los datos, nosabe nada de quién va a visulizar los datos ni como.
La forma más rápida y sencilla
Aparte de usar otros constructores que hay en JTable, una de las mejores formas de manejar JTable teniendo toda su funcionalidad, consiste en instanciar como modelo de datos un DefaultTableModel y luego un JTable , pasándole el modelo en el constructor. El código quedaría:
DefaultTableModel modelo = new DefaultTableModel();J
Table tabla = new JTable (modelo);
A partir de ahora todo se maneja con el modelo. En cuanto añadamos, borremos o cambiemos datos del modelo, el JTable se enterará y actualizará automáticamente. El DefaultTableModel tiene todos los métodos necesarios para modificar datos en su interior, añadir filas o columnas y darle a cada columna el nombre que queramos
Vamos a hacer nuestro propio modelo de datos
El DefaultTableModel es un modelo genérico y puede no ser suficiente (o al menos, incómodo de usar) para nuestros propósitos.
Es bastante habitual el querer manejar la tabla como si fuera una lista, de forma que cada filacorresponde a una clase de datos y las columnas son los atributos de esaclase. Por ejemplo, queremos una lista de Persona y cada persona tiene unnombre, un apellido y una edad. Queremos pintar este lista en una tabla,de forma que tiene tres columnas (nombre, apellido y edad) y tantas filascomo Personas haya en la lista. A mi me gustaría tener un modelo alque le diga
modelo.anhadePersona (persona);
y no un
A partir de ahora todo se maneja con el modelo. En cuanto añadamos, borremos o cambiemos datos del modelo, el JTable se enterará y actualizará automáticamente. El DefaultTableModel tiene todos los métodos necesarios para modificar datos en su interior, añadir filas o columnas y darle a cada columna el nombre que queramos
Vamos a hacer nuestro propio modelo de datos
El DefaultTableModel es un modelo genérico y puede no ser suficiente (o al menos, incómodo de usar) para nuestros propósitos.
Es bastante habitual el querer manejar la tabla como si fuera una lista, de forma que cada filacorresponde a una clase de datos y las columnas son los atributos de esaclase. Por ejemplo, queremos una lista de Persona y cada persona tiene unnombre, un apellido y una edad. Queremos pintar este lista en una tabla,de forma que tiene tres columnas (nombre, apellido y edad) y tantas filascomo Personas haya en la lista. A mi me gustaría tener un modelo alque le diga
modelo.anhadePersona (persona);
y no un
modelo.setValueAt (fila, columna, persona.nombre);columna++;modelo.setValueAt (fila, columna, persona.apellido);columna++;modelo.setValueAt (fila, columna, edad);
Por ello, a veces esmás cómodo implementar nuestros propios modelos de tabla. Lacosa es fácil, únicamente debemos implementar la interfaceTableModel y luego poner además todos losmétodos que queramos, como el anhadePersona() o el damePersona() mencionados antes.
Una clase que implemente un TableModel debe redefinir los siguientes métodos:
Una clase que implemente un TableModel debe redefinir los siguientes métodos:
class MiModelo implements TableModel
{
public void addTableModelListener (TableModelListener l) {...}
public Class getColumnClass (int columIndex) {...}
public int getColumnCount() {...}
public String getColumnName (int columnIndex) {...}
public int getRowCount() {...}
public Object getValueAt (int rowIndex, int columnIndex) {...}
public boolean isCellEditable (int rowIndex, int columnIndex) {...}
public void removeTableModelListener (TableModelListener l) {...}
public void setValueAt (Object aValue, int rowIndex, int columnIndex)
}
Hay básicamente tres tipos de métodos:
Métodos para manejo de suscriptores al modelo. Un suscriptor es cualquier clase que quiera enterarse de cambios en los datos del modelo. El JTable es un ejemplo claro. El JTable se suscribe a cambios de datos en el modelo y de esta forma, en cuanto cambiemos datos en el modelo, el JTable se entera y se repinta automáticamente la pantalla. En este grupo están los métodos addTableModelListener() y removeTableModelListener()
Métodos para menejo de datos. Permiten obtener y cambiar datos dentro de la tabla. Son los métodos getValueAt() y setValueAt().
El resto son métodos para obtener información de la tabla en sí misma, como número de filas, número de columnas, si una fila-columna es o no editable, nombre de la columna, etc.
Métodos para los suscriptores
Para implementar los métodos de los suscriptores necesitamos que nuestro modelo tenga una lista de suscriptores y únicamente hay que añadir o borrar suscriptores de esa lista. El código puede ser tan simple como esto:
Hay básicamente tres tipos de métodos:
Métodos para manejo de suscriptores al modelo. Un suscriptor es cualquier clase que quiera enterarse de cambios en los datos del modelo. El JTable es un ejemplo claro. El JTable se suscribe a cambios de datos en el modelo y de esta forma, en cuanto cambiemos datos en el modelo, el JTable se entera y se repinta automáticamente la pantalla. En este grupo están los métodos addTableModelListener() y removeTableModelListener()
Métodos para menejo de datos. Permiten obtener y cambiar datos dentro de la tabla. Son los métodos getValueAt() y setValueAt().
El resto son métodos para obtener información de la tabla en sí misma, como número de filas, número de columnas, si una fila-columna es o no editable, nombre de la columna, etc.
Métodos para los suscriptores
Para implementar los métodos de los suscriptores necesitamos que nuestro modelo tenga una lista de suscriptores y únicamente hay que añadir o borrar suscriptores de esa lista. El código puede ser tan simple como esto:
class MiModelo implements TableModel
{
public void addTableModelListener (TableModelListenerl) {
suscriptores.add (l);
}
public void removeTableModelListener (TableModelListener l) {
suscriptores.remove(l);<> }
private LinkedList suscriptores = new LinkedList();
}
Si en vez de implementar TableModel, heredamos de AbstractTableModel , ya tenemos esto implementado, además de otra serie de métodos que nos serán útiles más adelante.
Metodos para manejo de los datos
Para el manejode datos, sólo tenemos dos métodos. El que pone un dato enuna fila,columna y el que lo obtiene. Si seguimos con la idea de hacer unalista de personas, el código puede quedar como esto:
class MiModelo implements TableModel
{
public void setValueAt (Object dato, int fila, int columna) {
// Obtenemos la persona de la fila indicada
Persona aux = (Persona)datos.get (fila);
switch (columna) {
// Nos pasan el nombre.
case 0:
aux.nombre = (String)dato;
break;
// Nos pasan el apellido.
case 1:
aux.apellido = (String)dato;
break;
// Nos pasan la edad.
case 2:
aux.edad = ((Integer)dato).intValue();
break;
}
// Aquí hay que avisar a los sucriptores del cambio.
// Ver unpoco más abajo cómo.
}
public Object getValueAt (int fila, int columna) {
// Obtenemos la persona de la fila indicada
Persona aux = (Persona)datos.get (fila);
switch (columna) {
// Nos piden el nombre
case 0:
return aux.nombre;
break;
// Nos piden el apellido
case 1:
return aux.apellido;
break;
// Nos piden la edad.
case 2:
return new Integer (aux.edad);
break;
}
return null;
}
private LinkedList datos = new LinkedList();
}
Simplemente hemos declarado una lista de personas como atributo privado de la clase y hecho los switch necesarios para poner u obtener el campo concreto de Persona para la columna indicada. El Object recibido y devuelto para cada compo puede ser lo que nosotros queramos,pero para una fila,columna dada, debe ser del mismo tipo en ambos métodos. Dicho de otra forma, si devolvemos un Integer,nos pasarán un Integer. Además, debeser un Object (una instancia de una clase), por eso tratamos la edad como Integer y no como int.
El método setValueAt() tiene una pequeña pega. Cualquier modificación que hagamos en los datos, debe ser notificada a los suscriptores. Debemos crear un TableModelEvent , rellenarlo con los datos adecuados y avisar a los suscriptores.
El TableModelEvent se puede rellenar con el constructor. Parael caso de setValueAt() debemos ponerdespués de cambiar el dato (del switch) algo como esto
TableModelEvent evento = new TableModelEvent (this, fila, fila, columna);
Simplemente hemos declarado una lista de personas como atributo privado de la clase y hecho los switch necesarios para poner u obtener el campo concreto de Persona para la columna indicada. El Object recibido y devuelto para cada compo puede ser lo que nosotros queramos,pero para una fila,columna dada, debe ser del mismo tipo en ambos métodos. Dicho de otra forma, si devolvemos un Integer,nos pasarán un Integer. Además, debeser un Object (una instancia de una clase), por eso tratamos la edad como Integer y no como int.
El método setValueAt() tiene una pequeña pega. Cualquier modificación que hagamos en los datos, debe ser notificada a los suscriptores. Debemos crear un TableModelEvent , rellenarlo con los datos adecuados y avisar a los suscriptores.
El TableModelEvent se puede rellenar con el constructor. Parael caso de setValueAt() debemos ponerdespués de cambiar el dato (del switch) algo como esto
TableModelEvent evento = new TableModelEvent (this, fila, fila, columna);
Se le pasan como parámetros:
El modelo de datos que ha cambiado. En nuestro caso this.
La fila inicial que ha cambiado.
La fila final que ha cambiado, en nuestro caso la misma que la inicial, puesto que sólo ha cambiado una.
La columna que ha cambiado.
Una vez creado el evento, hay que pasárselo a los suscriptores a través de su método tableChanged()
int i;for (i=0; i
((TableModelListener)suscriptores.get(i)).tableChanged(evento);
Los demás métodos son de información general para la tabla y no tienen demasiado truco.
Devolver la clase de cada columna. Devolveremos String.class para el nombre y el apellido e Integer.class para la edad. Este método lo utiliza el JTable para saber como presentar o editar cada dato. Si el JTable no conoce la clase que le devolvemos (no es de las normales de java), lo más posible es que trate el dato como un Object yllame a su método toString() para pintarlo.
Devolver el número de columnas. Para nuestro ejemplo de Persona, que tiene tres campos, devolveremos un 3.
Devolver el nombre de las columnas. En nuestro ejemplo devolveremos "Nombre", "Apellido" y "Edad".
Devolver cuántas filas hay (el número de elementos en nuestra lista de personas)
Devolver si una celda en fila,columna es o no editable, es decir, si el usuario puede escribir en ella y modificar los datos del modelo. En nuestro ejemplo devolveremos true .
Otros métodos
Puesto que para eso hemos hecho este modelo, vamos a añadirle un par de métodos que nos son útiles para el ejemplo y nos facilitan el añadir y borrar personas:
public void anhadePersona (Persona nuevaPersona) {
// Añade la persona al modelo
datos.add (nuevaPersona);
// Avisa a los suscriptores creando un TableModelEvent...
TableModelEvent evento; evento = new TableModelEvent (
this, this.getRowCount()-1, this.getRowCount()-1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT);
// ... y avisando a los suscriptores
int i;
for (i=0; i
Las palabras que se encuentran en este tipo de letra son las cosas que el programador puede determinar y cambiar.
Luego se indica el contenido que va a tener cada casilla, este entre paréntesis, teniendo en cuenta que el primer dato va a aparecer en la primera fila de la primera columna, el segundo dato va a aparecer en la primera fila de la segunda columna, y así sucesivamente, hasta acabar con todas las columnas de la primera fila, luego entre otro paréntesis, va a ir la información de todas las columnas de la segunda fila, y así hasta terminar con la cantidad de filas que se requieran:
Se debe añadir esta información a la tabla, indicar el tamaño que esta va a tener, y añadir la tabla a un scrollpane; todo esto se realiza de la siguiente manera:
Además de la información, en el programa las tablas tienen colores de fondo y de letra, lo cual se realiza de la siguiente manera:
En esta tabla también se predeterminó el ancho de cada columna, para esto se utiliza el TableColumn, indicando la cantidad de columnas que se tienen y el tamaño de cada una; de la siguiente manera:
((TableModelListener)suscriptores.get(i)).tableChanged(evento);
}[7].
TABLAS SIN COMPONENTES
Esta es una forma de crear tablas sencillas(sin componentes). Se indica primero el nombre de las columnas, en una cadena de parámetros, de la siguiente forma:
Esta es una forma de crear tablas sencillas(sin componentes). Se indica primero el nombre de las columnas, en una cadena de parámetros, de la siguiente forma:
Las palabras que se encuentran en este tipo de letra son las cosas que el programador puede determinar y cambiar.
final String[] columnNames1 = {"HORA",
"LUNES",
"MARTES",
"MIÉRCOLES",
"JUEVES",
"VIERNES"};
Luego se indica el contenido que va a tener cada casilla, este entre paréntesis, teniendo en cuenta que el primer dato va a aparecer en la primera fila de la primera columna, el segundo dato va a aparecer en la primera fila de la segunda columna, y así sucesivamente, hasta acabar con todas las columnas de la primera fila, luego entre otro paréntesis, va a ir la información de todas las columnas de la segunda fila, y así hasta terminar con la cantidad de filas que se requieran:
final Object[][] info ={
{new Integer(720), "Química", "Modalidad", "Modalidad", "Modalidad", "Modalidad"},
{new Integer(850), "Ingles C.", "Filosofía", "Física", "Democracia", "L. Castellana"},
{new Integer(950), "DE", "S", "CA", "N", "SO"},
{new Integer(1020), "Filosofía", "Física", "Ingles C.", "L. Castellana",
"Calculo"},
{new Integer(1200), "DE", "S", "CA", "N", "SO"}, {new Integer(1230), "Filosofía", "Calculo", "Química", "Ed. Física",
"Talento"}
};
Se debe añadir esta información a la tabla, indicar el tamaño que esta va a tener, y añadir la tabla a un scrollpane; todo esto se realiza de la siguiente manera:
JTable table1 = new JTable(info, columnNames1);
table1.setPreferredScrollableViewportSize(new Dimension(500,100));
JScrollPane scrollPane1 = new JScrollPane(table1);
Además de la información, en el programa las tablas tienen colores de fondo y de letra, lo cual se realiza de la siguiente manera:
table1.setForeground(Color.blue);
table1.setBackground(Color.pink);
UTILIZANDO COMPONENTES
Para crear tabla con el TableModel, se crea una variable de tipo MyTableModel, para luego crear una nueva tabla, que contenga ese TableModel, de la siguiente manera:
Para crear tabla con el TableModel, se crea una variable de tipo MyTableModel, para luego crear una nueva tabla, que contenga ese TableModel, de la siguiente manera:
MyTableModel myModel = new MyTableModel();
JTable table = new JTable(myModel);
Igualmente que en la anterior tabla, en esta es necesario decir el tamaño que va a tener nuestra tabla, y añadirla a un scrollpane
En esta tabla, solo se puede seleccionar una fila a la vez, además muestra en la terminal(desde donde se abrió el archivo), la fila y la columna seleccionada. Para poder realizar esto se debe utilizar el SelectionMode, primero se debe determinar si se puede seleccionar varias filas, y si se puede seleccionar varias columnas de la siguiente forma:
Igualmente que en la anterior tabla, en esta es necesario decir el tamaño que va a tener nuestra tabla, y añadirla a un scrollpane
En esta tabla, solo se puede seleccionar una fila a la vez, además muestra en la terminal(desde donde se abrió el archivo), la fila y la columna seleccionada. Para poder realizar esto se debe utilizar el SelectionMode, primero se debe determinar si se puede seleccionar varias filas, y si se puede seleccionar varias columnas de la siguiente forma:
private boolean ALLOW_COLUMN_SELECTION = false;
private boolean ALLOW_COLUMN_SELECTION = true;
En esta tabla también se predeterminó el ancho de cada columna, para esto se utiliza el TableColumn, indicando la cantidad de columnas que se tienen y el tamaño de cada una; de la siguiente manera:
for (int i = 0, i <>
setUpIntegerEditor(table);
class MyTableModel extends AbstractTableModel {
column =" table.getColumnModel().getColumn(i)
if(i == 1) {
column.setPregerredWidth(100); } else {
if(i== 2) {
column.setPreferredWidth(100); } else
if (i == 4){
column.setPreferredWidth(50); } else { column.setPreferredWidth(8); } } } }
Esta tabla utilizando UpIntegerEditor, y el programa WholeNumberFiel, permite identificar cuando en una casilla hay un número, y permitir únicamente el ingreso de números en el.
setUpIntegerEditor(table);
private void setUpIntegerEditor(JTable table) {
final WholeNumberField integerField = new WholeNumberField(0, 5);
integerField.setHorizontalAlignment(WholeNumberField.RIGHT);
DefaultCellEditor integerEditor = new DefaultCellEditor(integerField) {
public Object getCellEditorValue() {
return new Integer(integerField.getValue()); } };
table.setDefaultEditor(Integer.class, integerEditor); }
Para finalizar se crea una clase en la cual van los títulos de las columnas, y la información que va dentro de cada fila. Esta información se escribe igualmente que en la tabla anterior, solo que esta, como ya se había dicho anteriormente, va dentro de una nueva clase, la cual va de la siguiente forma:
Para finalizar se crea una clase en la cual van los títulos de las columnas, y la información que va dentro de cada fila. Esta información se escribe igualmente que en la tabla anterior, solo que esta, como ya se había dicho anteriormente, va dentro de una nueva clase, la cual va de la siguiente forma:
class MyTableModel extends AbstractTableModel {
(Aquí van los nombres de las columnas y la información de cada fila)
public int getColumnCount() {
return columnNames.length; }
public int getRowCount() {
return informacion.length; ]
public String getColumnName(int col) {
return columnNames[col]; }
public Object getValueAt(int row, int col) {
return informacion[row][col]; }
public Class getColumnClass(int c) {
No hay comentarios:
Publicar un comentario