1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.xulux.guilayer.swing.widgets;
17
18 import java.util.ArrayList;
19 import java.util.Iterator;
20 import java.util.List;
21
22 import javax.swing.JScrollPane;
23 import javax.swing.ToolTipManager;
24 import javax.swing.tree.DefaultTreeCellRenderer;
25 import javax.swing.tree.TreePath;
26 import javax.swing.tree.TreeSelectionModel;
27
28 import org.xulux.api.core.IWidgetConfig;
29 import org.xulux.api.dataprovider.IField;
30 import org.xulux.api.dataprovider.IMapping;
31 import org.xulux.api.gui.IContentWidget;
32 import org.xulux.api.gui.IWidget;
33 import org.xulux.core.XuluxContext;
34 import org.xulux.dataprovider.contenthandlers.ContentView;
35 import org.xulux.dataprovider.contenthandlers.TreeContentHandler;
36 import org.xulux.gui.ContainerWidget;
37 import org.xulux.gui.WidgetFactory;
38 import org.xulux.guilayer.swing.extensions.XuluxJTree;
39 import org.xulux.guilayer.swing.listeners.ImmidiateTreeSelectionListener;
40 import org.xulux.guilayer.swing.listeners.MouseDoubleClickTreeListener;
41 import org.xulux.guilayer.swing.listeners.NewSelectionListener;
42 import org.xulux.guilayer.swing.listeners.PopupListener;
43 import org.xulux.guilayer.swing.listeners.UpdateButtonsListener;
44 import org.xulux.guilayer.swing.models.NyxTreeCellRenderer;
45 import org.xulux.guilayer.swing.models.SwingTreeModel;
46 import org.xulux.utils.BooleanUtils;
47 import org.xulux.utils.ClassLoaderUtils;
48
49
50
51
52
53 public class Tree extends ContainerWidget implements IContentWidget {
54
55
56
57
58 protected XuluxJTree jtree;
59
60
61
62 protected JScrollPane scrollPane;
63
64
65
66 protected Object content;
67
68
69
70 protected boolean contentChanged;
71
72
73
74 protected SwingTreeModel contentHandler;
75
76
77
78 protected boolean hasChildPopups;
79
80
81
82 protected IWidget menu;
83
84
85
86 protected NyxTreeCellRenderer cellRenderer;
87
88
89
90 protected NewSelectionListener selectionListener;
91
92
93
94 protected ImmidiateTreeSelectionListener immidiateListener;
95
96 protected MouseDoubleClickTreeListener mdcListener;
97
98
99
100
101 public Tree(String name) {
102 super(name);
103 }
104
105
106
107
108
109 public void destroy() {
110 if (!initialized) {
111 return;
112 }
113 super.destroy();
114 cellRenderer = null;
115 if (mdcListener != null) {
116 jtree.removeMouseListener(mdcListener);
117 mdcListener = null;
118 }
119 if (selectionListener != null) {
120 jtree.removeTreeSelectionListener(selectionListener);
121 selectionListener = null;
122 }
123 if (immidiateListener != null) {
124 jtree.removeTreeSelectionListener(immidiateListener);
125 immidiateListener = null;
126 }
127 if (this.scrollPane != null) {
128 if (this.jtree != null) {
129 this.scrollPane.remove(jtree);
130 jtree = null;
131 }
132 this.scrollPane = null;
133 }
134 }
135
136
137
138
139 public Object getNativeWidget() {
140 initialize();
141 return this.scrollPane;
142 }
143
144
145
146
147
148
149
150 public void initialize() {
151 if (initialized) {
152 return;
153 }
154 if (this.contentHandler == null) {
155 this.contentHandler = new SwingTreeModel(null);
156 }
157 jtree = new XuluxJTree(this.contentHandler);
158 ToolTipManager.sharedInstance().registerComponent(jtree);
159 if (selectionListener == null) {
160 selectionListener = new NewSelectionListener(this);
161 }
162 jtree.addTreeSelectionListener(selectionListener);
163 if (immidiateListener == null) {
164 immidiateListener = new ImmidiateTreeSelectionListener(this);
165 }
166 jtree.addTreeSelectionListener(immidiateListener);
167 cellRenderer = new NyxTreeCellRenderer(this);
168
169 jtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
170 jtree.setCellRenderer(this.cellRenderer);
171 scrollPane = new JScrollPane(jtree);
172 initializeChildren();
173 initialized = true;
174 contentChanged();
175 refresh();
176 }
177
178
179
180
181 public void refresh() {
182 if (isRefreshing()) {
183 return;
184 }
185 isRefreshing = true;
186 initialize();
187
188 String lineStyle = getProperty("linestyle");
189 if (lineStyle == null) {
190
191 lineStyle = "None";
192 }
193
194 if (jtree == null) {
195 return;
196 }
197 jtree.putClientProperty("JTree.lineStyle", lineStyle);
198 if (getChildWidgets() != null) {
199
200 IWidget child = (IWidget) getChildWidgets().get(0);
201 }
202 boolean showRoot = true;
203 if (getProperty("showRoot") != null) {
204 showRoot = BooleanUtils.toBoolean(getProperty("showRoot"));
205 }
206 jtree.setRootVisible(showRoot);
207
208 if (contentChanged) {
209 if (getProperty("contentview") != null) {
210 contentHandler.setView(ClassLoaderUtils.getClass((String)getProperty("contentview")));
211 }
212 contentHandler.refresh();
213 jtree.setModel(contentHandler);
214 contentChanged = false;
215 }
216 if (getProperty("collapse") != null) {
217 if (getContent() != null) {
218 setProperty("collapse", null);
219 }
220
221
222 if (jtree != null && contentHandler != null) {
223
224 String collapseUntill = getProperty("collapse-untill");
225 jtree.collapsePath(new TreePath(contentHandler.getRoot()));
226 if (collapseUntill != null) {
227 if (collapseUntill != null) {
228 if (collapseUntill.toLowerCase().startsWith("level")) {
229 int level = Integer.parseInt(collapseUntill.substring("level".length()));
230 expandToLevel(null, level);
231 }
232 }
233 }
234 }
235 }
236 if (getProperty("expand") != null) {
237 if (jtree != null && contentHandler != null) {
238 String expandUntill = getProperty("expand-untill");
239 expandTree(expandUntill);
240 }
241 }
242 jtree.setShowsRootHandles(true);
243
244
245 if (!BooleanUtils.toBoolean(getProperty("showicons"))) {
246 if (jtree != null) {
247 if (jtree.getCellRenderer() instanceof DefaultTreeCellRenderer) {
248 DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) jtree.getCellRenderer();
249 renderer.setOpenIcon(null);
250 renderer.setClosedIcon(null);
251 renderer.setLeafIcon(null);
252 }
253 }
254 }
255
256 if (mdcListener == null && getProperty("doubleclick") != null) {
257 mdcListener = new MouseDoubleClickTreeListener(this);
258 jtree.addMouseListener(mdcListener);
259 }
260 jtree.setEnabled(isEnabled());
261 jtree.setVisible(isVisible());
262 scrollPane.setPreferredSize(getRectangle().getRectangle().getSize());
263 initializePopupMenu();
264 isRefreshing = false;
265 }
266
267
268
269
270
271
272
273
274
275 protected void expandToLevel(Object root, int level) {
276 if (level == 0) {
277
278 return;
279 }
280 if (expandPath == null) {
281 expandPath = new ArrayList();
282 }
283 if (root == null) {
284
285 root = contentHandler.getRoot();
286 }
287 expandPath.add(root);
288 int childCount = contentHandler.getChildCount(root);
289 for (int i = 0; i < childCount; i++) {
290 Object ele = contentHandler.getChild(root, i);
291 if (expandPath.size() - 1 != level) {
292 expandToLevel(ele, level);
293 } else {
294 if (expandPath != null) {
295
296 jtree.collapsePath(new TreePath(expandPath.toArray()));
297
298 expandPath.remove(root);
299 jtree.expandPath(new TreePath(expandPath.toArray()));
300 break;
301 }
302 }
303 }
304 expandPath.remove(root);
305 }
306
307
308
309
310
311 protected void expandToLevel(Object root) {
312
313 }
314
315
316
317
318
319
320 protected void expandTree(String untill) {
321 boolean expandDefault = false;
322 Object root = contentHandler.getRoot();
323 if (untill == null) {
324 expandDefault(root);
325 return;
326 }
327 if (untill.equalsIgnoreCase("leaf")) {
328 expand(root, true);
329 return;
330 }
331 if (untill.equalsIgnoreCase("all")) {
332 expand(root, false);
333 return;
334 }
335 Class untillClazz = ClassLoaderUtils.getClass(untill);
336 if (untillClazz == null) {
337 expandDefault(root);
338 return;
339 }
340 expandFrom(root, untillClazz);
341 }
342
343
344
345 private List expandPath;
346
347
348
349
350
351 protected void expand(Object root, boolean leaf) {
352 if (expandPath == null) {
353 expandPath = new ArrayList();
354 }
355 expandPath.add(root);
356 int childCount = contentHandler.getChildCount(root);
357 for (int i = 0; i < childCount; i++) {
358 Object ele = contentHandler.getChild(root, i);
359 if (!contentHandler.isLeaf(ele)) {
360 expand(ele, leaf);
361 } else {
362 if (expandPath != null) {
363
364
365 if (leaf) {
366 expandPath.remove(root);
367 jtree.collapsePath(new TreePath(expandPath.toArray()));
368 }
369 jtree.expandPath(new TreePath(expandPath.toArray()));
370 }
371 }
372 }
373 expandPath.remove(root);
374 }
375
376
377
378
379
380
381 protected void expandFrom(Object root, Class untill) {
382 }
383
384
385
386
387
388 protected void expandDefault(Object root) {
389 jtree.expandPath(new TreePath(root));
390 }
391
392
393
394
395 public Object getGuiValue() {
396 return null;
397 }
398
399
400
401
402 public void focus() {
403
404 }
405
406
407
408
409 public boolean isValueEmpty() {
410 return false;
411 }
412
413
414
415
416 public boolean canContainValue() {
417 return false;
418 }
419
420
421
422
423 public void setContent(Object object) {
424
425
426 this.content = object;
427 if (object != null) {
428 String cHProp = getProperty("contenthandler");
429 TreeContentHandler handler = null;
430 if (cHProp != null) {
431 handler = (TreeContentHandler) ClassLoaderUtils.getObjectFromClassString(cHProp);
432 } else {
433 IWidgetConfig config = XuluxContext.getGuiDefaults().getWidgetConfig(getWidgetType());
434 handler = (TreeContentHandler) config.getContentHandler(object.getClass());
435 }
436
437 if (handler == null) {
438 System.err.println("Handler for content " + object.getClass() + " not found");
439 } else {
440 handler.setWidget(this);
441 handler.setContent(object);
442
443 this.contentHandler = new SwingTreeModel(handler);
444 this.contentHandler.setWidget(this);
445 this.contentHandler.setContent(object);
446 if (getProperty("contentview") != null) {
447 Class contentView = ClassLoaderUtils.getClass(getProperty("contentview"));
448 this.contentHandler.setView(contentView);
449 }
450 }
451 }
452 contentChanged = true;
453 refresh();
454 }
455
456
457
458
459 public Object getContent() {
460 return this.content;
461 }
462
463
464
465
466 public void contentChanged() {
467 if (getProperty("content") != null) {
468 String c = getProperty("content");
469 String cType = getProperty("content.type");
470 if (cType == null || cType.equalsIgnoreCase("use")) {
471 IMapping mapping = XuluxContext.getDictionary().getDefaultProvider().getMapping(getPart().getBean());
472 IField field = mapping.getField(c);
473 setContent(field.getValue(getPart().getBean()));
474 }
475 } else if (getProperty("content.type") != null) {
476 if ("bean".equalsIgnoreCase(getProperty("content.type"))) {
477 setContent(getPart().getBean());
478 }
479 }
480 if (contentHandler != null) {
481 if (getProperty("contentview") != null) {
482
483 contentHandler.getInnerContentHandler().setView(ClassLoaderUtils.getClass((String)getProperty("contentview")));
484 }
485 contentHandler.refresh();
486 }
487 }
488
489
490
491
492 public void addToParent(IWidget widget) {
493 if (widget instanceof PopupMenu || widget instanceof MenuItem) {
494 hasChildPopups = true;
495 } else {
496 cellRenderer.setChildWidget(widget);
497 }
498 }
499
500
501
502
503
504 protected void initializePopupMenu() {
505
506 if (hasChildPopups) {
507
508
509 if (menu == null) {
510 menu = WidgetFactory.getWidget("popupmenu", "PopupMenu:" + getName());
511 menu.setPart(getPart());
512 }
513 if (getChildWidgets() != null) {
514 for (Iterator it = getChildWidgets().iterator(); it.hasNext();) {
515 IWidget cw = (IWidget) it.next();
516 if (cw instanceof MenuItem) {
517 cw.addXuluxListener(new UpdateButtonsListener(this, cw));
518 cw.setParent(menu);
519 cw.setPart(getPart());
520 menu.addChildWidget(cw);
521 }
522 }
523 }
524 }
525 if (menu != null) {
526 menu.setParent(this);
527 menu.initialize();
528 jtree.addMouseListener(new PopupListener(this.menu, this));
529 }
530 }
531
532
533
534
535 public Object getValue() {
536 if (jtree != null) {
537 if (jtree.getSelectionPath() != null) {
538 Object obj = jtree.getSelectionPath().getLastPathComponent();
539 if (obj instanceof ContentView) {
540 obj = ((ContentView)obj).getSource();
541 }
542 return obj;
543 }
544 }
545 return null;
546 }
547
548
549
550
551
552 public void setValue(Object value) {
553 System.out.println("Setting value : " + value);
554 new Exception().printStackTrace();
555 if (this.contentHandler == null) {
556 return;
557 }
558 if (jtree != null) {
559 TreePath tp = this.contentHandler.getTreePath(value);
560 if (tp == null) {
561 System.out.println("Cannot find value "+value+" in the tree!");
562 } else {
563 jtree.setSelectionPath(tp);
564 jtree.scrollPathToVisible(tp);
565 }
566 }
567 super.setValue(value);
568 }
569
570
571
572
573 public SwingTreeModel getSwingModel() {
574 return this.contentHandler;
575 }
576
577 }