使用 JTable 类你可以显示表中的数据,也可以允许用户编辑表中的数据,JTable 不包含数据,也不缓存数据,它只是你的数据的壹個视图,下图是一个在滚动窗格中显示的一个典型的表格:
本节的其余部分告诉你如何完成一些表格相关的常用任务。
创建壹個简单的表格 1、点击
Launch 可以使用
Java Web Start 运行
SimpleTableDemo ,或者由你自己来编译运行
SimpleTableDemo.java ;
2、点击包含 "Snowboarding" 的单元格,这壹行都会被选中,说明你已经选择了 Kathy Smith 的数据。壹個特殊的高亮显示说明 "Snowboarding" 单元格是可以编辑的。通常来讲,你可以通过双击单元格来编辑该单元的文本信息。
3、将鼠标指向 "First Name",现在点击鼠标并且拖到右边,如同你所看到的壹样,用户可以重新排列表格中的列名称。
4、将鼠标指向列头的右边缘,现在点击鼠标并且左右拖动,该列宽度发生了改变,并且其它列填充了多出来的空间。
5、调整包含表格的窗口大小,以便它比实际展示需要的空间更大壹些。所有的表格元素变宽了,水平的填充了多出来的额外空间。
SimpleTableDemo.java 中的表格在 String 数组中声明列名称:
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)}
}; 然后表格对象使用 data 和 columnNames 完成构建。
JTable table = new JTable(data, columnNames);
壹共有两個 JTable 构造方法直接接受数据,SimpleTableDemo 使用第壹种:
JTable(Object[][] rowData, Object[] columnNames)
JTable(Vector rowData, Vector columnNames) 这些构造方法的优点就是它们非常易用,然而,这些构造方法也有它的缺点:
他们设置每個单元格可编辑;
他们以相同的方式对待所有的数据类型(全部识别为 String)。比如说,如果表中的某壹列包含 Boolean 数据,表格可以将该数据显示为壹個复选框。因此,如果你使用上述两個构造方法中任意壹個,你的 Boolean 数据都会被显示为字符串。你可以在上图中的 Vegetarian 列中查看这种差异。
他们要求你把所有的数据都存储在壹個二维数组或者 Vector 对象中,但是这样做对于某些情况下的数据是不合适的。比如说,如果你从数据库中初始化壹系列数据,你可能希望直接查询对象以获取结果,而不是把所有的结果都复制到数组或者 Vector 中。
如果你希望绕过这些限制,你需要实现自己的 Table Model,可以参考
创建壹個 Table Model。
增加壹個表格到容器中
如下是壹段典型的创建壹個卷动窗格作为表格的容器的代码:
JScrollPane scrollPane = new JScrollPane(table);
table.setFillsViewportHeight(true); 上面两行代码做了如下事情:调用 JScrollPane 构造方法并传入 table 对象作为其参数,这句话为 table 对象创建了壹個滚动窗格,table 被自动添加到该容器中;
调用
JTable.setFillsViewportHeight() 设置了fillsViewportHeight 属性,设置表格是否需要大到足以填充封闭视图的全部高度。当这個属性为 true 时,表格对象使用容器的所有高度,哪怕没有足够多的行来使用垂直的空间,这样做可以更加容易的使用表格作为拖拽的目标。
滚动空格自动的将表头放在了顶端,当表格中的数据滚动时仍然可以看到列名显示在顶上。
如果你使用表格却不包含滚动空格,那么你需要获取表头组件并且自己来放置它,比如说像下面这样:
container.setLayout(new BorderLayout());
container.add(table.getTableHeader(), BorderLayout.PAGE_START);
container.add(table, BorderLayout.CENTER);
设置和更改列宽度
默认情况下,表中所有的列开始时都是等宽的,并且所有的列会自动填充表格的整個宽度。当表格变宽或者变窄(当用户调整包含表格的窗口时会发生),所有的列宽会自动适应变化。
当用户通过拖动列的右边缘来调整列宽度时,其它列必须改变宽度,或者表格的宽度也必须改变。默认情况下,表格的宽度会保持原样,所有拖拽点右左边的列会调整以适应右边的空间增大,所有拖拽点左边的列会调整以适应左边的空间减少。
如果希望自定义初始的列宽,对于你的表格中的每壹列,你可以调用 setPreferredWidth 方法来进行设置。这会设置推荐宽度和他们的近似相对宽度。比如说:增加如下代码到 SimpleTableDemo 会让第三列比其它列要宽壹些。
TableColumn column = null;
for (int i = 0; i < 5; i++) {
column = table.getColumnModel().getColumn(i);
if (i == 2) {
column.setPreferredWidth(100); //第三列宽壹些
} else {
column.setPreferredWidth(50);
}
} 如同上述代码显示的壹样,表格的每壹列都由壹個
TableColumn 对象表示。TableColumn 为列宽度的最小值,推荐值,最大值提供了 getter 和 setter 方法,同样也提供了获取当前列宽度的方法。比如说,基于壹個近似的空间设置需要绘制的单元格元素的宽度,可以参考
TableRenderDemo.java 的 initColumnSizes() 方法。
当用户明确的调整宽度时,
列的首选宽度设置为用户指定的尺寸,同时变成列的当前宽度。然而,当表格自己调整时(通常因为窗口调整了)列的推荐宽度则不会改变,存在的首选宽度用于计算新的列宽以填充可用的空间。
你可以通过调用
setAutoResizeMode(int) 方法改变表格的宽度调整行为。
用户的选择
在这個默认配置下,表格支持选择壹行或者多行,用户可以选择连续的几行。最后一个单元格指示的用户得到一个特殊的迹象,在金属的视觉上看,这個元素超出了轮廓,它有时被称作焦点元素或者当前元素,用户使用鼠标或者键盘来做出选择,具体描述见下表:
操作
鼠标动作
键盘动作
选择单行
单击
上下光标键
延伸的连续选择
Shift + 单击 或者在表格行上拖动
Shift + 上下光标键
添加行选择/切换行选择
Ctrl + 单击
移动控制向上箭头或下箭头选择控制铅,然后使用空格键添加到选择或控制,空格键切换行选择。
要查看选择行是如何执行的,请点击
Launch 以使用
Java™ Web Start 来运行
TableSelectionDemo.java,或者由你自己来编译运行这個
例子。
这個样例程序展示了相似的表格,允许用户操纵特定的 JTable 选项。它还有壹個文本面板记录选择事件。在下方的截图中,壹個用户运行程序,单击第壹行,然后 Ctrl + 单击第三行,注意点击的最后壹個单元格周围的轮廓,这就是突出率先选择的金属外观和感觉。
在"Selection Mode"下方有几個单选按钮,点击标签是"Single Selection"的按钮。现在你可以每次只选择壹行了。如果你点击标签是"Single Interval Selection"的单选按钮,你可以选择连续的壹组行记录。所有的"Selection Mode"下方的单选按钮都调用了方法 JTable.setSelectionMode 这個方法只接受壹個参数,且必须是类 javax.swing.ListSelectionModel 中的常量值之壹,如下所示:MULTIPLE_INTERVAL_SELECTION,SINGLE_INTERVAL_SELECTION 还有 SINGLE_SELECTION。
回到 TableSelectionDemo,注意在"Selection Options"下方的三個复选框,每個复选框控制壹個 boolean 型的由 JTable 定义的绑定变量:
"行选择" 控制行选择,对应的有两個方法 setRowSelectionAllowed() 和 getRowSelectionAllowed()。当这個绑定属性为 true,并且 columnSelectionAllowed 的属性值为 false 时,用户可以选择行记录;
"列选择" 控制列选择,对应的有两個方法 setColumnSelectionAllowed() 和 getColumnSelectionAllowed()。当这個绑定属性为 true,并且 rowSelectionAllowed 绑定属性为 false 时,用户可以选择列记录;
"单元格选择" 控制单元格选择,对应的有两個方法 setCellSelectionEnabled() 和 getCellSelectionEnabled()。当这個绑定属性为 true 时,用户可以选择单個单元格或者矩形块状的单元格; 注意:JTable 使用非常简单的选择概念管理行和列的交叉点,
它不是设计来处理完全独立的单元格选择的。
如果你清除所有的三個复选框,将三個绑定属性设置为 false,那麽就不会有选择。只有高亮元素显示。
你可能会注意到在间隔选择模式下 "Cell Selection" 复选框被禁用。这是因为在演示中,不支持这种模式下的单元格选择。你可以在间隔选择模式下指定单元格的选择,但是结果集是壹個不会产生任何有效选择的表格。
你同样可能注意到更改任意三個选项都会影响到其它选项,这是因为同时允许行选择和列选择和允许单元格选择完全壹样,JTable 自动更新了三個绑定变量以保持它们的壹致性。
注意:设置 cellSelectionEnabled 到某個值会对 rowSelectionEnabled 和 columnSelectionEnabled 有边缘影响,它们也会被设置为这個值。同时设置 rowSele