Ext.ProgressColumn的Swing实现——略论JTable的绘制器、编辑器、比较器

Ext.ProgressColumn (在线demo 效果见下图)是Web用户界面组件包ExtJS 的一个用户扩展。本文中使用Swing组件包中JTable对ProgressColumn的特性进行了模拟,从而使其可以运行在Java平台上。并结合实例演示了如何自定义绘制器、编辑器和比较器。


 

环境准备

 

软件或资源 要求的版本
Java Development Kit (JDK) 6.0(5.0不行、因为要用比较器)
NetBeans IDE 6.5

 

运行demo

  1. 从附件中下载jtable_with_progresscolumn.zip到本地并解压。
  2. NetBeans主菜单依次选择“文件”——“打开项目”。
  3. 在弹出的“打开项目”对话框中选择刚才解压之后的jtable_with_progresscolumn目录,点击“打开项目”按钮。
  4. 在“项目”视图中找到jtable_with_progresscolumn项目,在上下文菜单中点击“运行”。
  5. 点一下“Growth”列的表头,正序排列;再点一下,逆序排列。
  6. 双击“Growth”列第1行的单元格。最终结果如图所示:

 

ProgressColumn的特性列表

  1. ProgressColumn的单元格,以一个进度条来直观的表现0到100的整数值。当取值在0-33时为红色、34-66时为黄色、67-100时为绿色。
  2. 单击ProgressColumn列的表头,可以对该列按正序、逆序排列。
  3. 双击ProgressColumn列的单元格,在自定义编辑器中输入一个整数值来改变对应进度条的刻度。

自定义绘制器

 

绘制器的现代UI技术中常用的概念,很多优秀的组件库(比如ExtJS和Swing)对其都有很好的实现。什么是绘制器呢?对于JList、JTable、JTree这样的复杂组件,其单元的绘制是交给另一个对象来完成的,这个对象叫做绘制器。

 

回到JTable的自定义绘制器问题上来,它被定义为一个叫做TableCellRenderer的接口,这个接口只有定义了一个方法:

 

public Component getTableCellRendererComponent(JTable table, Object value, 
          boolean isSelected, boolean hasFocus, int row, int column)

 

各位看官可能要说了,这也忒麻烦了。还好,Swing以DefaultTableCellRenderer类的方式提供了一个缺省的绘制器,它扩展JLabel并实现了TableCellRenderer接口。

 

具体到我们上面这张图来说,“Common Name”这一列在Model中是String类型(准确地说是Object),在界面中绘制为一个JLabel来显示字符串(Object的toString方法);"Indoor?"这一列在Model中是Boolean类型,它不用DefaultTableCellRenderer,而是调用一个继承自JCheckbox的专用绘制器类。

 

“Growth”这一列需要自定义绘制器:一是Model中该列对应的是我们自定义的Progress类型,缺省绘制器不认识它。二是需要重写paint方法来重绘JLabel(恩,这个进度条是用2D API画的)。

 

如果我们对某一列使用ProgressColumn的话,首先把该列指定为Progress类型,然后用以下代码给Progress类型绑定我们自定义的绘制器ProgressRenderer。

 

table.setDefaultRenderer(Progress.class, new ProgressRenderer());

 

自定义编辑器

 

编辑器是与绘制器紧密相关的一个概念,而且复杂度要高很多。别担心,我不会大讲特讲编辑器的概念(困了),因为这个demo里使用的只是最简单的自定义编辑器(看ProgressEditor行数就知道了)。

 

为什么这么少?你猜对了,JTable也有一个缺省编辑器,不过它的名字不是DefaultTableCellEditor,而是DefaultCellEditor(因为JTree也用它)。我们就是在它的基础上做一些小扩展:一是加上红色边框;二是由于我们自定义了Progress类型,将原来的值设置到JTextField中就需要做一点小处理。代码如下:

 

jtf.setText((value != null) ? value.toString() : "");   //  将原来的值设置到JTextField中
jtf.setBorder(new LineBorder(Color.RED, 2));    //  设置红色边框

 

然后用以下代码给Progress类型绑定自定义的编辑器ProgressEditor。

 

table.setDefaultEditor(Progress.class, new ProgressEditor(new JTextField()));

 

自定义比较器

 

由于JDK 6.0之前JTable是没有列排序API的,所以也谈不到比较器的问题。不过现在既然可以排序了,那么我们要对自定义的Progress给出一个比较器,也就是实现java.util.Comparator接口。然后给Progress类型绑定自定义的比较器ProgressComparator。

 

TableRowSorter sorter = new TableRowSorter(table.getModel());
sorter.setComparator(5, new ProgressComparator());
table.setRowSorter(sorter);

你可能感兴趣的:(Java,Swing,Swing,EXT,正则表达式,Netbeans,Web)