目录[-]
使用 JTable 类你可以显示表中的数据,也可以允许用户编辑表中的数据,JTable 不包含数据,也不缓存数据,它只是你的数据的壹個视图,下图是一个在滚动窗格中显示的一个典型的表格:
本节的其余部分告诉你如何完成一些表格相关的常用任务。
1
|
String[] columnNames = {
"First Name"
,
"Last Name"
,
"Sport"
,
"# of Years"
,
"Vegetarian"
};
|
它的数据被初始化并且存储在壹個二维的对象数组中:
1
2
3
4
5
6
7
|
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
)}
};
|
1
|
JTable table =
new
JTable(data, columnNames);
|
壹共有两個 JTable 构造方法直接接受数据,SimpleTableDemo 使用第壹种:
1
2
|
JTable(Object[][] rowData, Object[] columnNames)
JTable(Vector rowData, Vector columnNames)
|
如下是壹段典型的创建壹個卷动窗格作为表格的容器的代码:
1
2
|
JScrollPane scrollPane =
new
JScrollPane(table);
table.setFillsViewportHeight(
true
);
|
1
2
3
|
container.setLayout(
new
BorderLayout());
container.add(table.getTableHeader(), BorderLayout.PAGE_START);
container.add(table, BorderLayout.CENTER);
|
默认情况下,表中所有的列开始时都是等宽的,并且所有的列会自动填充表格的整個宽度。当表格变宽或者变窄(当用户调整包含表格的窗口时会发生),所有的列宽会自动适应变化。
当用户通过拖动列的右边缘来调整列宽度时,其它列必须改变宽度,或者表格的宽度也必须改变。默认情况下,表格的宽度会保持原样,所有拖拽点右左边的列会调整以适应右边的空间增大,所有拖拽点左边的列会调整以适应左边的空间减少。
如果希望自定义初始的列宽,对于你的表格中的每壹列,你可以调用 setPreferredWidth 方法来进行设置。这会设置推荐宽度和他们的近似相对宽度。比如说:增加如下代码到 SimpleTableDemo 会让第三列比其它列要宽壹些。
1
2
3
4
5
6
7
8
9
|
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
);
}
}
|
在这個默认配置下,表格支持选择壹行或者多行,用户可以选择连续的几行。最后一个单元格指示的用户得到一个特殊的迹象,在金属的视觉上看,这個元素超出了轮廓,它有时被称作焦点元素或者当前元素,用户使用鼠标或者键盘来做出选择,具体描述见下表:
操作 |
鼠标动作 |
键盘动作 |
选择单行 |
单击 |
上下光标键 |
延伸的连续选择 |
Shift + 单击 或者在表格行上拖动 |
Shift + 上下光标键 |
添加行选择/切换行选择 |
Ctrl + 单击 |
移动控制向上箭头或下箭头选择控制铅,然后使用空格键添加到选择或控制,空格键切换行选择。 |
这個样例程序展示了相似的表格,允许用户操纵特定的 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 自动更新了三個绑定变量以保持它们的壹致性。
注意:设置 cellSelectionEnabled 到某個值会对 rowSelectionEnabled 和 columnSelectionEnabled 有边缘影响,它们也会被设置为这個值。同时设置 rowSelectionEnabled 和 columnSelectionEnabled 到某個值同样对 cellSelectionEnabled 有边缘影响,它也会被设置为那個值。设置 rowSelectionEnabled 和 columnSelectionEnabled 为不同的值会对 cellSelectionEnabled 有边缘影响,它会被设置为 false。
为了获取当前选择,使用 JTable.getSelectedRows 会返回选择的所有行下标,使用 JTable.getSelectedColumns 会返回所有的列下标。 要检索率先选择的坐标,参照表和表的列模型的选择模型。下面的代码格式化包含率先选择的行和列的字符串:
1
|
String.format(
"Lead Selection: %d, %d. "
, table.getSelectionModel().getLeadSelectionIndex(), table.getColumnModel().getSelectionModel().getLeadSelectionIndex());
|
使用选择功能生成壹系列的事件。请参考 编写事件监听器 课程的 如何编写壹系列选择事件监听器 这壹节。
注意:选择数据实际描述为在视图中选择单元格 (表格数据就像它排序或者过滤之后显示出来的壹样) 而不是选择表格的 Model。这個区别不会影响你,除非你查看重新排列的数据,包括排序,过滤或者用户操作过的行。在这种情况下,你必须使用在排序和过滤中提到的转换方法转换选择坐标。
每個表对象使用壹個 table model 对象来管理实际的表数据。table model 对象必须实现 TableModel 接口。如果开发人员不提供 table model 对象的定义,那么 JTable 会自动创建壹個 DefaultTableModel 类的实例,这种关系如下图所示。
用 SimpleTableDemo 作为 table model 构造 JTable 表格的示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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);
}
}
|
这個表格与 SimpleTableDemo 在如下几個地方存在不同点:
1、TableDemo 的自定义 table model 哪怕很简单,它也可以决定数据的类型,帮助 JTable 以更好的格式展示数据。从另壹方面讲,SimpleTableDemo 自动创建的 table model 并不知道列 # of Years 包含靠右对齐的数字,并且具有特殊的格式。它不知道列 Vegerarian 包含布尔型值,可以将其展示成复选框。
2、在 TableDemo 中实现的自定义 table model 不允许你编辑姓名列,然而它允许你编辑其它列。在 SimpleTableDemo 中,所有的元素都是可以编辑的。
可以看到来自 TableDemo.java 的如下代码和来自 SimpleTableDemo.java 的不壹样。黑体字显示创建表格的 model 与为创建 SimpleTableDemo 而自动生成的 table model 不壹样。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
public
TableDemo() {
...
JTable table =
new
JTable(
new
MyTableModel());
...
}
class
MyTableModel
extends
AbstractTableModel {
private
String[] columnNames = ...
//和以前壹样
private
Object[][] data = ...
//和以前壹样
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];
}
public
Class getColumnClass(
int
c) {
return
getValueAt(
0
, c).getClass();
}
//如果你的表格不可编辑就不要实现这個方法
public
boolean
isCellEditable(
int
row,
int
col) {
return
col >=
2
;
}
//如果你的表格中的数据不改变,则不需要实现这個方法
public
void
setValueAt(Object value,
int
row,
int
col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
...
}
|
当表格中的数据发生改变时,每個 table model 都可以有壹系列的监听器,监听器都是 TableModelListener 的实例。在如下代码中,SimpleTableDemo 继承了这样壹個监听器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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);
...
//对数据做壹些事情...
}
...
}
|
为了发起数据更新的事件,table model 必须知道如何创建壹個 TableModelEvent 对象。这可以是壹個复杂的过程,但是它现在已经在 DefaultTableModel 中实现了。你既可以允许 JTable 使用默认的DefaultTableModel 实例,也可以创建你自己的 DefaultTableModel 的自定义的子类。我的理解,发起数据更新事件的含义就是,当数据改变时,通知所有相关的监听器,让它们知道某行某列的数据发生了改变,就是这样。如果 DefaultTableModel 对于你自定义的 table model 类而言不适用,你就可以考虑继承 AbstractTableModel 类实现壹個子类。这個类为创建 TableModelEvent 对象实现了壹個简单的框架。你的自定义类只需要在每次表数据被外部源改变时,简单的调用如下的 AbstractTableModel 方法。
方法名 |
发生的变化 |
fireTableCellUpdated(int row, int column) |
更新了某個单元格,其坐标为(row, column) |
fireTableRowsUpdated(int firstRow, int lastRow) |
更新了从 firstRow 到 lastRow 的行记录,包括 firstRow 和 lastRow |
fireTableDataChanged() |
更新了整個表格中的数据 |
fireTableRowsInserted(int firstRow, int lastRow) |
在行的范围[firstRow, lastRow]内已经插入新的数据,包含 firstRow 和 lastRow |
fireTableRowsDeleted(int firstRow, int lastRow) |
在行范围[firstRow, lastRow]内存在的行被删除了,包含 firstRow 和 lastRow |
fireTableStructureChanged() |
整個表格失效,包括表中的数据和表的结构 |
在你开始继续接下来几個任务之前,你需要理解表格是如何画出它们的单元格。你可能期望每個表格中的单元格都是壹個组件。然而,出于性能方面考虑,Swing 的表格的实现是不壹样的。
相反,单独壹個单元格渲染器通常可以用来画出所有的包含相同数据类型的单元格。你可以将渲染器想象成壹個可配置的墨水印章,表格使用它来给适当格式化的数据盖章。当用户开始编辑单元格中的数据时,壹個单元格渲染器接手单元格,控制单元格的编辑行为。
举例来说,TableDemo 中的每個# of Years 列的单元格包含 Number 型数据,比较特殊,是 Integer 对象。默认情况下,单元格渲染器对于壹個包含数字的列,在每個列中的单元格上都使用壹個 JLable 实例来画出合适的数字,靠右对齐。如果用户开始编辑其中壹個单元格,默认的单元格编辑器使用靠右对齐的 JTextField 来控制单元格的编辑。
为了选择渲染器来显示列中的单元,你首先需要决定表格是否需要为特定的列使用特定的渲染器。如果不需要,那么表格调用 table model 的 getColumnClass 方法,后者将会获取列中元素的数据类型,下壹步,表格中列的数据类型与壹個数据类型列表比较,数据类型列表中的元素渲染器已经注册过。这個列表由表格来完成初始化,但是你可以增加或者改变它。目前,表格将如下类型的数据放进列表中:
1
2
3
4
5
6
|
Boolean — 被渲染成壹個复选框;
Number — 被渲染成壹個靠右对齐的标签;
Double, Float — 和 Number 类型壹样,但是壹個 NumberFormat 实例会完成对象到文本的转换,针对当前语言使用默认的数字格式;
Date — 被渲染成壹個标签,但是壹個 DateFormat 实例会完成对象到文本的转换,针对时间和日期使用壹种简短的风格;
ImageIcon, Icon — 被渲染成壹個居中对齐的标签;
Object — 被渲染成壹個显示对象的字符串值的标签;
|
单元格编辑器的选择使用类似的算法。
记住,如果你允许壹個表格使用它自己的 model ,它就会使用 Object 作为每個列的类型。为了指定更加精确的列类型,table model 必须定义恰当的 getColumnClass() 方法。就像 TableDemo.java 的演示代码那样。牢记尽管渲染器决定每個单元格或者列头部如何展示,以及它们的 tool tip 文本是什么,但是渲染器不处理事件。如果你需要获取发生在表格中的事件,你需要使用技术不同的你感兴趣的事件排序:
情况 |
如何获取事件 |
检测单元格被编辑的事件 |
使用单元格编辑器,或者在单元格编辑器上注册壹個监听器 |
检测行、列或者单元格的选择与反选事件 |
使用 Detecting User Selections 中提到的选择监听器 |
在列的头部检测鼠标事件 |
在表格的 JTableHeader 对象中注册 mouse listener 的合适类型。请查阅 TableSorter.java 中的实例。 |
检测其它事件 |
为 JTable 对象注册合适的监听器 |
这壹章节告诉我们如何创建和指定壹個单元格的渲染器。你可以使用 JTable 的方法 setDefaultRenderer() 来设置壹個指定类型的单元格渲染器。为了让某個特殊列里面的单元格使用指定的渲染器,你可以使用 TableColumn 的 setCellRenderer() 方法。你甚至可以通过创建 JTable 的子类来指定壹個特定于单元格的渲染器。
使用 DefaultTableCellRenderer 可以很容易的自定义文本或者图片的默认渲染器,你只需要创建壹個子类并且实现 setValue() 方法以便它可以使用合适的字符串或者图片来调用 setText() 或者 setIcon() 方法。举個例子,这里是壹個默认的日期类渲染器的实现:
1
2
3
4
5
6
7
8
9
10
11
|
static
class
DateRenderer
extends
DefaultTableCellRenderer {
DateFormat formatter;
public
DateRenderer() {
super
(); }
public
void
setValue(Object value) {
if
(formatter==
null
) {
formatter = DateFormat.getDateInstance();
}
setText((value ==
null
) ?
""
: formatter.format(value));
}
}
|
如果扩展 DefaultTableCellRenderer 还不够,你可以使用另外壹個子类创建壹個渲染器。最简单的方法就是创建壹個已经存在的组件的子类,实现 TableCellRenderer 接口来创建你自己的子类。TableCellRenderer 只需要实现壹個方法:getTableCellRendererComponent()。你对这個方法的实现应该设置渲染组件,以反映传入的状态,然后返回组件。
在 TableDialogEditDemo 的截图中,用于 Favorite Color 单元格上的渲染器是壹個 JLabel 的子类,被称作 ColorRenderer。这里有壹個来自于 ColorRenderer.java的片段用于展示它是如何实现的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
public
class
ColorRenderer
extends
JLabel
implements
TableCellRenderer {
...
public
ColorRenderer(
boolean
isBordered) {
this
.isBordered = isBordered;
//将背景设置为不透明,为了能够显示出来必须这样做
setOpaque(
true
);
}
public
Component getTableCellRendererComponent(
JTable table, Object color,
boolean
isSelected,
boolean
hasFocus,
int
row,
int
column) {
Color newColor = (Color)color;
setBackground(newColor);
if
(isBordered) {
if
(isSelected) {
...
//selectedBorder 是颜色的固定边缘
//table.getSelectionBackground().
setBorder(selectedBorder);
}
else
{
...
//unselectedBorder 是颜色的固定边缘
//table.getBackground().
setBorder(unselectedBorder);
}
}
setToolTipText(...);
//留待后继讨论
return
this
;
}
}
|
1
|
table.setDefaultRenderer(Color.
class
,
new
ColorRenderer(
true
));
|
1
2
3
4
5
6
7
8
9
10
|
TableCellRenderer weirdRenderer =
new
WeirdRenderer();
table =
new
JTable(...) {
public
TableCellRenderer getCellRenderer(
int
row,
int
column) {
if
((row ==
0
) && (column ==
0
)) {
return
weirdRenderer;
}
// else...
return
super
.getCellRenderer(row, column);
}
};
|
默认情况下,显示在表中单元格上的工具提示文本由单元格的渲染器决定。然而,有时候通过重载 JTable 的实现中的 getToolTipText(MonseEvent e) 方法可以更加简单指定工具提示文本。这壹章节向你展示如何使用这两個技术。
为了在壹個单元格的渲染器上增加工具提示,你首先需要获得或者创建壹個单元格渲染器。然后,确保渲染器组件是壹個 JComponent,调用它的 setToolTipText() 方法即可。
TableRenderDemo 中有壹個为单元格设置工具提示的例子。点击这里可以运行该样例代码,当然你也可以自己编译运行它的源代码。它使用如下代码在 Sport 列中为单元格添加了工具提示:
1
2
3
|
DefaultTableCellRenderer renderer =
new
DefaultTableCellRenderer();
renderer.setToolTipText(
"Click for combo box"
);
sportColumn.setCellRenderer(renderer);
|
虽然上個例子里的工具提示文本样例是静态的,但是你也可以实现随着单元格状态改变而改变的工具提示文本程序,这里有两种实现的方法:
1、在渲染器的 getTableCellRendererComponent() 方法实现中增加壹些代码;
2、重载 JTable 的 getToolTipText(MonseEvent e)方法;
壹個在单元格渲染器中添加代码的例子是 TableDialogEditDemo。点击启动按钮可以运行这個例子,或者你也可以自行编译运行这個例子。TableDialogEditDemo 使用了壹個用于颜色的渲染器,并且在 ColorRender.java 中实现了它。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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
;
}
}
|
通过重载 JTable 的 getToolTipText(MouseEvent e) 方法你可以指定工具栏提示文本,程序 TableToolTipsDemo 展示了该如何进行。Sport 和 Vegetarian 两個列中的元素具有工具栏提示,它们的演示效果如下:
这是来自 TableToolTipsDemo 中的壹段代码,它实现了在 Sport 和 Vegetarian 列中的元素上添加工具栏提示的功能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
JTable table =
new
JTable(
new
MyTableModel()) {
//Implement table cell tool tips.
public
String getToolTipText(MouseEvent e) {
String tip =
null
;
java.awt.Point p = e.getPoint();
int
rowIndex = rowAtPoint(p);
int
colIndex = columnAtPoint(p);
int
realColumnIndex = convertColumnIndexToModel(colIndex);
if
(realColumnIndex ==
2
) {
//Sport column
tip =
"This person's favorite sport to "
+
"participate in is: "
+ getValueAt(rowIndex, colIndex);
}
else
if
(realColumnIndex ==
4
) {
//Veggie column
TableModel model = getModel();
String firstName = (String)model.getValueAt(rowIndex,
0
);
String lastName = (String)model.getValueAt(rowIndex,
1
);
Boolean veggie = (Boolean)model.getValueAt(rowIndex,
4
);
if
(Boolean.TRUE.equals(veggie)) {
tip = firstName +
" "
+ lastName
+
" is a vegetarian"
;
}
else
{
tip = firstName +
" "
+ lastName
+
" is not a vegetarian"
;
}
}
else
{
//another column
//You can omit this part if you know you don't
//have any renderers that supply their own tool
//tips.
tip =
super
.getToolTipText(e);
}
return
tip;
}
...
}
|
通过为你的表格的 JTableHeader设置工具提示文本,你可以增加壹個工具提示到列的头部。通常不同的列头部需要不同的工具提示信息。通过重载表格头的 getToolTipText() 方法你可以改变文本信息。你可以交替的调用 TableColumn.setHeaderRenderer() 方法来为表头提供自定义的渲染器。
在 TableSorterDemo.java 中有壹個为所有列的头部使用工具提示文本的例子,如下是如何设置工具提示信息的代码:
1
|
table.getTableHeader().setToolTipText(
"Click to sort; Shift-Click to sort in reverse order"
);
|
接下来的代码实现了工具提示功能,基本上,它创建了壹個 JTableHeader 的子类并且重载了 getToolTipText(MonseEvent e)方法,以便它可以为当前列返回文本。为了关联修改表的表头,JTable 中的 createDefaultTableHeader() 方法被重载了,以便它返回壹個 JTableHeader 子类的实例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
protected
String[] columnToolTips = {
null
,
// "First Name" assumed obvious
null
,
// "Last Name" assumed obvious
"The person's favorite sport to participate in"
,
"The number of years the person has played the sport"
,
"If checked, the person eats no meat"
};
...
JTable table =
new
JTable(
new
MyTableModel()) {
...
//实现表头工具栏提示
protected
JTableHeader createDefaultTableHeader() {
return
new
JTableHeader(columnModel) {
public
String getToolTipText(MouseEvent e) {
String tip =
null
;
java.awt.Point p = e.getPoint();
int
index = columnModel.getColumnIndexAtX(p.x);
int
realIndex =
columnModel.getColumn(index).getModelIndex();
return
columnToolTips[realIndex];
}
};
}
};
|
表格的排序和过滤由壹個 sorter 对象进行管理,最简单的提供 sorter 对象的方法是设置 autoCreateRowSorter 绑定属性为 true:
1
2
|
JTable table =
new
JTable();
table.setAutoCreateRowSorter(
true
);
|
这次我们定义壹個行排序 sorter,它是 javax.swing.table.TableRowSorter 的壹個实例。当用户点击列的头部时,排序工具提供给表格壹個简单的基于当地的排序。TableSortDemo.java 就是这样壹個演示的例子,下图是截屏:
要想获取更多关于排序的控制,你可以创建壹個 TableRowSorter 的实例并且指定它是你的表格中的排序对象。
1
2
|
TableRowSorter
new
TableRowSorter
table.setRowSorter(sorter);
|
1
2
3
4
5
6
7
8
|
Comparator
new
Comparator
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
]);
}
};
|
这個例子是特地简化过的;更常见情况下,Comparator 的实现是 java.text.Collator 的壹個子类。你可以有你自己的子类,使用在 Collator 类的工厂方法可以获取壹個基于本地环境的 Comparator 实例,或者使用 java.text.RuleBasedCollator 。
对于每壹列应该使用哪种 Comparator ,TableRowSorter 会尝试应用如下规则。规则会按照如下的顺序被遵循;第壹条规则如果已经使用,则后继的规则会被忽略。
1
2
3
4
5
|
1
、如果已经通过 setComparator() 指定了壹個比较器,则使用该比较器。
2
、如果 table model 已经声明列数据由字符串组成,就是说对于指定列调用 TableModel.getColumnClass() 方法返回 String.
class
,使用基于本地环境的字符串顺序进行排序。
3
|