Download as pdf or txt
Download as pdf or txt
You are on page 1of 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

La classe JTable i DefaultTableMode.


La forma ms fcil dutilitzar un JTable amb tota la seva funcionalitat consisteix en instanciar
un DefaultTableModel i embolcallar-hi el JTable al constructor.
DefaultTableModel model = new DefaultTableModel();
JTable taula = new JTable(model);
JScrollPane jsp=new JScrollPane(taula)//necessari per visualitzar-la!

Accions que podem fer:


Afegir columnes directament al model:
model.addColumn("etiqueta columna 1");
model.addColumn("etiqueta columna 2");

Afegir , modificar o esborrar dades directament al model:

Object [] fila = new Object[2];


fila[0] = "dades columna 1";
fila[1] = "dades columna 2";
model.addRow ( fila ); // Afegir una fila al final
model.setValueAt ("nou valor", 0, 1); // Canviar el valor de la fila 1, columna
2.

model.removeRow (0); // Borrar la primera fila

Qualsevol canvi es reflectir de forma immediata al JTable.

Obtenir la fila i columna del JTable en la qual shi ha premut el ratol.


Sovint ens pot interessar seleccionar una fila del JTable per fer alguna acci determinada
(visualitzar un men, mostrar dades, ...)
Una forma de fer-ho seria afegint un MouseListener al JTable:
taula.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
int fila = taula.rowAtPoint(e.getPoint());
int columna = taula.columnAtPoint(e.getPoint());
if ((fila > -1) && (columna > -1))
System.out.println(model.getValueAt(fila,columna));
}
});

Hem afegit un MouseAdapter per no tenir que implementar tots els mtodes de la interfcie.
Amb el mtode taula.rowAtPoint() s possible obtenir la fila del JTable on sha produt el
succs del ratol (prmer el ratol en aquest cas). Aix doncs, s suficient cridar aquest mtode
passant-li les coordenades x,y des succs del ratol, que sobt amb el mtode e.getPoint().
Material d APM.

Pgina 1 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

Un cop sabem la fila, hem de comprovar si s major que -1. El mtode rowAtPoint() ens
retorna -1 si hem premut en el JTable, per fora de qualsevol fila. s el cas que el JTable tingui
un tamany en pxels superior al que correspon segons el seu nombre de files.
El mateix raonament serveis per a les columnes amb columnAtPoint().
Un cop hem obtingut la fila i sabem que no s -1, s fcil obtenir les dades corresponents a
travs del model. En aquest cas escriu per pantalla el valor de la fila i la columna
seleccionada.

Fer que una cella del JTable no sigui editable.


Si utilitzem el DefaultTableModel les celles del JTable sn editables per defecte. Ara b, ens
pot interessar que no ho siguin. El JTable no t mtodes per evitar-ho. La forma de decidir
quines celles sn o no editables cal fer el nostre propi model de dades TableModel. La forma
ms senzilla s heretar de DefaultTableModel i redefinir el mtode isCellEditable() com mostra
el segent codi:
public class MeuModel extends DefaultTableModel
{
public boolean isCellEditable (int row, int column)
{
// Aqu retornem true o false segons si volem que una cella
// identificada per fila,columna (row,column), siqui o no
//editable
if (column == 3)
return true;
return false;
}
}

Podeu observar que hem creat el nostre propi model de dades que fa que la columna 4
(Recordeu que els ndexs sinicien a la posici 0) de la taula sigui editable i la resta no. Ara
noms ens cal instanciar el JTable utilitzant aquest model i utilitzar-lo com abans.
MeuModel model = new MeuModel();
JTable taula = new JTable(model);

Canviar el tipus de dades amb DefaultTableModel


Per defecte JTable fa que totes les dades que t siguin Object. Ara b, ens pot interessar que
una determinada columna sigui dun determinat tipus Boolean, Integer,... per canviar, per
exemple, la forma visual de presentaci (TableCellRender) de les dades.
Per fer-ho hem de crear el nostre propi model de Dades com abans. La forma ms senzilla s
heretant de la classe DefaultTableModel i redefinir el mtode getColumnClass().
Material d APM.

Pgina 2 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

public class MeuModel extends DefaultTableModel


{
/** Primera columna Boolean, segona Integer i la resta Object */
public Class getColumnClass(int columna)
{
if (columna == 0) return Boolean.class;
if (columna == 1) return Integer.class;
return Object.class;
}
}

En aquest cas la primera columna ser boolean, la segona Integer i la resta Object.
Nota: Si fem una columna de tipus Boolean, el JTable el pintar com un JCheckBox.

JTable amb scroll i capalera.


Per aconseguir que un JTable tingui scroll i una capalera amb etiquetes de les columnes, es
necessari que sigui embolcallada per una JScrollPane. Aix podem fer-ho de dues formes:
JTable taula = new JTable();
JScrollPane scroll = new JScrollPane(taula);

o tamb:
JTable taula = new JTable();
JScrollPane scroll = new JScrollPane();
scroll.setViewportView(taula);

Compte perqu el segent codi s incorrecte i NO funcionar correctament:


JTable taula = new JTable();
JScrollPane scroll = new JScrollPane();
// Aix NO funciona.
scroll.add(tabla);

Canviar l'espai entre celles.


Podeu fer-ho amb el mtode setIntercellSpacing.

Prohibir intercanviar lordre de les columnes.


No permetre intercanviar lordre entre les columnes:
taula.getTableHeader().setReorderingAllowed(false) ;

Material d APM.

Pgina 3 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

Selecci Mltiple en un JTable.


JTable table = new JTable();
// Get default selection mode
int selMode = table.getSelectionModel().getSelectionMode();
// MULTIPLE_INTERVAL_SELECTION
// Allow only single a selection
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// Allow selection to span one contiguous set of rows,
// visible columns, or block of cells
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
// Allow multiple selections of rows, visible columns, or cell blocks (default)
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

Codi dexemple: Posar un ResultSet dins duna JTable.


Instanciar una JTable:
DefaultTableModel model = new DefaultTableModel();
JTable taula = new JTable(model);

Omplir el DefaultTableModel amb les dades del ResultSet:


// Crear les columnes.
model.addColumn("id");
model.addColumn("nombre");
model.addColumn("nacimiento");
// Iteraci per a cada resultat de la consulta
while (rs.next())
{
// Crear un array que es correspondr amb una fila de la taula.
Object [] fila = new Object[3]; //Hi ha tres columnes a la taula
// Omplir cada posici de larray amb una de les columnes de la
taula de la base de dades.
for (int i=0;i<3;i++)
fila[i] = rs.getObject(i+1); // El primer ndex dun rs s el
1, no el zero, per aix hi sumem 1.
// Afegir al model la fila completa.
model.addRow(fila);
}

Material d APM.

Pgina 4 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

Tot el que fem amb el DefaultTableModel (model) sactualitzar automticament al


JTable. A mida que executem el codi saniran afegint els registres al JTable.

Les Metadades.
Podem automatitzar el procs domplir un JTable amb un resultSet utilitzant la
informaci que ens faciliten les MetaDades dun ResultSet. El codi per obtenir aquestes
metadades seria:
ResultSetMetaData metaDades = rs.getMetaData();

La classe ResultSetMetaData cont tota la informaci sobre els camps de la taula


continguda al ResultSet. Concretament necessitem el nombre de columnes i letiqueta
de cada una de les columnes. El codi seria:
// obtenir el nmero de columnes.
int numeroColumnes = metaDatos.getColumnCount();
// crear un array detiquetes per a omplir
Object[] etiquetes = new Object[numeroColumnes];
// obtienir cada una de las etiquetes para a cada columna
for (int i = 0; i < numeroColumnes; i++)
{
// Altre cop, per a ResultSetMetaData la primera columna s la 1.
etiquetes[i] = metaDades.getColumnLabel(i + 1);
}

Un cop tenim larray detiquetes hem de fer una crida al DefaultTableMode per
configurar el nombre de columnes. El codi seria:
model.setColumnIdentifiers(etiquetes);

Queda per lalumne el codi genric per omplir de forma automtica un JTable a partir
dun ResultSet qualsevol.

Material d APM.

Pgina 5 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

JTABLE.
http://docs.oracle.com/javase/tutorial/uiswing/components/table.html
Amb el JTable es pot visualitzar taules de dades i opcionalment editar-les. La segent
imatge mostra un exemple de JTable amb scroll pane:

Creant una taula simple. (SimpleTableModel.java)


import
import
import
import
import
import
import
import

javax.swing.JFrame;
javax.swing.JPanel;
javax.swing.JScrollPane;
javax.swing.JTable;
java.awt.Dimension;
java.awt.GridLayout;
java.awt.event.MouseAdapter;
java.awt.event.MouseEvent;

public class SimpleTableDemo extends JPanel {


private boolean DEBUG = false;
public SimpleTableDemo() {
super(new GridLayout(1,0));
String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};
Object[][] data = {
{"Kathy", "Smith",
"Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black",
"Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White",
"Speed reading", new Integer(20), new Boolean(true)},
{"Joe", "Brown",
"Pool", new Integer(10), new Boolean(false)}
};
final JTable table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
if (DEBUG) {
table.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
printDebugData(table);
}
});
}
//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
//Add the scroll pane to this panel.
add(scrollPane);
}

Material d APM.

Pgina 6 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

private void printDebugData(JTable table) {


int numRows = table.getRowCount();
int numCols = table.getColumnCount();
javax.swing.table.TableModel model = table.getModel();
System.out.println("Value of data: ");
for (int i=0; i < numRows; i++) {
System.out.print("
row " + i + ":");
for (int j=0; j < numCols; j++) {
System.out.print(" " + model.getValueAt(i, j));
}
System.out.println();
}
System.out.println("--------------------------");
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("SimpleTableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
SimpleTableDemo newContentPane = new SimpleTableDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

La fila capalera lhem declarat amb un vector de tipus cadena:


String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};

Les dades de la taula les hem obtingut amb una taula de dues dimensions, on els
seus elements sn de tipus Object:
Object[][] data = {
{"Kathy", "Smith",
"Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black",
"Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White",
"Speed reading", new Integer(20), new Boolean(true)},
{"Joe", "Brown",
"Pool", new Integer(10), new Boolean(false)}
};

Material d APM.

Pgina 7 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

La taula lhem construt utilitzant aquestes dades i els noms de columnes:


JTable table = new JTable(data, columnNames);

Hi ha dos constructors que accepten dades directament:


JTable(Object[][] rowData, Object[] columnNames)
JTable(Vector rowData, Vector columnNames)

Lavantatge daquests constructors s la seva facilitat ds. En canvi com a


desavantatges podem destacar:
Automticament fa les celles editables.
Totes les dades sn tractades com a cadenes (String). En canvi, si pogussim
posar un tipus boole, podria mostrar-se com un vist-i-plau.
Cal posar totes les dades en un Vector o Array, quan en realitat pot no ser
apropiat per algun tipus de dades. Per exemple si estem treballant amb consultes
a BBDD ens podria interessar treballar directament amb els valors i no pas
haver-los de copiar dins dun Vector o Array.
Si volem evitar aquestes restriccions ens cal implementar la nostre propi model de
dades.
Afegint un JTable dins dun Container.
La forma ms tpica de posar barres de desplaament a un JTable seria fent:
JScrollPane scrollPane = new JscrollPane(table);
table.setFillsViewportHeight(true);

El constructor JScrollPane s crida amb la instncia del JTable com argument.


Aix crea una barra de desplaament com un contenidor per la taula; la taula s
afegida automticament al contenidor.
JTable.setFillsViewportHeight s invocat per configurar la propietat del conjunt
de fillsViewportHeight. Quan aquesta propietat s true la taula utilitza tota
lalada del contenidor,
Tot i desplaar les files de la taula, la fila capalera sempre est visible.
Si utilitzes una taula sense barra de desplaament, i vols visulatizar sempre les dades de
la fila capalera, cal situar la capalera de la segent forma:
container.setLayout(new BorderLayout());
container.add(table.getTableHeader(), BorderLayout.PAGE_START);
container.add(table, BorderLayout.CENTER);

Material d APM.

Pgina 8 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

Configurant i canviant lamplada de les columnes


Per defecte totes les columnes duna taula sinicien amb la mateixa amplada, i omplen
tota lamplada de la taula.
De totes formes podem triar lamplada de les columnes utilitzant setPreferredWidth en
cada columna de la taula.
En el segent codi lamplada de la 3a columna s superior a la resta:
TableColumn column = null;
for (int i = 0; i < 5; i++) {
column = table.getColumnModel().getColumn(i);
if (i == 2) {
column.setPreferredWidth(100); //tercera columna s ms gran
} else {
column.setPreferredWidth(50);
}
}

Cada columna de la taula s representada per un objecte TableColumn.

Utilitzar seleccions.
Per defecte podem seleccionar una o ms files. Podem ser contiges o no. La darrera
cella que indica lusuari t una indicaci visual especial; la cella t el focus.
La segent taula mostra les possibles opcions:
Mouse
Operation
Keyboard Action
Action
Select single row.
Click.
Up Arrow or Down Arrow.
Extend contiguous
selection.

Shift-Click or
Drag over
Shift-Up Arrow or Shift-Down Arrow.
rows.

Add row to
selection/toggle row
selection.

Move lead selection with Control-Up Arrow or


Control-Down Arrow, then use Space Bar to add
Control-Click
to selection or Control-Space Bar to toggle row
selection.

Material d APM.

Pgina 9 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

El segent codi mostra les diferents possibilitats implementades:


import
import
import
import
import
import
import
import

javax.swing.*;
javax.swing.table.AbstractTableModel;
javax.swing.event.ListSelectionEvent;
javax.swing.event.ListSelectionListener;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.GridLayout;
java.awt.Dimension;

public class TableSelectionDemo extends JPanel


implements ActionListener {
private JTable table;
private JCheckBox rowCheck;
private JCheckBox columnCheck;
private JCheckBox cellCheck;
private ButtonGroup buttonGroup;
private JTextArea output;
public TableSelectionDemo() {
super();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
table = new JTable(new MyTableModel());
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
table.getSelectionModel().addListSelectionListener(new RowListener());
table.getColumnModel().getSelectionModel().
addListSelectionListener(new ColumnListener());
add(new JScrollPane(table));
add(new JLabel("Selection Mode"));
buttonGroup = new ButtonGroup();
addRadio("Multiple Interval Selection").setSelected(true);
addRadio("Single Selection");
addRadio("Single Interval Selection");
add(new JLabel("Selection Options"));
rowCheck = addCheckBox("Row Selection");
rowCheck.setSelected(true);
columnCheck = addCheckBox("Column Selection");
cellCheck = addCheckBox("Cell Selection");
cellCheck.setEnabled(false);
output = new JTextArea(5, 40);
output.setEditable(false);
add(new JScrollPane(output));
}
private JCheckBox addCheckBox(String text) {
JCheckBox checkBox = new JCheckBox(text);
checkBox.addActionListener(this);
add(checkBox);
return checkBox;
}
private JRadioButton addRadio(String text) {
JRadioButton b = new JRadioButton(text);
b.addActionListener(this);
buttonGroup.add(b);
add(b);
return b;
}
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
//Cell selection is disabled in Multiple Interval Selection
//mode. The enabled state of cellCheck is a convenient flag
//for this status.
if ("Row Selection" == command) {
table.setRowSelectionAllowed(rowCheck.isSelected());
//In MIS mode, column selection allowed must be the
//opposite of row selection allowed.

Material d APM.

Pgina 10 de 21

DAM UF5 Llibreries Swing La classe JTable.

}
}

Institut Almat

if (!cellCheck.isEnabled()) {
table.setColumnSelectionAllowed(!rowCheck.isSelected());
}
else if ("Column Selection" == command) {
table.setColumnSelectionAllowed(columnCheck.isSelected());
//In MIS mode, row selection allowed must be the
//opposite of column selection allowed.
if (!cellCheck.isEnabled()) {
table.setRowSelectionAllowed(!columnCheck.isSelected());
}
else if ("Cell Selection" == command) {
table.setCellSelectionEnabled(cellCheck.isSelected());
else if ("Multiple Interval Selection" == command) {
table.setSelectionMode(
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
//If cell selection is on, turn it off.
if (cellCheck.isSelected()) {
cellCheck.setSelected(false);
table.setCellSelectionEnabled(false);
}
//And don't let it be turned back on.
cellCheck.setEnabled(false);
else if ("Single Interval Selection" == command) {
table.setSelectionMode(
ListSelectionModel.SINGLE_INTERVAL_SELECTION);
//Cell selection is ok in this mode.
cellCheck.setEnabled(true);
else if ("Single Selection" == command) {
table.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
//Cell selection is ok in this mode.
cellCheck.setEnabled(true);

}
//Update checkboxes to reflect selection mode side effects.
rowCheck.setSelected(table.getRowSelectionAllowed());
columnCheck.setSelected(table.getColumnSelectionAllowed());
if (cellCheck.isEnabled()) {
cellCheck.setSelected(table.getCellSelectionEnabled());
}
}
private void outputSelection() {
output.append(String.format("Lead: %d, %d. ",
table.getSelectionModel().getLeadSelectionIndex(),
table.getColumnModel().getSelectionModel().
getLeadSelectionIndex()));
output.append("Rows:");
for (int c : table.getSelectedRows()) {
output.append(String.format(" %d", c));
}
output.append(". Columns:");
for (int c : table.getSelectedColumns()) {
output.append(String.format(" %d", c));
}
output.append(".\n");
}
private class RowListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent event) {
if (event.getValueIsAdjusting()) {
return;
}
output.append("ROW SELECTION EVENT. ");
outputSelection();
}
}
private class ColumnListener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent event) {
if (event.getValueIsAdjusting()) {
return;
}
output.append("COLUMN SELECTION EVENT. ");
outputSelection();

Material d APM.

Pgina 11 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

}
}
class MyTableModel extends AbstractTableModel {
private String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};
private Object[][] data = {
{"Kathy", "Smith",
"Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black",
"Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White",
"Speed reading", new Integer(20), new Boolean(true)},
{"Joe", "Brown",
"Pool", new Integer(10), new Boolean(false)}
};
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return data.length;
}
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
/*
* JTable uses this method to determine the default renderer/
* editor for each cell. If we didn't implement this method,
* then the last column would contain text ("true"/"false"),
* rather than a check box.
*/
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's
* editable.
*/
public boolean isCellEditable(int row, int col) {
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
if (col < 2) {
return false;
} else {
return true;
}
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
/**
* Create the GUI and show it.

Material d APM.

For thread safety,

Pgina 12 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

* this method should be invoked from the


* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Disable boldface controls.
UIManager.put("swing.boldMetal", Boolean.FALSE);
//Create and set up the window.
JFrame frame = new JFrame("TableSelectionDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
TableSelectionDemo newContentPane = new TableSelectionDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

La tercera fila i tercera columna t el focus. Podem triar el tipus de selecci que volem fer. Si
triem single selection noms podem fer seleccions duna sola fila. Si triem Single Interval
Selection podem fer seleccions de varies files contiges. Laltra opci permet fer selecci
mltiple i en files no contiges.
Material d APM.

Pgina 13 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

Per aconseguir canviar de modes sutilitza el mtode JTable.setSelectionMode amb les


segents opcions, definides a javax.swing.ListSelectionModel, com a parmetre:
o MULTIPLE_INTERVAL_SELECTION,
o SINGLE_INTERVAL_SELECTION,
o SINGLE_SELECTION.
Exemple:
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

Permetre la selecci per fila, per columna o per cella cal fer-ho utilitzant:
void setRowSelectionAllowed( boolean )
boolean getRowSelectionAllowed()
void setColumnSelectionAllowed( boolean )
boolean getColumnSelectionAllowed()
void setCellSelectionEnabled( boolean )
boolean getCellSelectionEnabled()

Determinar la selecci actual:


Int[] JTable.getSelectedRows
Int[] JTable.getSelectedColumns
Retrona els ndexs de les files i columnes seleccionades respectivament.

Crear un TableModel
Tots els objectes JTable utilitzen un objecte Table Model per gestionar les dades. Un table
model ha dimplementar la interfcie TableModel. Si el programador no facilita un objecte
table model, JTable automticament crea una instncia de DefaultTableModel. La relaci
entre aquests objectes s la segent:

Material d APM.

Pgina 14 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

Una possible implementaci simple seria:


new AbstractTableModel() {
public String getColumnName(int col) {
return columnNames[col].toString();
}
public int getRowCount() { return rowData.length; }
public int getColumnCount() { return columnNames.length; }
public Object getValueAt(int row, int col) {
return rowData[row][col];
}
public boolean isCellEditable(int row, int col)
{ return true; }
public void setValueAt(Object value, int row, int col) {
rowData[row][col] = value;
fireTableCellUpdated(row, col);
}
}

Listening per canvis en les dades.


La interfcie que cal implementar s TableModelListener.
Exemple:
import javax.swing.event.*;
import javax.swing.table.TableModel;
public class SimpleTableDemo ... implements TableModelListener {
...
public SimpleTableDemo() {
...
table.getModel().addTableModelListener(this);
...
}
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
String columnName = model.getColumnName(column);
Object data = model.getValueAt(row, column);
...// Do something with the data...
}
...
}

Material d APM.

Pgina 15 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

Disparant events per canvis en les dades.


Mtodes dAbstractTableModel
Method

Change

fireTableCellUpdated

Update of specified cell.

fireTableRowsUpdated

Update of specified rows

fireTableDataChanged

Update of entire table (data only).

fireTableRowsInserted

New rows inserted.

fireTableRowsDeleted

Existing rows Deleted

fireTableStructureChanged

Invalidate entire table, both data and structure.

Concepts: Editors i renders.


Un simple cell renderer s utilitzat generalment per dibuixar totes les celles que
contenen dades del mateix tipus.
Per triar com mostrar les celles duna columna, una taula primer determina si el
programador ha especificat una forma particular de fer-ho. Si no ho ha fet, llavors
model de la taula invoca el mtode getColumnClass, el qual obt el tipus de dades de
les celles de la columna. Desprs, la taula compara els tipus de dades de la columna
amb la llista de tipus de dades que t registrades per dibuixar la columna. Els tipus de
dades suportats sn:
Boolean rendered with a check box.
Number rendered by a right-aligned label.
Double, Float same as Number, but the object-to-text translation is
performed by a NumberFormat instance (using the default number format for the
current locale).
Date rendered by a label, with the object-to-text translation performed by a
DateFormat instance (using a short style for the date and time).
ImageIcon, Icon rendered by a centered label.
Object rendered by a label that displays the object's string value.
Recorda que si utilitzes un JTable amb el teu propi model de dades, utilitza el tipus
Object per cada columna. Per especificar els tipus de dades de les columnes cal definirho amb el mtode getColumnClass de forma adequada.

Material d APM.

Pgina 16 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

Events en funci de la part grfica afectada:


Situation
How to Get Events
To detect events from a cell
that is being edited...

Use the cell editor (or register a listener on the cell


editor).

To detect row/column/cell
Use a selection listener as described in Detecting User
selections and deselections... Selections.
To detect mouse events on a
column header...

Register the appropriate type of mouse listener on the


table's JTableHeader object. (See TableSorter.java
for an example.)

To detect other events...

Register the appropriate listener on the JTable object.

Utilitzant renderers a mida (consultar la font)


Especificar Tool Tips per a les celles.
Per defecte el text que mostrar el tool tips per una taula es determina per les celles.
Exemple dus:
//Set up tool tips for the sport cells.
DefaultTableCellRenderer renderer =
new DefaultTableCellRenderer();
renderer.setToolTipText("Click for combo box");
sportColumn.setCellRenderer(renderer);

Aquest codi preten posar un tool tip text a la columna Sport.


Podem fer el mateix per de forma no esttica. Necessitarem fer dues coses:
Afegir un petit codi al mtode getTableCellRendererComponent de la interficie
TableCellRenderer.
Sobreescriure el mtode getToolTipText() del JTable.

Exemple:
public class ColorRenderer extends JLabel
implements TableCellRenderer {
...
public Component getTableCellRendererComponent(
JTable table, Object color,
boolean isSelected, boolean hasFocus,
int row, int column) {
Color newColor = (Color)color;
...
setToolTipText("RGB value: " + newColor.getRed() + ", "
+ newColor.getGreen() + ", "
+ newColor.getBlue());
return this;
}
}

Material d APM.

Pgina 17 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

Mostra un tool tip text a la columna del color favorit:

Especificar Tool Tips per capaleres de columna.


Podem especificar tips per a la capalera de les columnes JTableHeader. Per fer-ho cal
sobreescriure el mtode getToolTipText. Alternativament pots invocar el mtode
TableColumn.setHeaderRender per cusotmitzar el render de la capalera.
Exemple:
table.getTableHeader().setToolTipText(
"Click to sort; Shift-Click to sort in reverse order");

Ordernar I filtrar
Per ordenar i filtrar en una taula s gestiona amb un objecte sorter. La forma ms fcil
de fer-ho s utilitzant la propietat setAutoCreateRowSorter(true).
Exemple:
JTable table = new JTable();
table.setAutoCreateRowSorter(true);

Si vols ms control sobre lordenaci, pots instanciar un TableRowSorter i especificar


quin s lobjecte ordenable de la teva taula.
TableRowSorter<TableModel> sorter
= new TableRowSorter<TableModel>(table.getModel());
table.setRowSorter(sorter);

TableRowSorter utilitza un objecte java.util.Comparator per ordenar les files. Una


classe que implementi aquesta interfcie cal que disposi del m`+etode compare que
defineix com dos objectes sn comparats per tal dordenar-los.
Exemple per comparar dos cadenes:
Comparator<String> comparator = new Comparator<String>() {
public int compare(String s1, String s2) {
String[] strings1 = s1.split("\\s");
String[] strings2 = s2.split("\\s");
return strings1[strings1.length - 1]
.compareTo(strings2[strings2.length - 1]);
}
};

Material d APM.

Pgina 18 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

Si volem ordenar per ms duna columna podem fer el segent:


List <RowSorter.SortKey> sortKeys
= new ArrayList<RowSorter.SortKey>();
sortKeys.add(new RowSorter.SortKey(1, SortOrder.ASCENDING));
sortKeys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
sorter.setSortKeys(sortKeys);

Posar una bot dins una cella de la taula


http://www.java2s.com/Code/Java/Swing-Components/ButtonTableExample.htm

import
import
import
import
import

java.awt.Component;
java.awt.event.ActionEvent;
java.awt.event.ActionListener;
java.awt.event.WindowAdapter;
java.awt.event.WindowEvent;

import
import
import
import
import
import
import
import
import
import

javax.swing.DefaultCellEditor;
javax.swing.JButton;
javax.swing.JCheckBox;
javax.swing.JFrame;
javax.swing.JOptionPane;
javax.swing.JScrollPane;
javax.swing.JTable;
javax.swing.UIManager;
javax.swing.table.DefaultTableModel;
javax.swing.table.TableCellRenderer;

/**
* @version 1.0 11/09/98
*/
public class JButtonTableExample extends JFrame {
public JButtonTableExample() {
super("JButtonTable Example");
DefaultTableModel dm = new DefaultTableModel();
dm.setDataVector(new Object[][] { { "button 1", "foo" },
{ "button 2", "bar" } }, new Object[] { "Button", "String" });
JTable table = new JTable(dm);
table.getColumn("Button").setCellRenderer(new ButtonRenderer());
table.getColumn("Button").setCellEditor(
new ButtonEditor(new JCheckBox()));
JScrollPane scroll = new JScrollPane(table);

Material d APM.

Pgina 19 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

getContentPane().add(scroll);
setSize(400, 100);
setVisible(true);
}
public static void main(String[] args) {
JButtonTableExample frame = new JButtonTableExample();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
/**
* @version 1.0 11/09/98
*/
class ButtonRenderer extends JButton implements TableCellRenderer {
public ButtonRenderer() {
setOpaque(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
} else {
setForeground(table.getForeground());
setBackground(UIManager.getColor("Button.background"));
}
setText((value == null) ? "" : value.toString());
return this;
}
}
/**
* @version 1.0 11/09/98
*/
class ButtonEditor extends DefaultCellEditor {
protected JButton button;
private String label;
private boolean isPushed;
public ButtonEditor(JCheckBox checkBox) {
super(checkBox);
button = new JButton();
button.setOpaque(true);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}

Material d APM.

Pgina 20 de 21

DAM UF5 Llibreries Swing La classe JTable.

Institut Almat

});
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
if (isSelected) {
button.setForeground(table.getSelectionForeground());
button.setBackground(table.getSelectionBackground());
} else {
button.setForeground(table.getForeground());
button.setBackground(table.getBackground());
}
label = (value == null) ? "" : value.toString();
button.setText(label);
isPushed = true;
return button;
}
public Object getCellEditorValue() {
if (isPushed) {
//
//
JOptionPane.showMessageDialog(button, label + ": Ouch!");
// System.out.println(label + ": Ouch!");
}
isPushed = false;
return new String(label);
}
public boolean stopCellEditing() {
isPushed = false;
return super.stopCellEditing();
}
protected void fireEditingStopped() {
super.fireEditingStopped();
}
}

Material d APM.

Pgina 21 de 21

You might also like