上文實現了renderer復用editor的功能,那么反過來editor是否也可以復用renderer的功能呢?而且第一篇提到“通過Java2D來繪制各種天花亂墜的效果”如何實現?這倆個疑問在以下代碼中都有了很好的解答,里面有不少技術細節,我就不多說了大家自己仔細看看。
其實Flex也有同樣的機制,可參見Example: Using an item renderer as an item editor
1
/**
2
* A flag that indicates that the item renderer is also an item editor.
3
* If this property is <code>true</code>, Flex
4
* ignores the <code>itemEditor</code> property and uses the item
5
* renderer for that item as the editor.
6
*
7
* @default false
8
*/
9
public var rendererIsEditor:Boolean = false;

2

3

4

5

6

7

8

9

1
import java.awt.*;
2
import java.awt.geom.*;
3
import java.awt.event.*;
4
import javax.swing.*;
5
import javax.swing.border.*;
6
import javax.swing.table.*;
7
public class TableTest3 extends JFrame {
8
JTable table;
9
Double[] values = new Double[]{new Double(0.1), new Double(0.3), new Double(0.8)};
10
11
// model
12
class TableModel extends AbstractTableModel{
13
public int getColumnCount() {
14
return 2;
15
}
16
public int getRowCount() {
17
return values.length;
18
}
19
public Object getValueAt(int rowIndex, int columnIndex) {
20
return values[rowIndex];
21
}
22
public void setValueAt(Object value, int rowIndex, int columnIndex) {
23
values[rowIndex] = (Double)value;
24
this.fireTableCellUpdated(rowIndex, 0);
25
}
26
public String getColumnName(int columnIndex) {
27
if(columnIndex == 0){
28
return "plain";
29
}else{
30
return "beauty";
31
}
32
}
33
public boolean isCellEditable(int rowIndex, int columnIndex) {
34
if(columnIndex == 0){
35
return false;
36
}else{
37
return true;
38
}
39
}
40
}
41
42
// cell editor
43
class Editor extends AbstractCellEditor implements TableCellEditor, ActionListener {
44
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 100, 50);
45
TableCellRenderer renderer;
46
JButton actionButton;
47
48
Object value;
49
JTable table;
50
int row;
51
int column;
52
53
JPanel panel = new JPanel(new BorderLayout());
54
55
public Editor(TableCellRenderer renderer){
56
this.renderer = renderer;
57
actionButton = new JButton(new ImageIcon(TableTest3.class.getResource("dotdotdot.gif")));
58
actionButton.addActionListener(this);
59
actionButton.setFocusable(false);
60
actionButton.setFocusPainted(false);
61
actionButton.setMargin(new Insets(0, 0, 0, 0));
62
panel.add(actionButton, BorderLayout.EAST);
63
}
64
65
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column){
66
this.value = value;
67
this.table = table;
68
this.row = row;
69
this.column = column;
70
panel.add(renderer.getTableCellRendererComponent(table, value, true, isSelected, row, column));
71
return panel;
72
}
73
74
public Object getCellEditorValue(){
75
return value;
76
}
77
public void actionPerformed(ActionEvent e) {
78
int intValue = (int)(((Number)value).doubleValue() * 100);
79
slider.setValue(intValue);
80
81
int result = JOptionPane.showOptionDialog(TableTest3.this,
82
slider, "change value",
83
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null);
84
85
if(result==JOptionPane.OK_OPTION) {
86
this.value = new Double(slider.getValue()/100.0);
87
this.fireEditingStopped();
88
}else{
89
this.fireEditingCanceled();
90
}
91
}
92
}
93
94
// cell render
95
class Renderer extends JComponent implements TableCellRenderer{
96
Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
97
Border focusBorder = UIManager.getBorder("Table.focusCellHighlightBorder");
98
99
private boolean hasFocus;
100
private Double value;
101
102
public void paintComponent(Graphics g) {
103
super.paintComponent(g);
104
105
if(hasFocus){
106
this.setBorder(focusBorder);
107
}else{
108
this.setBorder(noFocusBorder);
109
}
110
Dimension size = this.getSize();
111
112
Graphics2D g2 = (Graphics2D) g;
113
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
114
GradientPaint gp = new GradientPaint(0, 0, Color.BLUE, size.width, 0, Color.YELLOW, true);
115
g2.setPaint(gp);
116
g2.fillRect(0, 0, size.width, size.height);
117
118
g2.setColor(Color.GREEN);
119
double r = (size.height - <IMG class=wp-smiley alt=8) src="http://twaver.servasoft.com/wp-includes/images/smilies/icon_cool.gif"> / 2.0;
120
int centerX = (int)(size.width * value.doubleValue());
121
int centerY = (int)r;
122
g2.fill(new Ellipse2D.Double(centerX-r, centerY-r+4, r * 2, r * 2));
123
}
124
125
public Component getTableCellRendererComponent(JTable table, Object value,
126
boolean isSelected, boolean hasFocus, int row, int column) {
127
this.hasFocus = hasFocus;
128
this.value = (Double)value;
129
this.setToolTipText(value + "");
130
return this;
131
}
132
}
133
134
public TableTest3(){
135
super("renderer used by editor");
136
table = new JTable(new TableModel());
137
TableColumn tableColumn = table.getColumnModel().getColumn(1);
138
tableColumn.setCellRenderer(new Renderer());
139
tableColumn.setCellEditor(new Editor(new Renderer()));
140
141
this.getContentPane().setLayout(new BorderLayout());
142
this.getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
143
this.setSize(500, 300);
144
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
145
}
146
public static void main(String[] args) {
147
new TableTest3().show();
148
}
149
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149
