12.11.5 绘制单元格内容
12.11.5 绘制单元格内容
前面看到的所有表格的单元格内容都是字符串,实际上表格的单元格内容也可以是更复杂的内容,JTable
使用TableCellRenderer
绘制单元格,Swing
为该接口提供了一个实现类:DefaultTableCellRenderer
,该单元格绘制器可以绘制如下三种类型的单元格值(根据其TableModel
的getColumnClass
方法来决定该单元格值的类型)。
Icon
:默认的单元格绘制器会把该类型的单元格值绘制成该Icon
对象所代表的图标。Boolean
:默认的单元格绘制器会把该类型的单元格值绘制成复选按钮Object
:默认的单元格绘制器在单元格内绘制出该对象的toString()
方法返回的字符串
在默认情况下,如果程序直接使用二维数组或Vector
来创建JTable
,程序将会使用JTable
的匿名内部类或DefaultTableModel
充当该表格的mode
对象,这两个TableModel
的getColumnClass
方法的返回值都是Object
。这意味着,即使该二维数组里值的类型是Icon
,但由于两个默认的TableModel
实现类的getColumnClass
方法总是返回Object
,这将导致默认的单元格绘制器把Icon
值当成Object
值处理——只是绘制出其toString
方法返回的字符串。
为了让默认的单元格绘制器可以将Icon
类型的值绘制成图标,把Boolean
类型的值绘制成复选框,创建JTable
时所使用的TableModel
绝不能采用默认的TableModel
,必须采用扩展后的TableModel
类,如下所示。
1 | //定义一个DefaultTableCellRenderer类的子类 |
提供了上面的ExtendedTableModel
类之后,程序应该先创建ExtendedTableModel
对象,再利用该对象来创建Table
,这样就可以保证JTable
的model
对象的getColumnClass
方法会返回每列真实的数据类型,默认的单元格绘制器就会将Icon
类型的单元格值绘制成图标,将Boolean
类型的单元格值绘制成复选框。
自定义表格单元格绘制器
如果希望程序采用自己定制的单元格绘制器,则必须实现自己的单元格绘制器,单元格绘制器必须实现TableCellRenderer
接口。与前面的TreeCellRenderer
接口完全相似,该接口里也只包含一个getTableCellrendererComponent()
方法,该方法返回的Component
将会作为指定单元格绘制的组件。
单元格绘制器模型
Swing
提供了一致的编程模型,不管是JList
、JTree
还是JTable
,它们所使用的单元格绘制器都有一致的编程模型,分别需要扩展ListCellRenderer
、TreeCellRenderer
或TableCellRenderer
,扩展这三个基类时都需要重写getXxeCellRendererComponent()
方法,该方法的返回值将作为被绘制的组件
单元格绘制器的两种方式
一旦实现了自己的单元格绘制器之后,还必须将该单元格绘制器安装到指定的JTable
对象上,为指定的JTable
对象安装单元格绘制器有如下两种方式。
- 局部方式(列级):调用
TableColumn
的setCellRenderer()
方法为指定列安装指定的单元格绘制器 - 全局方式(表级):调用
JTable
的setDefaultRenderer()
方法为指定的JTable
对象安装单元格绘制器。setDefaultRenderer()
方法需要传入两个参数,即列类型和单元格绘制器,表明指定类型的数据列才会使用该单元格绘制器。
局部绘制器优先级更高
当某一列既符合全局绘制器的规则,又符合局部绘制器的规则时,局部绘制器将会负责绘制该单元格,全局绘制器不会产生任何作用。
列头单元格绘制器
除此之外,TableColumn
还包含了一个setHeaderRenderer()
方法,该方法可以为指定列的列头安装单元格绘制器。
程序
下面程序提供了一个ExtendedTablemodel
类,该类扩展了DefaultTableModel
,重写了父类的getColumnClass()
方法,该方法根据每列的第一个值来决定该列的数据类型;下面程序还提供了一个定制的单元格绘制器,它使用图标来形象地表明每个好友的性别
1 | import java.awt.*; |
上面程序中没有直接使用二维数组和一维数组来创建JTable
对象,而是采用ExtendedTableModel
对象来创建JTable
对象(如第一段粗体字代码所示)。ExtendedTableModel
类重写了父类的getColumnClass
方法,该方法将会根据每列实际的值来返回该列的类型(如第二段粗体字代码所示)。
程序提供了一个GenderTableCellRenderer
类,该类实现了Tablecellrenderer
接口,可以作为单元格绘制器使用。该类继承了JPanel
容器,重写getTableCelIRendererComponent()
方法时返回this
,这表明它会使用JPanel
对象作为单元格绘制器。
读者可以将ExtendedTableModel
补充得更加完整——主要是将DefaultTableModel
中的几个构造器重新暴露出来,以后程序中可以使用ExtendedTablemodel
类作为JTable
的model
类,这样创建的JTable
就可以将Icon
列、Boolean
列绘制成图标和复选框。
运行上面程序,会看到如图12.54所示的效果。