1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.devaki.nextobjects.ui.main;
21
22 import java.awt.Component;
23 import java.awt.GridBagConstraints;
24 import java.awt.GridBagLayout;
25 import java.awt.Insets;
26 import java.awt.event.MouseEvent;
27 import javax.swing.JPanel;
28 import javax.swing.JScrollPane;
29 import javax.swing.JTree;
30 import javax.swing.event.MouseInputAdapter;
31 import javax.swing.tree.DefaultMutableTreeNode;
32 import javax.swing.tree.DefaultTreeCellEditor;
33 import javax.swing.tree.DefaultTreeCellRenderer;
34 import javax.swing.tree.DefaultTreeModel;
35 import javax.swing.tree.TreeNode;
36 import javax.swing.tree.TreePath;
37 import javax.swing.tree.TreeSelectionModel;
38 import org.devaki.nextobjects.constants.CstImages;
39 import org.devaki.nextobjects.ui.components.CustomTreeNode;
40 import org.devaki.nextobjects.ui.menus.TreePopupMenu;
41 import org.devaki.nextobjects.ui.workspace.models.EditorFactory;
42 import org.devaki.nextobjects.util.ModelMan;
43 import org.devaki.nextobjects.workspace.models.ConceptualModel;
44 import org.devaki.nextobjects.workspace.models.PhysicalModel;
45 import org.devaki.nextobjects.workspace.models.columns.Column;
46 import org.devaki.nextobjects.workspace.models.objects.Association;
47 import org.devaki.nextobjects.workspace.models.objects.BaseClass;
48 import org.devaki.nextobjects.workspace.models.objects.BaseObject;
49 import org.devaki.nextobjects.workspace.models.objects.Constraint;
50 import org.devaki.nextobjects.workspace.models.objects.Entity;
51 import org.devaki.nextobjects.workspace.models.objects.Table;
52 import org.devaki.nextobjects.workspace.models.objects.InheritanceLink;
53
54 /***
55 * The tree containing the hierarchy of the objects in the current
56 * workspace (project
57 */
58 public class NOTreeView extends JPanel
59 {
60 /***
61 *Local reference of the object
62 */
63 private NOTreeView me;
64
65 /***
66 * Node objects
67 */
68 private Object object;
69
70 /***
71 * A parent node
72 */
73 private Object objectParent;
74
75 /***
76 * the tree model
77 **/
78 private static NOTreeModel treeModel;
79
80 /***
81 * The cell renderer to edit name of classes and fields
82 */
83 private NOTreeCellRenderer jTreeRenderer= new NOTreeCellRenderer();
84
85 /***
86 * Another node
87 */
88 private DefaultMutableTreeNode root;
89
90 /***
91 * The JTree
92 */
93 private static JTree jTree;
94
95 /***
96 * Reference to the popup menu
97 */
98 private TreePopupMenu pop= new TreePopupMenu();
99
100 /***
101 * Construct a new 'NOTreeView' object
102 */
103 public NOTreeView()
104 {
105 super(new GridBagLayout());
106
107
108 this.me= this;
109
110
111 root= new CustomTreeNode("Workspace");
112
113 treeModel= new NOTreeModel(root);
114
115 jTree= new JTree(treeModel);
116
117 jTree.putClientProperty("JTree.lineStyle", "Angled");
118
119 jTree.setCellRenderer(this.jTreeRenderer);
120 jTree.setCellEditor(new NOTreeCellEditor());
121
122
123 jTree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
124
125 jTree.setEditable(true);
126
127
128 jTree.addMouseListener(new MouseInputAdapter()
129 {
130
131 public void mouseClicked(MouseEvent e)
132 {
133 if (jTree.getSelectionPath() != null)
134 {
135
136 object= ((CustomTreeNode) jTree.getSelectionPath().getLastPathComponent()).getUserObject();
137
138
139 if (((CustomTreeNode) jTree.getSelectionPath().getLastPathComponent()).getParent() != null)
140 {
141 objectParent=
142 ((CustomTreeNode) ((CustomTreeNode) jTree.getSelectionPath().getLastPathComponent())
143 .getParent())
144 .getUserObject();
145 }
146
147
148 if (object instanceof BaseObject)
149 {
150 if (e.isControlDown())
151 {
152 ModelMan.addCurrentObject((BaseObject) object);
153 }
154 else
155 {
156 ModelMan.setCurrentObject((BaseObject) object);
157 }
158 }
159
160
161
162
163 if (object instanceof Entity)
164 {
165 if (e.getClickCount() == 2)
166 {
167 EditorFactory.getEntityEdit((Entity) ModelMan.getCurrentObject());
168 }
169 }
170
171
172 else if (object instanceof Association)
173 {
174 if (e.getClickCount() == 2)
175 {
176 EditorFactory.getAssociationEdit((Association) ModelMan.getCurrentObject());
177 }
178 }
179
180
181 else if (object instanceof Table)
182 {
183 if (e.getClickCount() == 2)
184 {
185 EditorFactory.getTableEdit((Table) ModelMan.getCurrentObject());
186 }
187 }
188
189
190 else if (object instanceof Constraint)
191 {
192 if (e.getClickCount() == 2)
193 {
194 EditorFactory.getConstraintEdit((Constraint) ModelMan.getCurrentObject());
195 }
196 }
197
198
199 else if (object instanceof ConceptualModel)
200 {
201 if (e.getClickCount() == 2)
202 {
203 EditorFactory.getModelEdit();
204 }
205 }
206
207
208 else if (object instanceof PhysicalModel)
209 {
210 if (e.getClickCount() == 2)
211 {
212 EditorFactory.getModelEdit();
213 }
214 }
215 if (ModelMan.getCurrentModel() != null)
216 {
217 ModelMan.getCurrentModel().getPanel().repaint();
218 }
219
220 }
221 }
222
223
224
225 public void mousePressed(MouseEvent e)
226 {
227 evaluatePopup(e);
228 }
229
230 public void mouseReleased(MouseEvent e)
231 {
232 evaluatePopup(e);
233 }
234
235 /***
236 * Evaluate if popup menu has been requested
237 * This function is needed because of the difference to get a popup menu
238 * on Mac OS X (mousePressed instead of mouseReleased)
239 * @param e
240 */
241 private void evaluatePopup(MouseEvent e)
242 {
243 if (e.isPopupTrigger())
244 {
245
246 jTree.setSelectionRow(jTree.getClosestRowForLocation(e.getX(), e.getY()));
247
248 object= ((CustomTreeNode) jTree.getSelectionPath().getLastPathComponent()).getUserObject();
249
250 if (((CustomTreeNode) jTree.getSelectionPath().getLastPathComponent()).getParent() != null)
251 {
252 objectParent=
253 ((CustomTreeNode) ((CustomTreeNode) jTree.getSelectionPath().getLastPathComponent())
254 .getParent())
255 .getUserObject();
256 pop.setData(object, objectParent);
257 }
258 else
259 {
260 pop.setData(object, null);
261 }
262
263
264
265 pop.show(me, e.getX() + 5, e.getY() + 5);
266 }
267 }
268 });
269
270 /*** Assembling components **/
271
272
273 this.add(
274 new JScrollPane(jTree),
275 new GridBagConstraints(
276 0,
277 0,
278 1,
279 1,
280 1.0,
281 1.0,
282 GridBagConstraints.CENTER,
283 GridBagConstraints.BOTH,
284 new Insets(3, 3, 3, 3),
285 0,
286 0));
287 }
288
289 /***
290 * Set the selected node in the tree
291 * @param pNode
292 */
293 public static void setSelectedNode(CustomTreeNode pNode)
294 {
295 TreePath path= new TreePath(pNode.getPath());
296 jTree.setSelectionPath(path);
297 jTree.scrollPathToVisible(path);
298 }
299
300 /***
301 * Add the node as selected in the tree
302 * @param pNode
303 */
304 public static void addSelectedNode(CustomTreeNode pNode)
305 {
306 TreePath path= new TreePath(pNode.getPath());
307 jTree.addSelectionPath(path);
308 jTree.scrollPathToVisible(path);
309 }
310
311 /***
312 * Reset the selection in the tree
313 */
314 public static void resetSelectedNode()
315 {
316 jTree.setSelectionPath(jTree.getPathForRow(0));
317 }
318
319 /***
320 * Add a node to the root node in the tree
321 * @param newNode
322 */
323 public static void addNode(CustomTreeNode newNode)
324 {
325 treeModel.insertNodeInto(newNode, (CustomTreeNode) treeModel.getRoot(), ModelMan.getModels().size() - 1);
326 }
327
328 /***
329 * Add a node to another node in the tree
330 * @param newNode
331 * @param parentNode
332 * @param i
333 */
334 public static void addNode(CustomTreeNode newNode, CustomTreeNode parentNode, int i)
335 {
336 treeModel.insertNodeInto(newNode, parentNode, i);
337
338 jTree.expandPath(new TreePath(parentNode.getPath()));
339 }
340
341 /***
342 * Remove a node in the tree
343 * @param pNode
344 */
345 public static void removeNode(CustomTreeNode pNode)
346 {
347 treeModel.removeNodeFromParent(pNode);
348 }
349
350 /***
351 * Rename the current selected node
352 */
353 public static void renameNode()
354 {
355 jTree.startEditingAtPath(jTree.getSelectionPath());
356 }
357
358 /***
359 * Reload childrens of the given node from a BaseClass object
360 * @param pNode the node where to start a recursive reload
361 */
362 public static void reloadBaseClassChildrens(CustomTreeNode pNode)
363 {
364 BaseClass baseClass= (BaseClass) pNode.getUserObject();
365 Column tmpColumn= null;
366
367
368 baseClass.getDynamicTreeNode().removeAllChildren();
369
370
371 for (int i= 0; i < baseClass.getData().size(); i++)
372 {
373 tmpColumn= (Column) baseClass.getData().elementAt(i);
374 if (tmpColumn.getDynamicTreeNode() == null)
375 {
376 tmpColumn.setDynamicTreeNode(new CustomTreeNode(tmpColumn));
377 }
378 addNode(tmpColumn.getDynamicTreeNode(), pNode, i);
379 }
380
381
382 treeModel.reload();
383 jTree.expandPath(new TreePath(pNode.getPath()));
384 }
385
386 /***
387 * NOTreeCellRenderer render a tree cell
388 */
389 private class NOTreeCellRenderer extends DefaultTreeCellRenderer
390 {
391 public Component getTreeCellRendererComponent(
392 JTree tree,
393 Object value,
394 boolean isSelected,
395 boolean expanded,
396 boolean leaf,
397 int row,
398 boolean hasFocus)
399 {
400 super.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, hasFocus);
401 Object object= ((CustomTreeNode) value).getUserObject();
402 if (object instanceof Column)
403 {
404 if (((Column) object).isPk())
405 {
406 this.setIcon(CstImages.ICN_FIELD_PK);
407 }
408 else
409 {
410 this.setIcon(CstImages.ICN_FIELD);
411 }
412 }
413 else if (object instanceof Entity || object instanceof Table)
414 {
415 this.setIcon(CstImages.ICN_TABLE);
416 }
417 else if (object instanceof Association)
418 {
419 this.setIcon(CstImages.ICN_ASSOCIATION);
420 }
421 else if (object instanceof Constraint)
422 {
423 this.setIcon(CstImages.ICN_CONSTRAINT);
424 }
425 else if (object instanceof InheritanceLink)
426 {
427 this.setIcon(CstImages.ICN_INHERITANCE);
428 }
429 else if (object instanceof ConceptualModel)
430 {
431 this.setIcon(CstImages.ICN_CDM);
432 }
433 else if (object instanceof PhysicalModel)
434 {
435 this.setIcon(CstImages.ICN_PDM);
436 }
437 else
438 {
439 this.setIcon(CstImages.ICN_WORKSPACE);
440 }
441 return this;
442 }
443 }
444
445 /***
446 * NOTreeCellEditor is responsible for editing a tree node
447 */
448 private class NOTreeCellEditor extends DefaultTreeCellEditor
449 {
450 public NOTreeCellEditor()
451 {
452 super(jTree, jTreeRenderer);
453 }
454
455 protected void determineOffset(
456 JTree tree,
457 Object value,
458 boolean isSelected,
459 boolean expanded,
460 boolean leaf,
461 int row)
462 {
463 Object object= ((CustomTreeNode) value).getUserObject();
464 if (object instanceof Column)
465 {
466 if (((Column) object).isPk())
467 {
468 this.editingIcon= CstImages.ICN_FIELD_PK;
469 }
470 else
471 {
472 this.editingIcon= CstImages.ICN_FIELD;
473 }
474 }
475 else if (object instanceof Entity || object instanceof Table)
476 {
477 this.editingIcon= CstImages.ICN_TABLE;
478 }
479 else if (object instanceof Association)
480 {
481 this.editingIcon= CstImages.ICN_ASSOCIATION;
482 }
483 else if (object instanceof Constraint)
484 {
485 this.editingIcon= CstImages.ICN_CONSTRAINT;
486 }
487 else if (object instanceof ConceptualModel)
488 {
489 this.editingIcon= CstImages.ICN_CDM;
490 }
491 else if (object instanceof PhysicalModel)
492 {
493 this.editingIcon= CstImages.ICN_PDM;
494 }
495 else
496 {
497 this.editingIcon= CstImages.ICN_WORKSPACE;
498 }
499
500 this.offset= this.renderer.getIconTextGap() + this.editingIcon.getIconWidth();
501 }
502 }
503
504 /***
505 * The tree model
506 */
507 private class NOTreeModel extends DefaultTreeModel
508 {
509 public NOTreeModel(TreeNode newRoot)
510 {
511 super(newRoot);
512 }
513
514 /***
515 * Actions to be executed when a node edition is over
516 * @param path
517 * @param newValue
518 */
519 public void valueForPathChanged(TreePath path, Object newValue)
520 {
521 if (object instanceof Column)
522 {
523 int index= ((BaseObject) objectParent).getData().indexOf((Column) object);
524 ((Column) ((BaseObject) objectParent).getData().elementAt(index)).setName(newValue.toString());
525 }
526 else if (object instanceof Entity)
527 {
528 ((Entity) object).setName(newValue.toString());
529 }
530 else if (object instanceof Table)
531 {
532 ((Table) object).setName(newValue.toString());
533 }
534 else if (object instanceof Association)
535 {
536 ((Association) object).setName(newValue.toString());
537 }
538 else if (object instanceof Constraint)
539 {
540 ((Constraint) object).setName(newValue.toString());
541 }
542 else if (object instanceof PhysicalModel)
543 {
544 ((PhysicalModel) object).setName(newValue.toString());
545 }
546 else if (object instanceof ConceptualModel)
547 {
548 ((ConceptualModel) object).setName(newValue.toString());
549 }
550 }
551 }
552
553 }