1、创建一个简单的Table
JTable table = new JTable(data, columnNames);
其中data和columnNames是两个数组,分贝代表表头和表中的数据。
下面是JTable的两个常用构造器:
JTable(Object[][] rowData, Object[] columnNames)
JTable(Vector rowData, Vector columnNames)
这两个构造器虽然简单,但有很多缺陷:
(1)每个单元格可编辑;
(2)把所有的数据类型都当做String型。
(3)静态的绑定数据,在初始化时就要求绑定所有数据,不适合在运行时从数据库导入数据的需求。
2、将Table加入容器
JScrollPane scrollPane = new JScrollPane(table);
table.setFillsViewportHeight(true); //使用容器全部高度
JScrollPane将表头始终报纸在容器上方,如果不想用JScrollPane作为容器,必须获得TableHeader对象,并且自己将其放置到容器中。
container.setLayout(new BorderLayout());
container.add(table.getTableHeader(), BorderLayout.PAGE_START);
container.add(table, BorderLayout.CENTER);
3、设置和改变列宽
TableColumn column = null;
for (int i = 0; i < 5; i++) {
column = table.getColumnModel().getColumn(i);
if (i == 2) {
column.setPreferredWidth(100); //third column is bigger
} else {
column.setPreferredWidth(50);
}
}
4、用户选择
可以通过JTable.setSelectionMode方法设置选择方式,该方法包含以下参数:MULTIPLE_INTERVAL_SELECTION, SINGLE_INTERVAL_SELECTION, and SINGLE_SELECTION,分别代表不连续多选,连续多选,单选。
还有几个和选择行为有关的方法:setRowSelectionAllowed,setColumnSelectionAllowed,setCellSelectionEnabled。
获得当前选择的行或列:JTable.getSelectedRows JTable.getSelectedColumns,返回选中的行号或列号组成的数组。
如果要获得lead selection的坐标:
String.format("Lead Selection: %d, %d. ",
table.getSelectionModel().getLeadSelectionIndex(),
table.getColumnModel().getSelectionModel().getLeadSelectionIndex());
用户选择会引起一系列的Selection Event发生,如对这些事件感兴趣,可以注册list selection listener进行监听。
5、创建一个TableModel
所有的TableModel对象,必须实现TableModel接口。如果编程者没有显示的提供TableModel,JTable会自动创建一个DefualtTableModel的实例。一般来说,编程者并不直接通过实现TableModel接口来创建model,可以简单的继承AbastractTableModel,这样会省好多事。
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);
}
}//可以将数据保存在一个数组中、Vector中、Hashmap中、或是数据库中。
6、监听数据变化
通过注册TableModelListener,来监听数据变化。
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...
}
...
}
7、发出数据变化事件
为了发出数据变化事件,model必须知道如何构建TableModelEvent 对象,这是一个非常复杂的过程,但是已经被DefaultTableModel所实现。如果有些场合DefaultTableModel并不适合,可以考虑AbstractTableModel,该model已经简单实现事件发送的框架。当数据发生变化时,显示调用以下方法:
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 |
8、Editor和Render
cell render用来显示各单元的内容(通常render的类型和单元格数据类型绑定),cell editor用来编辑单元格数据。比如,对于包含整数的单元格,会使用JLabel作为其render,而是用JTextField作为其editor。
为了决定某列的一个单元格改用何种render,table首先检查你是否显示为该列设置了render,如没有就调用model的getColumnClass方法获得单元格的数据类型,然后会根据数据类型寻找与其绑定的render。通常如下:
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.
editor也是通过如此方法选择的。
注意render并不控制事件,如果想捕获和table相关的事件:
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 selections and deselections... | Use a selection listener as described in Detecting User 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 |
9、自定render
(1)创建DefaultTableCellRenderer的子类,如果DefaultTableCellRenderer不满足要求,创建一个其他类的子类并实现TableCellRender接口
(2)通过JTable的setDefaultRenderer方法,设置与特定数据类型相关的render;通过TableColumn的setCellRenderer,设置某列的render;通过创建JTable的子类,重写getCellRenderer方法,设置某个单元格的render。
10、使用Combobox作为editor
JComboBox comboBox = new JComboBox();
comboBox.addItem("Snowboarding");
comboBox.addItem("Rowing");
comboBox.addItem("Chasing toddlers");
comboBox.addItem("Speed reading");
comboBox.addItem("Teaching high school");
comboBox.addItem("None");
sportColumn.setCellEditor(new DefaultCellEditor(comboBox));