在使用EMaker時發現竟然沒有Tree組件可以使用,可又需要靠它來完成一定的功能。在參考了Emaker的文檔后,終于寫了出來,發在這里與大家共享。
以下為外部類,編譯好后放到emaker\html\jcx\jform\bfc\和emaker\jcx\jform\bfc\兩個目錄下。
??1
package
?jcx.jform.bfc;
??2
??3
import
?java.awt.BorderLayout;
??4
import
?java.awt.GridLayout;
??5
??6
import
?java.awt.Toolkit;
??7
??8
import
?javax.swing.JComponent;
??9
import
?javax.swing.JPanel;
?10
?11
import
?javax.swing.JScrollPane;
?12
?13
import
?javax.swing.JTree;
?14
?15
import
?javax.swing.tree.DefaultMutableTreeNode;
?16
?17
import
?javax.swing.tree.DefaultTreeModel;
?18
?19
import
?javax.swing.tree.MutableTreeNode;
?20
?21
import
?javax.swing.tree.TreePath;
?22
?23
import
?javax.swing.tree.TreeSelectionModel;
?24
?25
//
import?javax.swing.event.TreeModelEvent;
?26
//
import?javax.swing.event.TreeModelListener;
?27
import
?javax.swing.event.TreeSelectionEvent;
?28
import
?javax.swing.event.TreeSelectionListener;
?29
import
?jcx.jform.bdisplay;
?30
import
?java.util.Enumeration;
?31
?32
//
import?java.lang.reflect.Method;
?33
?34
/**?*/
/**
?35
?*?<code>DynTree</code>是用來在EMaker中生成內嵌的Tree的類。<br>
?36
?*?
?37
?*?
@version
?1.0
?38
?*?
@author
?Bernie(Hongbin)?Yoo
?39
?*?
?40
?
*/
?41
public
?
class
?DynTree?
extends
?JPanel?
implements
?java.awt.event.ActionListener?
{
?42
????
/**?*/
/**
?根節點。?
*/
?43
????
public
?DefaultMutableTreeNode?rootNode;
?44
?45
????
/**?*/
/**
?當前選擇的節點。?
*/
?46
????
public
?DefaultMutableTreeNode?selectionNode;
?47
?48
????
/**?*/
/**
?上一次選擇的節點,用于取消選擇節點時使用。?
*/
?49
????
private
?DefaultMutableTreeNode?preSelectionNode;
?50
?51
????
/**?*/
/**
?Tree?Model?
*/
?52
????
protected
?DefaultTreeModel?treeModel;
?53
?54
????
protected
?JTree?tree;
?55
?56
????
private
?Toolkit?toolkit?
=
?Toolkit.getDefaultToolkit();
?57
?58
????
/**?*/
/**
?<code>jcx.jform.bdisplay</code>,Emaker中Tree的容器。?
*/
?59
????
protected
?bdisplay?bdis;
?60
?61
????
/**?*/
/**
?62
?????*?靜態自調用函數,可在未定義類實例時使用,返回為一個<code>DynTree</code>實例。
?63
?????*?
?64
?????*?
@param
?bd
?65
?????*????????????<code>jcx.jform.bdisplay</code>,Emaker中<code>DynTree</code>的容器。
?66
?????*?
@param
?root
?67
?????*????????????根節點名稱。
?68
?????*?
@param
?rootVisible
?69
?????*????????????根節點是否可見。
?70
?????*?
@return
?一個<code>DynTree</code>類的實例。
?71
?????
*/
?72
????
public
?
static
?Object?init(bdisplay?bd,?String?root,?
boolean
?rootVisible)?
{
?73
?74
????????
return
?
new
?DynTree(bd,?root,?rootVisible);
?75
????}
?76
?77
????
/**?*/
/**
?78
?????*?<code>DynTree</code>的構造函數。
?79
?????*?
?80
?????*?
@param
?bd
?81
?????*????????????<code>jcx.jform.bdisplay</code>,Emaker中<code>DynTree</code>的容器。
?82
?????*?
@param
?root
?83
?????*????????????根節點名稱。
?84
?????*?
@param
?rootVisible
?85
?????*????????????根節點是否可見。
?86
?????
*/
?87
????
public
?DynTree(bdisplay?bd,?String?root,?
boolean
?rootVisible)?
{
?88
????????bdis?
=
?bd;
?89
????????JPanel?pan?
=
?
new
?JPanel(
new
?GridLayout(
1
,?
1
));
?90
????????JComponent?base?
=
?bdis.getLabel();
?91
????????base.setLayout(
new
?BorderLayout());
?92
?93
????????rootNode?
=
?
new
?DefaultMutableTreeNode(root);
?94
????????treeModel?
=
?
new
?DefaultTreeModel(rootNode);
?95
?96
????????tree?
=
?
new
?JTree(treeModel);
?97
????????tree.addTreeSelectionListener(
new
?MyTreeSelectionListener());
?98
????????tree.setEditable(
false
);
?99
????????tree.getSelectionModel().setSelectionMode(
100
????????????????TreeSelectionModel.SINGLE_TREE_SELECTION);
101
????????tree.setShowsRootHandles(
true
);
102
????????tree.setRootVisible(rootVisible);
103
????????JScrollPane?scrollPane?
=
?
new
?JScrollPane(tree);
104
????????pan.add(scrollPane);
105
????????base.add(pan,?BorderLayout.CENTER);
106
????}
107
108
????
/**?*/
/**
109
?????*?(non-Javadoc)
110
?????*?
111
?????*?
@see
?java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
112
?????
*/
113
????
public
?
void
?actionPerformed(java.awt.event.ActionEvent?e)?
{
114
115
????}
116
117
????
/**?*/
/**
?移除根節點以外所有節點。?
*/
118
????
public
?
void
?clear()?
{
119
????????rootNode.removeAllChildren();
120
????????treeModel.reload();
121
????}
122
123
????
/**?*/
/**
?移除當前選中的節點。?
*/
124
125
????
public
?
void
?removeCurrentNode()?
{
126
127
????????TreePath?currentSelection?
=
?tree.getSelectionPath();
128
129
????????
if
?(currentSelection?
!=
?
null
)?
{
130
????????????DefaultMutableTreeNode?currentNode?
=
?(DefaultMutableTreeNode)?(currentSelection
131
????????????????????.getLastPathComponent());
132
133
????????????MutableTreeNode?parent?
=
?(MutableTreeNode)?(currentNode.getParent());
134
135
????????????
if
?(parent?
!=
?
null
)?
{
136
????????????????treeModel.removeNodeFromParent(currentNode);
137
????????????????
return
;
138
????????????}
139
????????}
140
????????toolkit.beep();
141
????}
142
143
????
/**?*/
/**
144
?????*?添加子節點到當前選擇的節點下。
145
?????*?
146
?????*?
@param
?itemID
147
?????*????????????子節點的ItemID。
148
?????*?
@param
?itemName
149
?????*????????????子節點的ItemName。
150
?????*?
@param
?itemNumber
151
?????*????????????子節點的ItemNumber。
152
?????*?
@return
?新增加的子節點。
153
?????
*/
154
????
public
?DefaultMutableTreeNode?addObject(
int
?itemID,?String?itemName,
155
????????????String?itemNumber)?
{
156
157
????????DefaultMutableTreeNode?parentNode?
=
?
null
;
158
????????TreePath?parentPath?
=
?tree.getSelectionPath();
159
160
????????
if
?(parentPath?
==
?
null
)?
{
161
????????????parentNode?
=
?rootNode;
162
????????}
?
else
?
{
163
????????????parentNode?
=
?(DefaultMutableTreeNode)?(parentPath
164
????????????????????.getLastPathComponent());
165
????????}
166
????????
return
?addObject(parentNode,?itemID,?itemName,?itemNumber,?
true
);
167
????}
168
169
????
/**?*/
/**
170
?????*?添加子節點到當前選擇的節點下。
171
?????*?
172
?????*?
@param
?parent
173
?????*????????????父節點。
174
?????*?
@param
?itemID
175
?????*????????????子節點的ItemID。
176
?????*?
@param
?itemName
177
?????*????????????子節點的ItemName。
178
?????*?
@param
?itemNumber
179
?????*????????????子節點的ItemNumber。
180
?????*?
@return
?新增加的子節點。
181
?????
*/
182
????
public
?DefaultMutableTreeNode?addObject(DefaultMutableTreeNode?parent,
183
????????????
int
?itemID,?String?itemName,?String?itemNumber)?
{
184
????????
return
?addObject(parent,?itemID,?itemName,?itemNumber,?
true
);
185
????}
186
187
????
/**?*/
/**
188
?????*?添加子節點到當前選擇的節點下。
189
?????*?
190
?????*?
@param
?parent
191
?????*????????????父節點。
192
?????*?
@param
?itemID
193
?????*????????????子節點的ItemID。
194
?????*?
@param
?itemName
195
?????*????????????子節點的ItemName。
196
?????*?
@param
?itemNumber
197
?????*????????????子節點的ItemNumber。
198
?????*?
@param
?shouldBeVisible
199
?????*????????????新增節點是否自動展開。
200
?????*?
@return
?新增加的子節點。
201
?????
*/
202
????
public
?DefaultMutableTreeNode?addObject(DefaultMutableTreeNode?parent,
203
????????????
int
?itemID,?String?itemName,?String?itemNumber,
204
????????????
boolean
?shouldBeVisible)?
{
205
????????ItemInfo?child?
=
?
new
?ItemInfo(itemID,?itemName,?itemNumber);
206
????????DefaultMutableTreeNode?childNode?
=
?
new
?DefaultMutableTreeNode(child);
207
208
????????
if
?(parent?
==
?
null
)?
{
209
????????????parent?
=
?rootNode;
210
????????}
211
212
????????treeModel.insertNodeInto(childNode,?parent,?parent.getChildCount());
213
214
????????
//
?Make?sure?the?user?can?see?the?lovely?new?node.
215
????????
if
?(shouldBeVisible)?
{
216
????????????tree.scrollPathToVisible(
new
?TreePath(childNode.getPath()));
217
????????}
218
????????
//
?tree.setSelectionPath(new?TreePath(childNode.getPath()));
219
????????
return
?childNode;
220
????}
221
222
????
/**?*/
/**
223
?????*?得到當前選中的節點。
224
?????
*/
225
????
public
?DefaultMutableTreeNode?getSelectedNode()?
{
226
????????
return
?(DefaultMutableTreeNode)?tree.getSelectionPath()
227
????????????????.getLastPathComponent();
228
????}
229
????
/**?*/
/**
230
?????*?得到指定的節點。
231
?????*?
@param
?itemID?欲獲取節點的ItemID值。
232
?????*?
@return
?????指定的節點。若不存在則返回null。
233
?????
*/
234
????
public
?DefaultMutableTreeNode?getNode(
int
?itemID)?
{
235
????????ItemInfo?nodItem;
236
237
????????
for
?(Enumeration?e?
=
?rootNode.depthFirstEnumeration();?e
238
????????????????.hasMoreElements();)?
{
239
????????????DefaultMutableTreeNode?x?
=
?(DefaultMutableTreeNode)?(e
240
????????????????????.nextElement());
241
????????????nodItem?
=
?(ItemInfo)?(x.getUserObject());
242
????????????
if
?(nodItem.itemID?
==
?itemID)?
{
243
????????????????
return
?x;
244
????????????}
245
????????}
246
????????
return
?
null
;
247
????}
248
????
/**?*/
/**
249
?????*?得到指定的節點。
250
?????*?
@param
?itemNumber?欲獲取節點的ItemNumber值。
251
?????*?
@return
????指定的節點。若不存在則返回null。
252
?????
*/
253
????
public
?DefaultMutableTreeNode?getNode(String?itemNumber)?
{
254
????????ItemInfo?nodItem;
255
????????
for
?(Enumeration?e?
=
?rootNode.depthFirstEnumeration();?e
256
????????????????.hasMoreElements();)?
{
257
????????????DefaultMutableTreeNode?x?
=
?(DefaultMutableTreeNode)?(e
258
????????????????????.nextElement());
259
????????????nodItem?
=
?(ItemInfo)?(x.getUserObject());
260
????????????
if
?(nodItem.itemNumber.equals(itemNumber))?
{
261
????????????????
return
?x;
262
????????????}
263
????????}
264
????????
return
?
null
;
265
????}
266
????
/**?*/
/**
267
?????*?節點改變時的處理,未實際實現,在Emaker中由繼承類實現。
268
?????*?
@param
?node?選中的節點。
269
?????*?
@param
?itemID?選中節點的ItemID。
270
?????*?
@param
?itemName?選中節點的ItemName。
271
?????*?
@param
?itemNumber?選中節點的ItemNumber。
272
?????
*/
273
????
public
?
void
?chgAction(DefaultMutableTreeNode?node,?
int
?itemID,
274
????????????String?itemName,?String?itemNumber)?
{
275
????????
//
?未實現,由其繼承類實現
276
????}
277
????
/**?*/
/**
278
?????*?取消選擇,返回之前的選擇對象,配合<code>chgAction</code>使用。
279
?????*
280
?????
*/
281
????
public
?
void
?cancelChanged()?
{
282
????????tree.setSelectionPath(
new
?TreePath(preSelectionNode.getPath()));
283
????}
284
????
/**?*/
/**
285
?????*?節點上的自定義對象,實現對節點的ItemID\ItemName\ItemNumber的管理。
286
?????*?
@author
?Bernie(Hongbin)?Yoo
287
?????*?
@version
?1.0
288
?????
*/
289
????
private
?
class
?ItemInfo?
{
290
????????
public
?
int
?itemID;
291
292
????????
public
?String?itemName;
293
294
????????
public
?String?itemNumber;
295
????????
296
????????
/**?*/
/**
297
?????????*?構造函數
298
?????????*?
@param
?itemID?ItemID.
299
?????????*?
@param
?itemName?ItemName.
300
?????????*?
@param
?itemNumber?ItemNumber.
301
?????????
*/
302
????????
public
?ItemInfo(
int
?itemID,?String?itemName,?String?itemNumber)?
{
303
304
????????????
this
.itemName?
=
?itemName;
305
????????????
this
.itemID?
=
?itemID;
306
????????????
this
.itemNumber?
=
?itemNumber;
307
????????}
308
????????
/**/
/*
309
?????????*?(non-Javadoc)
310
?????????*?@see?java.lang.Object#toString()
311
?????????
*/
312
????????
313
????????
public
?String?toString()?
{
314
????????????
return
?itemName;
315
????????}
316
????}
317
????
/**?*/
/**
318
?????*?實現監聽節點選擇改變的接口
319
?????*?
@author
?Bernie(Hongbin)?Yoo
320
?????*
321
?????
*/
322
????
323
????
class
?MyTreeSelectionListener?
implements
?TreeSelectionListener?
{
324
????????
public
?
void
?valueChanged(TreeSelectionEvent?e)?
{
325
326
????????????DefaultMutableTreeNode?node?
=
?(DefaultMutableTreeNode)?(e.getPath()
327
????????????????????.getLastPathComponent());
328
????????????
if
?(node?
==
?
null
)
329
????????????????
return
;
330
????????????
if
?(
!
node.equals(selectionNode))?
{
331
????????????????preSelectionNode?
=
?selectionNode;
332
????????????????selectionNode?
=
?node;
333
????????????????
if
?(node.equals(rootNode))?
{
334
????????????????????chgAction(node,?
-
1
,?node.toString(),?
""
);
335
????????????????}
?
else
?
{
336
????????????????????ItemInfo?it?
=
?(ItemInfo)?(node.getUserObject());
337
????????????????????chgAction(node,?it.itemID,?it.itemName,?it.itemNumber);
338
????????????????}
339
????????????}
340
????????}
341
????}
342
}
343
在Emaker中的使用方法:
?1
/**//*
?2
?*在窗體上添加兩個“文字”項,一為text1,一為text2。在text1的自定義格式里添加如下全部代碼。
?3
?*/
?4
?5
if(value==START)
{
?6
????/**//*
?7
?????*??繼承實現DynTree,以改寫節點改變事件的響應代碼
?8
????*/
?9
????class?SubTree?extends?
10
11
12
jcx.jform.bfc.DynTree
{
13
????????public?SubTree(bdisplay?bd,?String?root,boolean?rootVisible)
{
14
????????????super(bd,?root,rootVisible);
15
????????}
16
????????public?void?chgAction(javax.swing.tree.DefaultMutableTreeNode?node,int?itemID,?String?itemName,?String?itemNumber)
{
17
????????????/**//*
18
?????????????*若要響應節點改變事件,實現該方法即可。
19
?????????????*?參數說明:
20
?????????????*??????node:當前選中的節點;
21
?????????????*??????itemID:選中節點的ItemID;
22
?????????????*??????itemName:選中節點的ItemName;
23
?????????????*??????itemNumber:選中節點的ItemNumber
24
?????????????*??????
25
?????????????*??如要在選擇下一個節點前進行事務處理,如保存等可使用
26
?????????????*??????cancelChanged(),表示取消本次選擇,返回上次選擇
27
????????????*/
28
????????????if?(itemID==9)
{?????
29
????????????????cancelChanged();
30
????????????????return;
31
????????????}
32
????????????setValue("text2","ID:"+itemID+";Number:"+itemNumber+";Name:"+itemName);
33
34
????????}
35
36
????????
37
????}
38
????/**//*
39
?????*?初始化實例.
40
?????*?構造函數參數說明:
41
?????*??????SubTree(bdisplay?bd,?String?root,boolean?rootVisible)
42
?????*??????bd:傳入的組件,為固定值this,不可改變.
43
?????*??????root:根節點的名稱.
44
?????*??????rootVisible:根節點是否可見.
45
????*/
46
?????
47
48
49
SubTree?rtn=new?SubTree(this,"root",false);
50
????
51
????/**//*
52
?????*添加節點:
53
?????*??obj.addObject(parentNode,itemID,itemName,itemNumber,isExpend);
54
?????*??參數:
55
?????*??????obj:一個
56
57
58
jcx.jform.bfc.DynTree實例。
59
?????*??????parentNode:父節點。若添加一級節點時,始終為obj.rootNode;
60
?????*??????itemID,itemName,itemNumber:略;
61
?????*??????isExpend:是添自動展開該節點。
62
?????*
63
?????*??得到某一節點:
64
?????*??????obj.getNode(itemID)
65
?????*??????obj.getNode(itemNumber)
66
?????*
67
????*/
68
????for(int?i=1;i<11;i++)
{?
69
????????rtn.addObject(rtn.rootNode,i,"Item"+i,"a"+i,true);
70
????????for(int?j=1;j<11;j++)
{
71
????????????rtn.addObject(rtn.getNode(i),i*100+j,"SubItem"+j,"b"+j,true);
72
????????????for?(int?n=1;n<3;n++)
{
73
????????????????rtn.addObject(rtn.getNode(i*100+j),(i*100+j)*10+n,"SubSubItem"+n,"c"+n,true);
74
????????????}?
75
????????}
76
????}
77
}?else?
{?
78
79
}
80
return?;