Posted on 2010-08-24 11:39
TWaver 阅读(1436)
评论(2) 编辑 收藏
renderer和editor的机制的掌握对于能否灵活深入使用Swing、Flex、Silverlight包括Web组件尤为重要,但renderer和editor的机制对于初学者而已的确有一定的门槛,甚至可以说有相当的UI开发者纵使简历上赫然写着具备N年UI开发经验,当你面试问及renderer和editor原理是很多人是一头雾水,更有甚者会反过来问你啥叫“renderer”?啥叫“editor”?即使听过的大部分也是一知半解,他会敷衍的回答:“不就是表格上的那个什么什么..”,更别提现场让他写个哪怕是bool的check类型的renderer和edtior。
如果作为interviewer哪天你有幸遇到一位能和你深入讨论如何让tree、combobox、list和table的renderer进行代码复用,如何让renderer对象实例进行复用以及复用需要注意的副作用时,我强烈建议你赶紧留着此人,这种人已是稀有物种了。
言归正传,以下通过Swing的表格为例通过几个例子帮助大家理解:
TableCellRenderer就是用来绘制展示当前cell单元数值内容的,你可以用文字、数值或者图片来表示内容,当然最强大展示方式的就是通过自定义自己的renderer组件,通过Java2D来绘制各种天花乱坠的效果。
TableCellEditor主要是用来当用户点击在具体cell时进行编辑的组件,所以TableCellEditor除了具有TableCellRenderer一样的绘制功能外还可以进行交互动作,例如在cell上出现下拉框、勾选框甚至通过按钮弹出更复杂的对话框让用户进行输入编辑。
以下是在cell中嵌入start、stop两个按钮的表格,注意这里的renderer只是用来显示效果,并没有进行交互动作,真正进行动作的是当你将鼠标点击在cell上时,JTable定位上去的editor,所以不要徒劳在renderer上做点击事项处理,renderer是不会接受到交互事项的,renderer只是个画笔,你看到的start、stop按钮只是这个画笔画出来的内容,是虚的并没有真正的组件在上面。
1
import java.awt.*;
2
import java.awt.event.*;
3
import javax.swing.*;
4
import javax.swing.table.*;
5
public class TableTest1 extends JFrame
{
6
JTable table;
7
String[] states = new String[]
{"stop", "stop", "stop"};
8
9
// model
10
class TableModel extends AbstractTableModel
{
11
public int getColumnCount()
{
12
return 2;
13
}
14
public int getRowCount()
{
15
return states.length;
16
}
17
public Object getValueAt(int rowIndex, int columnIndex)
{
18
if(columnIndex == 0)
{
19
return states[rowIndex];
20
}
21
return null;
22
}
23
public String getColumnName(int columnIndex)
{
24
if(columnIndex == 0)
{
25
return "state";
26
}else
{
27
return "operate";
28
}
29
}
30
public boolean isCellEditable(int rowIndex, int columnIndex)
{
31
if(columnIndex == 0)
{
32
return false;
33
}else
{
34
return true;
35
}
36
}
37
}
38
39
// cell editor
40
class Editor extends AbstractCellEditor implements TableCellEditor, ActionListener
{
41
int row;
42
JTable table;
43
JPanel panel;
44
JButton start;
45
JButton stop;
46
Editor()
{
47
panel = new JPanel();
48
panel.setLayout(new GridLayout(1, 2));
49
start = new JButton("start");
50
stop = new JButton("stop");
51
start.addActionListener(this);
52
stop.addActionListener(this);
53
panel.add(start);
54
panel.add(stop);
55
}
56
public Object getCellEditorValue()
{
57
return null;
58
}
59
public Component getTableCellEditorComponent(JTable table,
60
Object value,
61
boolean isSelected,
62
int row,
63
int column)
{
64
this.table = table;
65
this.row = row;
66
return panel;
67
}
68
69
public void actionPerformed(ActionEvent e)
{
70
if(e.getSource() == start)
{
71
states[row] = "start";
72
}else
{
73
states[row] = "stop";
74
}
75
((AbstractTableModel)table.getModel()).fireTableCellUpdated(row, 0);
76
}
77
78
}
79
80
// cell render
81
class Renderer extends JComponent implements TableCellRenderer
{
82
JPanel panel;
83
JButton start;
84
JButton stop;
85
Renderer()
{
86
panel = new JPanel();
87
panel.setLayout(new GridLayout(1, 2));
88
start = new JButton("start");
89
stop = new JButton("stop");
90
panel.add(start);
91
panel.add(stop);
92
}
93
public Component getTableCellRendererComponent(JTable table, Object value,
94
boolean isSelected, boolean hasFocus, int row, int column)
{
95
return panel;
96
}
97
}
98
99
public TableTest1()
{
100
super("renderer and editor self-existent");
101
table = new JTable(new TableModel());
102
TableColumn tableColumn = table.getColumnModel().getColumn(1);
103
tableColumn.setCellRenderer(new Renderer());
104
tableColumn.setCellEditor(new Editor());
105
106
this.getContentPane().setLayout(new BorderLayout());
107
this.getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
108
this.setSize(500, 300);
109
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
110
}
111
public static void main(String[] args)
{
112
new TableTest1().show();
113
}
114
}
