1 package com.ontotext.gate.vr;
2
3 import javax.swing.*;
4 import javax.swing.tree.*;
5 import javax.swing.event.*;
6
7
8 import com.ontotext.gate.vr.*;
9
10
11 import java.awt.event.*;
12 import java.awt.*;
13 import java.awt.datatransfer.*;
14 import java.awt.dnd.*;
15 import java.awt.dnd.peer.*;
16
17 import java.io.*;
18 import java.util.*;
19 import java.util.List;
20
21 import gate.creole.ontology.*;
22 import gate.util.GateRuntimeException;
23 import gate.util.Out;
24
25
28 public class EditableTreeView extends JTree
29 implements TreeSelectionListener,DragGestureListener,DropTargetListener,
30 DragSourceListener
31 {
32
33
34 protected TreePath selectedTreePath = null;
35
36
37 protected ClassNode selectedNode = null;
38
39
40 private JPopupMenu m_popUpMenu;
41
42 private JMenuItem add_item;
43 private JMenuItem rename_item;
44 private JMenuItem editURI_item;
45 private JMenuItem remove_item;
46 private JMenuItem view_properties_item;
47
48 private OEMainPanel mainPanel;
49
50
51 private DragSource dragSource = null;
52
53 private DragSourceContext dragSourceContext = null;
54
55 private Transferable transferable = null;
56
57
58 public EditableTreeView(OntoTreeModel model) {
59 super(model);
60 init();
61 }
62
63
68 public static void synchronizeTreeExpansion(JTree orig, JTree mirror) {
69
70
76 Set expanded = new HashSet();
77 TreeModel model = orig.getModel();
78
80 ArrayList remains = new ArrayList();
81 ArrayList remainPaths = new ArrayList();
82
83 remains.add(model.getRoot());
84 ArrayList rootPath = new ArrayList();
85 rootPath.add(model.getRoot());
86 remainPaths.add(rootPath);
87
88 while (remains.size() > 0 ) {
89 Object node = remains.get(0);
90 int cc = model.getChildCount(node);
91 ArrayList parentPath = (ArrayList)remainPaths.get(0);
92 for ( int c = 0 ; c < cc ; c++) {
93 Object child = model.getChild(node,c);
94 remains.add(child);
95 ArrayList pp = new ArrayList(parentPath);
96 pp.add(child);
97 remainPaths.add(pp);
98 }
99 TreePath tp = new TreePath(parentPath.toArray());
100 if (orig.isExpanded(tp)) {
101 expanded.add(node.toString());
102 }
103 remains.remove(0);
104 remainPaths.remove(0);
105 }
107
108
112
113 remains = new ArrayList();
114 remainPaths = new ArrayList();
115
116 model = mirror.getModel();
117 remains.add(model.getRoot());
118 rootPath = new ArrayList();
119 rootPath.add(model.getRoot());
120 remainPaths.add(rootPath);
121
122 while (remains.size() > 0 ) {
123 Object node = remains.get(0);
124 int cc = model.getChildCount(node);
125 ArrayList parentPath = (ArrayList)remainPaths.get(0);
126 for ( int c = 0 ; c < cc ; c++) {
127 Object child = model.getChild(node,c);
128 remains.add(child);
129 ArrayList pp = new ArrayList(parentPath);
130 pp.add(child);
131 remainPaths.add(pp);
132 }
133
134 if (expanded.contains(node.toString()) ) {
135 TreePath tp = new TreePath(parentPath.toArray());
136 mirror.expandPath(tp);
137 }
138 remains.remove(0);
139 remainPaths.remove(0);
140 }
142 }
144
149 public void setMainPanel(OEMainPanel panel) {
150 mainPanel = panel;
151 }
152
153
155 public OEMainPanel getmainPanel(){
156 return mainPanel;
157 }
158
159 public void setModel(OntoTreeModel model){
160 if( model != null)
161 super.setModel(model);
162 else
163 super.setModel(null);
164 }
165
166
167 private void init(){
168 getSelectionModel().setSelectionMode(
169 TreeSelectionModel.SINGLE_TREE_SELECTION);
170 DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
171 renderer.setLeafIcon(renderer.getDefaultClosedIcon());
172 this.setCellRenderer(renderer);
173 addMouseListener(new MyMouseAdapter(this));
174 m_popUpMenu= new JPopupMenu();
175
176 add_item = new JMenuItem("Add sub class");
177 add_item.addActionListener(new AddSubActListener());
178
179 rename_item = new JMenuItem("Rename class");
180 rename_item.addActionListener(new RenameListener());
181
182 remove_item = new JMenuItem("Remove class");
183 remove_item.addActionListener(new RemoveActListener());
184
185 editURI_item = new JMenuItem("Edit URI");
186 editURI_item.addActionListener(new EditURIListener());
187
188
189 m_popUpMenu.add(add_item);
190 m_popUpMenu.add(rename_item);
191 m_popUpMenu.add(editURI_item);
192 m_popUpMenu.add(remove_item);
193
194
195
196 addTreeSelectionListener(this);
197
198 dragSource = DragSource.getDefaultDragSource() ;
199
200
201 DragGestureRecognizer dgr =
202 dragSource.createDefaultDragGestureRecognizer(
203 this, DnDConstants.ACTION_MOVE, this );
207
208
210 dgr.setSourceActions(dgr.getSourceActions() & ~InputEvent.BUTTON3_MASK);
211
212
214 DropTarget dropTarget = new DropTarget(this, this);
215
216 putClientProperty("JTree.lineStyle", "Angled");
217
218 }
220
221
222 public void dragGestureRecognized(DragGestureEvent event) {
223 ClassNode dragNode = this.getSelectedNode();
225
226 if (dragNode != null) {
227 transferable = (Transferable) dragNode;
229
230
231 Cursor cursor = DragSource.DefaultMoveNoDrop;
233
234 dragSource.startDrag(event, cursor, transferable, this);
236 }
237
238 }
240 public void drop(DropTargetDropEvent e) {
241
242 Transferable tr = e.getTransferable();
243
244 if (!tr.isDataFlavorSupported( ClassNode.CLASS_NODE_FLAVOR)) {
246 e.rejectDrop();
247 }
248
249 Point loc = e.getLocation();
251 TreePath destinationPath = getPathForLocation(loc.x, loc.y);
252
253 final String msg = testDropTarget(destinationPath, selectedTreePath);
254 if (msg != null) {
255 e.rejectDrop();
256
257 SwingUtilities.invokeLater(new Runnable() {
258 public void run() {
259 JOptionPane.showMessageDialog(
260 mainPanel, msg, "Error Dialog", JOptionPane.ERROR_MESSAGE
261 );
262 }
263 });
264 }
266
267 ClassNode newParent =
268 (ClassNode) destinationPath.getLastPathComponent();
269
270
271 TreePath temPath;
272 if (null == (temPath = selectedTreePath.getParentPath())) {
273 throw new GateRuntimeException (
274 "The node being dragged has no parent." );
275 }
276 ClassNode oldParent = (ClassNode) temPath.getLastPathComponent();
277
278 int action = e.getDropAction();
279
280 try {
281 oldParent.removeSubNode((ClassNode)transferable);
282 newParent.addSubNode((ClassNode)transferable);
283 e.acceptDrop (DnDConstants.ACTION_MOVE);
284 }
285 catch (java.lang.IllegalStateException ils) {
286 e.rejectDrop();
287 }
288
289 e.getDropTargetContext().dropComplete(true);
290
291
292 this.setExpandedState(temPath,true);
293 this.setExpandedState(destinationPath,true);
294
295 this.updateUI();
296
297
298 }
300 public void dragExit(DragSourceEvent dsde) {
301 dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
302 }
303
304 public void dragExit(DropTargetEvent e) {
305 }
306
307
308 public void dragEnter(DragSourceDragEvent dsde) {
309 dragSourceContext = dsde.getDragSourceContext();
310 }
311
312 public void dragEnter(DropTargetDragEvent e) {
313
314 }
315
316 public void dropActionChanged(DragSourceDragEvent e) {
317 dragSourceContext = e.getDragSourceContext();
318 }
319
320 public void dropActionChanged(DropTargetDragEvent e) {
321 e.acceptDrag(DnDConstants.ACTION_MOVE);
322 }
323
324 public void dragOver(DragSourceDragEvent e) {
325 dragSourceContext = e.getDragSourceContext();
326 }
327
328 public void dragOver(DropTargetDragEvent e) {
329 Point cursorLocationBis = e.getLocation();
331 TreePath destinationPath =
332 getPathForLocation(cursorLocationBis.x, cursorLocationBis.y);
333
334
335 if (testDropTarget(destinationPath, selectedTreePath) == null){
337
338 if ( null != dragSourceContext )
339 dragSourceContext.setCursor(DragSource.DefaultMoveDrop);
340
341 e.acceptDrag(DnDConstants.ACTION_MOVE);
342 }
343 else {
345
346 if ( null != dragSourceContext )
347 dragSourceContext.setCursor(DragSource.DefaultMoveNoDrop);
348
349 e.rejectDrag() ;
350 } }
353
354 public void dragDropEnd(DragSourceDropEvent e) {
355 }
357
358
363 private String testDropTarget(TreePath destination, TreePath dropper) {
364 boolean destinationPathIsNull = destination == null;
366 if (destinationPathIsNull)
367 return "Invalid drop location.";
368
369 ClassNode node = (ClassNode) destination.getLastPathComponent();
371
372 if (destination.equals(dropper))
373 return "Destination cannot be same as source";
374
375 if ( dropper.isDescendant(destination))
377 return "Destination node cannot be a descendant.";
378
379 if ( dropper.getParentPath().equals(destination))
381 return "Destination node cannot be a parent.";
382
383 return null;
384 }
386
387 public void valueChanged(TreeSelectionEvent evt) {
388 selectedTreePath = evt.getNewLeadSelectionPath();
389 if (selectedTreePath == null) {
390 selectedNode = null;
391 return;
392 }
393 selectedNode =
394 (ClassNode)selectedTreePath.getLastPathComponent();
395 }
397
398 public ClassNode getSelectedNode() {
399 return selectedNode;
400 }
401
402
403
404
405
406
407
408 class MyMouseAdapter extends MouseAdapter{
409 private EditableTreeView view;
410
411 public MyMouseAdapter(EditableTreeView view){
412 this.view=view;
413 }
414
415 public void mouseClicked(MouseEvent e){
416 TreePath path=view.getSelectionPath();
417 javax.swing.JTree tree = new javax.swing.JTree();
418 IFolder node =null;
420 if(SwingUtilities.isRightMouseButton(e)){
421 if( path != null){
422 node = (IFolder)path.getLastPathComponent();
424 ClassNode cnode = (ClassNode) node;
425 if (cnode.getSource() instanceof Ontology) {
426 rename_item.setEnabled(false);
427 remove_item.setEnabled(false);
428 }
429 else {
430 rename_item.setEnabled(true);
431 remove_item.setEnabled(true);
432 }
433
434 m_popUpMenu.show(view,e.getX(),e.getY());
435 }
436 }
437 }
438 }
440
441 class AddSubActListener implements ActionListener{
442 public void actionPerformed(ActionEvent e) {
443 JMenuItem item = (JMenuItem)e.getSource();
444 JPopupMenu popup = (JPopupMenu)item.getParent();
445 EditableTreeView tree = (EditableTreeView)popup.getInvoker();
446 OEMainPanel panel = tree.getmainPanel();
447
448 if (null == panel) {
449 throw new GateRuntimeException(
450 "the main panel of the editor is not reachable\n "+
451 "upon add sub class from the popup");
452 }
454 OntologyEditor oe = panel.getOntologyEditor();
455
456 if (null == oe) {
457 throw new GateRuntimeException(
458 "the ontology editor of the main panel is not reachable\n "+
459 "upon add sub class from the popup");
460 }
462 oe.addSubClass((int)EditableTreeView.this.getLocationOnScreen().getX()+50,
463 (int)EditableTreeView.this.getLocationOnScreen().getY()+50);
464
465 } }
468
469 class RemoveActListener implements ActionListener{
470 public void actionPerformed(ActionEvent e) {
471 JMenuItem item = (JMenuItem)e.getSource();
472 JPopupMenu popup = (JPopupMenu)item.getParent();
473 EditableTreeView tree = (EditableTreeView)popup.getInvoker();
474 ClassNode node = (ClassNode)tree.getLastSelectedPathComponent();
475 OEMainPanel panel = tree.getmainPanel();
476
477 if (null == panel) {
478 throw new GateRuntimeException(
479 "the main panel of the editor is not reachable\n "+
480 "upon add sub class from the popup");
481 }
483 OntologyEditor oe = panel.getOntologyEditor();
484
485 if (null == oe) {
486 throw new GateRuntimeException(
487 "the ontology editor of the main panel is not reachable\n "+
488 "upon add sub class from the popup");
489 }
491 oe.removeClass(node);
492
493 } }
496
497 class EditURIListener implements ActionListener{
498 public void actionPerformed(ActionEvent e) {
499 JMenuItem item = (JMenuItem)e.getSource();
500 JPopupMenu popup = (JPopupMenu)item.getParent();
501 EditableTreeView tree = (EditableTreeView)popup.getInvoker();
502 ClassNode node = (ClassNode)tree.getLastSelectedPathComponent();
503 OEMainPanel panel = tree.getmainPanel();
504
505 if (null == panel) {
506 throw new GateRuntimeException(
507 "the main panel of the editor is not reachable\n "+
508 "upon rename class from the popup");
509 }
511 OntologyEditor oe = panel.getOntologyEditor();
512
513 if (null == oe) {
514 throw new GateRuntimeException(
515 "the ontology editor of the main panel is not reachable\n "+
516 "upon rename class from the popup");
517 }
519 Object obj = node.getSource();
520 if ( null == obj ) {
521 throw new GateRuntimeException(
522 "the class/ontology is null; in EditURIListener");
523 }
524 if (obj instanceof OClass) {
525 oe.editClassURI((OClass)obj,0,0);
526 }
527 if (obj instanceof Ontology) {
528 oe.editURI((Ontology)obj,0,0);
529 }
530 } }
533
534 class RenameListener implements ActionListener{
535 public void actionPerformed(ActionEvent e) {
536 JMenuItem item = (JMenuItem)e.getSource();
537 JPopupMenu popup = (JPopupMenu)item.getParent();
538 EditableTreeView tree = (EditableTreeView)popup.getInvoker();
539 ClassNode node = (ClassNode)tree.getLastSelectedPathComponent();
540 OEMainPanel panel = tree.getmainPanel();
541
542 if (null == panel) {
543 throw new GateRuntimeException(
544 "the main panel of the editor is not reachable\n "+
545 "upon rename class from the popup");
546 }
548 OntologyEditor oe = panel.getOntologyEditor();
549
550 if (null == oe) {
551 throw new GateRuntimeException(
552 "the ontology editor of the main panel is not reachable\n "+
553 "upon rename class from the popup");
554 }
556 Object obj = node.getSource();
557 if ( null == obj ) {
558 throw new GateRuntimeException(
559 "the class/ontology is null; in EditURIListener");
560 }
561 if (obj instanceof OClass) {
562 OClass rc = (OClass)obj;
563 oe.renameClass(rc,node,0,0);
564 }
565 if (obj instanceof Ontology) {
566 Ontology ro = (Ontology) obj;
567 oe.renameOntology(ro,0,0);
568 }
569 EditableTreeView.this.updateUI();
570 }
572 }
574
575 }