Posted on 2010-08-24 11:39
TWaver 阅读(1434)
评论(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按钮只是这个画笔画出来的内容,是虚的并没有真正的组件在上面。
1import java.awt.*;
2import java.awt.event.*;
3import javax.swing.*;
4import javax.swing.table.*;
5public 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}