精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|||||||
---|---|---|---|---|---|---|---|
作者 | 正文 | ||||||
发表时间:2009-02-12
最后修改:2009-05-06
Ext.ProgressColumn (在线demo 效果见下图)是Web用户界面组件包ExtJS 的一个用户扩展。本文中使用Swing组件包中JTable对ProgressColumn的特性进行了模拟,从而使其可以运行在Java平台上。并结合实例演示了如何自定义绘制器、编辑器和比较器。
环境准备
运行demo
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<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()); sorter.setComparator(5, new ProgressComparator()); table.setRowSorter(sorter); 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|||||||
返回顶楼 | |||||||
发表时间:2009-03-07
楼主 太感谢了!
|
|||||||
返回顶楼 | |||||||
发表时间:2009-03-07
正在研究这方面的东西啊
|
|||||||
返回顶楼 | |||||||
发表时间:2009-05-06
第一个图是WEB还是Swing?
|
|||||||
返回顶楼 | |||||||
发表时间:2009-05-06
web。extjs-grid组件的扩展
EdwardWorld 写道 第一个图是WEB还是Swing?
|
|||||||
返回顶楼 | |||||||
发表时间:2009-08-21
感谢楼主,一个很不错的Demo!
想请教一下,我想对JTable单元格中的某几个字进行高亮,不知道楼主有什么高招? |
|||||||
返回顶楼 | |||||||
发表时间:2009-08-21
最后修改:2009-08-21
推荐你看一下swingx。swing的做法就是去自定义一个绘制器,然后setColor。但是swingx作者不推荐这么做,他推荐用Highlighter。我写一小段代码: Object rows[][] = {{"Ming", "Xu Da", "38"}, {"Wu", "Zhang Shicheng", "46"}, {"Ming", "Zhu Chongba", "34"}, {"Han", "Chen Youliang", "37"}, {"Ming", "Zhu Wenzheng", "14"}, {"Ming", "Li Shanchang", "14"}}; Object columns[] = {"Symbol", "Name", "Age"}; JXTable table = new JXTable(rows, columns); Pattern p = Pattern.compile("Ming"); PatternPredicate pp = new PatternPredicate(p, 0, 0); table.addHighlighter(new ColorHighlighter(pp, null, Color.RED)); 简单说一下:
line 10——构造方法的签名为PatternPredicate(Pattern pattern, int testColumn, int decorateColumn)。参数1是正则表达式、参数2是正则表达式要匹配的column、参数3是要修饰的column(如果不给这个参数就修饰整行)。 line 11——构造方法的签名为ColorHighlighter(HighlightPredicate predicate, Color cellBackground, Color cellForeground)。参数2是背景色、参数3是前景色。
|
|||||||
返回顶楼 | |||||||
发表时间:2009-08-25
最后修改:2009-08-25
谢谢楼主提供方法,我的问题已经就解决了。
用swing也是可以解决,我查API的时候发现 javax.swing.JLabel |_javax.swing.table.DefaultTableCellRenderer 所以可以这样来特殊显示 Object rows[][] = {{"<html><u>Ming</u></html>", "Xu Da", "38"}, {"Wu", "Zhang Shicheng", "46"}, {"Ming", "Zhu Chongba", "34"}, {"Han", "Chen Youliang", "37"}, {"Ming", "Zhu Wenzheng", "14"}, {"Ming", "Li Shanchang", "14"}}; |
|||||||
返回顶楼 | |||||||
浏览 5319 次