在使用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
5if(value==START){
6 /**//*
7 * 继承实现DynTree,以改写节点改变事件的响应代码
8 */
9 class SubTree extends
10
11
12jcx.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
49SubTree rtn=new SubTree(this,"root",false);
50
51 /**//*
52 *添加节点:
53 * obj.addObject(parentNode,itemID,itemName,itemNumber,isExpend);
54 * 参数:
55 * obj:一个
56
57
58jcx.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}
80return ;