Tables
Tables
Like trees, tables in Swing are vast and powerful.
They are primarily intended to be the popular “grid” interface to
databases via Java Database Connectivity (JDBC, discussed in Chapter 15) and
thus they have a tremendous amount of flexibility, which you pay for in
complexity. There’s easily enough here to be the basis of a full-blown
spreadsheet and could probably justify an entire book. However, it is also
possible to create a relatively simple JTable if you understand the
basics.
The JTable controls how the data is displayed,
but the TableModel controls the data itself. So to create a JTable
you’ll typically create a TableModel first. You can fully implement
the TableModel interface, but it’s usually simpler to inherit from
the helper class AbstractTableModel:
//:
c13:Table.java
//
Simple demonstration of JTable.
//
<applet code=Table
//
width=350 height=200></applet>
import
javax.swing.*;
import
java.awt.*;
import
java.awt.event.*;
import
javax.swing.table.*;
import
javax.swing.event.*;
import
com.bruceeckel.swing.*;
public
class
Table
extends
JApplet {
JTextArea txt =
new
JTextArea(4, 20);
// The TableModel controls all the
data:
class
DataModel
extends
AbstractTableModel {
Object[][] data = {
{"one",
"two",
"three",
"four"},
{"five",
"six",
"seven",
"eight"},
{"nine",
"ten",
"eleven",
"twelve"},
};
// Prints data when table
changes:
class
TML
implements
TableModelListener {
public
void
tableChanged(TableModelEvent e){
txt.setText("");
// Clear it
for(int
i = 0; i < data.length; i++) {
for(int
j = 0; j < data[0].length; j++)
txt.append(data[i][j] + "
");
txt.append("\n");
}
}
}
public
DataModel() {
addTableModelListener(new
TML());
}
public
int
getColumnCount() {
return
data[0].length;
}
public
int
getRowCount() {
return
data.length;
}
public
Object
getValueAt(int
row,
int
col) {
return
data[row][col];
}
public
void
setValueAt(Object val,
int
row,
int
col) {
data[row][col] = val;
// Indicate the change has
happened:
fireTableDataChanged();
}
public
boolean
isCellEditable(int
row,
int
col) {
return
true;
}
}
public
void
init() {
Container cp = getContentPane();
JTable table =
new
JTable(new
DataModel());
cp.add(new
JScrollPane(table));
cp.add(BorderLayout.SOUTH, txt);
}
public
static
void
main(String[] args) {
Console.run(new
Table(), 350, 200);
}
}
///:~
DataModel contains an array of data, but you
could also get the data from some other source such as a database. The
constructor adds a TableModelListener that prints the array every time
the table is changed. The rest of the methods follow the Beans naming
convention, and are used by JTable when it wants to present the
information in DataModel. AbstractTableModel provides default
methods for setValueAt( ) and isCellEditable( ) that
prevent changes to the data, so if you want to be able to edit the data, you
must override these methods.
Once you have a TableModel, you only need to
hand it to the JTable constructor. All the details of displaying,
editing, and updating will be taken care of for you. This example also puts the
JTable in a JScrollPane
|