Posted on 2010-08-24 11:39
TWaver 閱讀(1444)
評(píng)論(2) 編輯 收藏
renderer和editor的機(jī)制的掌握對(duì)于能否靈活深入使用Swing、Flex、Silverlight包括Web組件尤為重要,但renderer和editor的機(jī)制對(duì)于初學(xué)者而已的確有一定的門檻,甚至可以說(shuō)有相當(dāng)?shù)腢I開發(fā)者縱使簡(jiǎn)歷上赫然寫著具備N年UI開發(fā)經(jīng)驗(yàn),當(dāng)你面試問(wèn)及renderer和editor原理是很多人是一頭霧水,更有甚者會(huì)反過(guò)來(lái)問(wèn)你啥叫“renderer”?啥叫“editor”?即使聽過(guò)的大部分也是一知半解,他會(huì)敷衍的回答:“不就是表格上的那個(gè)什么什么..”,更別提現(xiàn)場(chǎng)讓他寫個(gè)哪怕是bool的check類型的renderer和edtior。
如果作為interviewer哪天你有幸遇到一位能和你深入討論如何讓tree、combobox、list和table的renderer進(jìn)行代碼復(fù)用,如何讓renderer對(duì)象實(shí)例進(jìn)行復(fù)用以及復(fù)用需要注意的副作用時(shí),我強(qiáng)烈建議你趕緊留著此人,這種人已是稀有物種了。
言歸正傳,以下通過(guò)Swing的表格為例通過(guò)幾個(gè)例子幫助大家理解:
TableCellRenderer就是用來(lái)繪制展示當(dāng)前cell單元數(shù)值內(nèi)容的,你可以用文字、數(shù)值或者圖片來(lái)表示內(nèi)容,當(dāng)然最強(qiáng)大展示方式的就是通過(guò)自定義自己的renderer組件,通過(guò)Java2D來(lái)繪制各種天花亂墜的效果。
TableCellEditor主要是用來(lái)當(dāng)用戶點(diǎn)擊在具體cell時(shí)進(jìn)行編輯的組件,所以TableCellEditor除了具有TableCellRenderer一樣的繪制功能外還可以進(jìn)行交互動(dòng)作,例如在cell上出現(xiàn)下拉框、勾選框甚至通過(guò)按鈕彈出更復(fù)雜的對(duì)話框讓用戶進(jìn)行輸入編輯。
以下是在cell中嵌入start、stop兩個(gè)按鈕的表格,注意這里的renderer只是用來(lái)顯示效果,并沒(méi)有進(jìn)行交互動(dòng)作,真正進(jìn)行動(dòng)作的是當(dāng)你將鼠標(biāo)點(diǎn)擊在cell上時(shí),JTable定位上去的editor,所以不要徒勞在renderer上做點(diǎn)擊事項(xiàng)處理,renderer是不會(huì)接受到交互事項(xiàng)的,renderer只是個(gè)畫筆,你看到的start、stop按鈕只是這個(gè)畫筆畫出來(lái)的內(nèi)容,是虛的并沒(méi)有真正的組件在上面。
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
}
