001: // ResourceTreeBrowser.java
002: // $Id: ResourceTreeBrowser.java,v 1.33 2000/08/16 21:37:30 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1998.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigadmin.editors;
007:
008: import javax.swing.JTree;
009: import javax.swing.JOptionPane;
010: import javax.swing.KeyStroke;
011: import javax.swing.JDialog;
012: import javax.swing.JFrame;
013: import javax.swing.JPopupMenu;
014: import javax.swing.JMenuItem;
015: import javax.swing.tree.TreePath;
016: import javax.swing.tree.DefaultTreeCellRenderer;
017: import javax.swing.tree.DefaultTreeModel;
018: import javax.swing.tree.MutableTreeNode;
019: import javax.swing.event.TreeWillExpandListener;
020: import javax.swing.event.TreeExpansionEvent;
021: import javax.swing.tree.ExpandVetoException;
022: import javax.swing.tree.TreeNode;
023:
024: import java.awt.Cursor;
025: import java.awt.Point;
026: import java.awt.Component;
027: import java.awt.GridLayout;
028: import java.awt.Dimension;
029: import java.awt.Container;
030: import java.awt.event.ActionListener;
031: import java.awt.event.ActionEvent;
032: import java.awt.event.MouseListener;
033: import java.awt.event.MouseAdapter;
034: import java.awt.event.MouseEvent;
035: import java.awt.event.KeyEvent;
036: import java.awt.dnd.DropTarget;
037: import java.awt.dnd.DropTargetListener;
038: import java.awt.dnd.DropTargetDragEvent;
039: import java.awt.dnd.DropTargetDropEvent;
040: import java.awt.dnd.DropTargetEvent;
041: import java.awt.dnd.DnDConstants;
042: import java.awt.datatransfer.Transferable;
043: import java.awt.datatransfer.DataFlavor;
044: import java.awt.datatransfer.UnsupportedFlavorException;
045:
046: import java.io.IOException;
047:
048: import java.util.Vector;
049:
050: import org.w3c.jigadmin.RemoteResourceWrapper;
051: import org.w3c.jigadmin.PropertyManager;
052: import org.w3c.jigadmin.gui.Message;
053: import org.w3c.jigadmin.events.ResourceActionListener;
054: import org.w3c.jigadmin.events.ResourceActionEvent;
055: import org.w3c.jigadmin.widgets.Icons;
056:
057: import org.w3c.jigsaw.admin.RemoteAccessException;
058: import org.w3c.jigsaw.admin.RemoteResource;
059:
060: /**
061: * A JTree used to manage RemoteResource.
062: * @version $Revision: 1.33 $
063: * @author Benoît Mahé (bmahe@w3.org)
064: */
065: public class ResourceTreeBrowser extends JTree implements
066: DropTargetListener, ResourceActionListener {
067:
068: public static final String DELETE_RESOURCE_AC = "delres";
069:
070: protected RemoteResourceWrapperNode rootNode = null;
071: protected String resIdentifier = null;
072: protected String resClassname = null;
073: protected JDialog popup = null;
074:
075: private boolean isDragging = false;
076:
077: /**
078: * Our TreeWillExpandListener
079: */
080: TreeWillExpandListener twel = new TreeWillExpandListener() {
081: public void treeWillExpand(TreeExpansionEvent event)
082: throws ExpandVetoException {
083: TreeNode node = (TreeNode) event.getPath()
084: .getLastPathComponent();
085: ((RemoteNode) node).nodeWillExpand();
086: ((DefaultTreeModel) getModel()).reload(node);
087: }
088:
089: public synchronized void treeWillCollapse(
090: TreeExpansionEvent event) throws ExpandVetoException {
091: TreeNode node = (TreeNode) event.getPath()
092: .getLastPathComponent();
093: ((RemoteNode) node).nodeWillCollapse();
094: ((DefaultTreeModel) getModel()).reload(node);
095: }
096: };
097:
098: /**
099: * Our ActionListener
100: */
101: ActionListener al = new ActionListener() {
102: public void actionPerformed(ActionEvent evt) {
103: String command = evt.getActionCommand();
104: if (command.equals(DELETE_RESOURCE_AC)) {
105: //delete the selected resource
106: deleteSelectedResources();
107: }
108: }
109: };
110: /**
111: * Our MouseListener
112: */
113: MouseAdapter mouseAdapter = new MouseAdapter() {
114: public void mouseClicked(MouseEvent e) {
115: int selRow = getRowForLocation(e.getX(), e.getY());
116: TreePath selPath = getPathForLocation(e.getX(), e.getY());
117: if (selRow != -1) {
118: if (e.getClickCount() == 1) {
119: simpleClick(selPath);
120: } else if (e.getClickCount() == 2) {
121: doubleClick(selPath);
122: }
123: }
124: }
125:
126: public void mousePressed(MouseEvent e) {
127: maybeShowPopup(e);
128: }
129:
130: public void mouseReleased(MouseEvent e) {
131: maybeShowPopup(e);
132: }
133:
134: private void maybeShowPopup(MouseEvent e) {
135: if (e.isPopupTrigger()) {
136: RemoteResourceWrapper rrw = getSelectedResourceWrapper();
137: if (rrw != null)
138: getPopupMenu(rrw).show(e.getComponent(), e.getX(),
139: e.getY());
140: }
141: }
142: };
143:
144: //DropTargetListener
145:
146: DropTarget dropTarget;
147:
148: /**
149: * Is the mouse dragging something on the resource tree?
150: * @return a boolean
151: */
152: public boolean isDragging() {
153: return isDragging;
154: }
155:
156: /**
157: * a Drag operation has encountered the DropTarget
158: */
159: public void dragEnter(DropTargetDragEvent dropTargetDragEvent) {
160: dropTargetDragEvent.acceptDrag(DnDConstants.ACTION_COPY);
161: isDragging = true;
162: }
163:
164: /**
165: * The Drag operation has departed the DropTarget without dropping.
166: */
167: public void dragExit(DropTargetEvent dropTargetEvent) {
168: isDragging = false;
169: }
170:
171: /**
172: * a Drag operation is ongoing on the DropTarget
173: */
174: public void dragOver(DropTargetDragEvent dropTargetDragEvent) {
175: Point location = dropTargetDragEvent.getLocation();
176: TreePath path = getClosestPathForLocation(location.x,
177: location.y);
178: setSelectionPath(path);
179: }
180:
181: /**
182: * The user as modified the current drop gesture
183: */
184: public void dropActionChanged(
185: DropTargetDragEvent dropTargetDragEvent) {
186: }
187:
188: /**
189: * The Drag operation has terminated with a Drop on this DropTarget
190: */
191: public synchronized void drop(
192: DropTargetDropEvent dropTargetDropEvent) {
193: isDragging = false;
194: Transferable tr = dropTargetDropEvent.getTransferable();
195: DataFlavor required = TransferableResourceCell.RESOURCE_CELL_FLAVOR;
196: try {
197: if (tr.isDataFlavorSupported(required)) {
198: dropTargetDropEvent
199: .acceptDrop(DnDConstants.ACTION_COPY);
200: ResourceCell cell = (ResourceCell) tr
201: .getTransferData(required);
202: dropTargetDropEvent.dropComplete(dropResource(cell));
203: } else {
204: dropTargetDropEvent.rejectDrop();
205: }
206: } catch (IOException ex) {
207: ex.printStackTrace();
208: dropTargetDropEvent.rejectDrop();
209: } catch (UnsupportedFlavorException ufe) {
210: ufe.printStackTrace();
211: dropTargetDropEvent.rejectDrop();
212: }
213: }
214:
215: /**
216: * Drop a resource.
217: * @param cell The resource cell
218: * @see org.w3c.jigadmin.editors.ResourceCell
219: */
220: protected boolean dropResource(ResourceCell cell) {
221: RemoteResourceWrapper rrw = getSelectedResourceWrapper();
222: PropertyManager pm = PropertyManager.getPropertyManager();
223: try {
224: if (!pm.isExtensible(rrw)) {
225: return false;
226: } else if ((cell.isFrame() || cell.isFilter())
227: && (pm.isEditable(rrw))) {
228: //popupresource
229: popupResource(rrw);
230: return true;
231: } else if (((cell.isContainer() || cell.isResource()) && (!rrw
232: .getResource().isIndexersCatalog()))
233: || (rrw.getResource().isIndexersCatalog() && cell
234: .isIndexer())) {
235: //must be droppped on a Container
236: if (rrw.getResource().isContainer()) {
237: //add the resource
238: String identifier = getIdentifier(cell, rrw);
239: if (identifier != null) {
240: TreePath path = getSelectionPath();
241: addResource(identifier, cell.toString(), rrw,
242: path);
243: return true;
244: }
245: }
246: }
247: return false;
248: } catch (RemoteAccessException ex) {
249: Message.showErrorMessage(this , ex);
250: return false;
251: }
252: }
253:
254: //End of DropTargetListener
255:
256: /**
257: * A resource action occured.
258: * @param e the ResourceActionEvent
259: */
260: public void resourceActionPerformed(ResourceActionEvent e) {
261: int cmd = e.getResourceActionCommand();
262: if (isShowing()) {
263: if (cmd == ResourceActionEvent.DELETE_EVENT) {
264: deleteSelectedResources();
265: } else if (cmd == ResourceActionEvent.REINDEX_EVENT) {
266: reindexSelectedResources(false); //FIXME
267: } else if (cmd == ResourceActionEvent.REFERENCE_EVENT) {
268: showReferenceDocumentation();
269: } else if (cmd == ResourceActionEvent.ADD_EVENT) {
270: addResourceToSelectedContainer();
271: } else if (cmd == ResourceActionEvent.EDIT_EVENT) {
272: doubleClick(getSelectionPath());
273: }
274: }
275: }
276:
277: /**
278: * Add a resource to the resource wrapped.
279: * @param identifier The new resource identifier
280: * @param classname The new resource class name
281: * @param rrwf the Wrapper of the father resource
282: * @param fpath The path of the father node
283: */
284: protected void addResource(String identifier, String classname,
285: RemoteResourceWrapper rrwf, TreePath fpath)
286: throws RemoteAccessException {
287: RemoteResource rc = rrwf.getResource().registerResource(
288: identifier, classname);
289: RemoteResourceWrapper nrrw = new RemoteResourceWrapper(rrwf, rc);
290: RemoteResourceWrapperNode parent = (RemoteResourceWrapperNode) fpath
291: .getLastPathComponent();
292: RemoteResourceWrapperNode child = new RemoteResourceWrapperNode(
293: parent, nrrw, identifier);
294: ((DefaultTreeModel) getModel())
295: .insertNodeInto(child, parent, 0);
296: expandPath(fpath);
297: }
298:
299: /**
300: * Add a resource to the selected container.
301: * @param classname the resource class name
302: * @param identifier the resource identifier
303: */
304: protected void addResourceToSelectedContainer(String classname,
305: String identifier) throws RemoteAccessException {
306: RemoteResourceWrapper rrw = getSelectedResourceWrapper();
307: if (rrw == null)
308: return;
309: addResource(identifier, classname, rrw, getSelectionPath());
310: }
311:
312: /**
313: * Get (compute) the resource identifier of the dropped resource.
314: * @param cell the ResourceCell dropped
315: * @param rrw the RemoteResourceWrapper of the father
316: * @return a String instance
317: * @see org.w3c.jigadmin.editors.ResourceCell
318: */
319: protected String getIdentifier(ResourceCell cell,
320: RemoteResourceWrapper rrw) throws RemoteAccessException {
321: String id = cell.toString();
322: id = id.substring(id.lastIndexOf('.') + 1);
323: String names[] = rrw.getResource()
324: .enumerateResourceIdentifiers();
325: String identifier = id;
326: int cpt = 0;
327: int i = 0;
328: loop: while (i < names.length) {
329: if (names[i].equals(identifier)) {
330: identifier = id + String.valueOf(++cpt);
331: i = 0;
332: continue loop;
333: }
334: i++;
335: }
336: return identifier;
337: }
338:
339: /**
340: * Get the RemoteResourceWrapper associated to the selected node.
341: * @return a RemoteResourceWrapper
342: */
343: protected RemoteResourceWrapper getSelectedResourceWrapper() {
344: RemoteResourceWrapperNode node = (RemoteResourceWrapperNode) getLastSelectedPathComponent();
345: if (node == null)
346: return null;
347: return node.getResourceWrapper();
348: }
349:
350: /**
351: * Get the RemoteResourceWrapper associated to the selected node.
352: * @param path the selected path
353: * @return a RemoteResourceWrapper
354: */
355: protected RemoteResourceWrapper getSelectedResourceWrapper(
356: TreePath path) {
357: if (path == null)
358: return null;
359: RemoteResourceWrapperNode node = (RemoteResourceWrapperNode) path
360: .getLastPathComponent();
361: return node.getResourceWrapper();
362: }
363:
364: /**
365: * Get the Panel used to add a new resource
366: * @param title The title
367: * @param rrw The wrapper of the father RemoteResource
368: * @return a AddResourcePanel instance
369: * @see org.w3c.jigadmin.editors.AddResourcePanel
370: */
371: protected AddResourcePanel getAddResourcePanel(String title,
372: RemoteResourceWrapper rrw) throws RemoteAccessException {
373: return new AddResourcePanel(title, rrw, this );
374: }
375:
376: /**
377: * Popup a "add resource" Dialog
378: * @param title the popup title
379: * @param rrw The wrapper of the father RemoteResource
380: */
381: protected void popupAddResourceDialog(String title,
382: RemoteResourceWrapper rrw) {
383: try {
384: AddResourcePanel arp = getAddResourcePanel(title, rrw);
385: JFrame frame = rootNode.getResourceWrapper()
386: .getServerBrowser().getFrame();
387: popup = new JDialog(frame, title, false);
388: Container cont = popup.getContentPane();
389: cont.setLayout(new GridLayout(1, 1));
390: cont.add(arp);
391: popup.setSize(new Dimension(600, 220));
392: popup.show();
393: arp.getFocus();
394: while (!arp.waitForCompletion())
395: ;
396: } catch (RemoteAccessException ex) {
397: Message.showErrorMessage(this , ex);
398: }
399: }
400:
401: /**
402: * Dispose the "add resource" popup
403: */
404: protected void disposeAddResourcePopup() {
405: if (popup != null) {
406: popup.dispose();
407: popup = null;
408: }
409: }
410:
411: /**
412: * Specify some properties of the resource to add
413: * @param classnema the new resource class name
414: * @param identifier the new resource identifier
415: */
416: protected void setResourceToAdd(String classname, String identifier) {
417: this .resClassname = classname;
418: this .resIdentifier = identifier;
419: }
420:
421: private void performAddResourceToSelectedContainer() {
422: popupAddResourceDialog("Add Resource",
423: getSelectedResourceWrapper());
424: if ((resIdentifier != null) && (resClassname != null)) {
425: try {
426: addResourceToSelectedContainer(resClassname,
427: resIdentifier);
428: } catch (RemoteAccessException ex) {
429: Message.showErrorMessage(this , ex);
430: }
431: }
432: }
433:
434: /**
435: * Add a (new) resource to the container associated to the
436: * selected node.
437: */
438: protected void addResourceToSelectedContainer() {
439: RemoteResourceWrapper selected = getSelectedResourceWrapper();
440: PropertyManager pm = PropertyManager.getPropertyManager();
441: try {
442: if (selected == null) {
443: JOptionPane.showMessageDialog(this ,
444: "No Container selected", "Error",
445: JOptionPane.ERROR_MESSAGE);
446: return;
447: } else if (!pm.isExtensible(selected)) {
448: JOptionPane
449: .showMessageDialog(this ,
450: "The resource selected is not "
451: + "extensible.", "Error",
452: JOptionPane.ERROR_MESSAGE);
453: } else if (selected.getResource().isContainer()) {
454: Thread thread = new Thread() {
455: public void run() {
456: performAddResourceToSelectedContainer();
457: }
458: };
459: thread.start();
460: } else {
461: JOptionPane.showMessageDialog(this ,
462: "The resource selected is not " + "container.",
463: "Error", JOptionPane.ERROR_MESSAGE);
464: }
465: } catch (RemoteAccessException ex) {
466: Message.showErrorMessage(this , ex);
467: }
468: }
469:
470: /**
471: * Filter the TreePath array. Remove all nodes that have one of their
472: * parent in this array.
473: * @param paths the TreePath array
474: * @return the filtered array
475: */
476: protected TreePath[] removeDescendants(TreePath[] paths) {
477: if (paths == null)
478: return null;
479: Vector newpaths = new Vector();
480: for (int i = 0; i < paths.length; i++) {
481: TreePath currentp = paths[i];
482: boolean hasParent = false;
483: for (int j = 0; j < paths.length; j++) {
484: if ((!(j == i)) && (paths[j].isDescendant(currentp)))
485: hasParent = true;
486: }
487: if (!hasParent)
488: newpaths.addElement(currentp);
489: }
490: TreePath[] filteredPath = new TreePath[newpaths.size()];
491: newpaths.copyInto(filteredPath);
492: return filteredPath;
493: }
494:
495: /**
496: * Reindex the containers associated to the selected nodes.
497: * Display an error message (dialog) if there is no node selected or
498: * if one of the selected resource is not a ResourceContainer.
499: * @param rec recursivly?
500: */
501: protected void reindexSelectedResources(boolean rec) {
502: TreePath path[] = removeDescendants(getSelectionPaths());
503: if (path == null) {
504: JOptionPane.showMessageDialog(this ,
505: "No Container selected", "Error",
506: JOptionPane.ERROR_MESSAGE);
507: return;
508: }
509: if (path.length > 0) {
510: int result = JOptionPane.showConfirmDialog(this ,
511: "Reindex selected resource(s)?",
512: "Reindex Resource(s)", JOptionPane.YES_NO_OPTION);
513: if (result == JOptionPane.YES_OPTION) {
514: for (int i = 0; i < path.length; i++) {
515: RemoteResourceWrapper rrw = getSelectedResourceWrapper(path[i]);
516: if (rrw == null)
517: continue;
518: try {
519: reindexResource(rrw, rec);
520: } catch (RemoteAccessException ex) {
521: Message.showErrorMessage(this , ex);
522: continue;
523: }
524: }
525: }
526: }
527: }
528:
529: /**
530: * Reindex the container wrapped by the given wrapper.
531: * Display an error message (dialog) if the resource
532: * is not a ResourceContainer.
533: * @param rrw the RemoteResourceWrapper
534: * @param rec recursivly?
535: * @exception RemoteAccessException if a Remote Error occurs
536: */
537: protected void reindexResource(RemoteResourceWrapper rrw,
538: boolean rec) throws RemoteAccessException {
539: RemoteResource rr = rrw.getResource();
540: if (rr.isContainer()) {
541: rr.reindex(rec);
542: } else {
543: JOptionPane.showMessageDialog(this , rr
544: .getValue("identifier")
545: + " is not a container.", "Error",
546: JOptionPane.ERROR_MESSAGE);
547: }
548: }
549:
550: /**
551: * Delete the resources associated to the selected nodes.
552: * Display an error message if there is no node selected or if
553: * the resource is not editable.
554: */
555: protected void deleteSelectedResources() {
556: PropertyManager pm = PropertyManager.getPropertyManager();
557: TreePath path[] = removeDescendants(getSelectionPaths());
558: if (path == null) {
559: JOptionPane.showMessageDialog(this , "No Resource selected",
560: "Error", JOptionPane.ERROR_MESSAGE);
561: return;
562: }
563: if (path.length > 0) {
564: int result = JOptionPane.showConfirmDialog(this ,
565: "Delete selected resource(s)?",
566: "Delete Resource(s)", JOptionPane.YES_NO_OPTION);
567: if (result == JOptionPane.YES_OPTION) {
568: DefaultTreeModel model = (DefaultTreeModel) getModel();
569: for (int i = 0; i < path.length; i++) {
570: RemoteResourceWrapper rrw = getSelectedResourceWrapper(path[i]);
571: if (rrw == null)
572: continue;
573: try {
574: if (pm.isEditable(rrw)) {
575: deleteResource(rrw);
576: MutableTreeNode node = (MutableTreeNode) path[i]
577: .getLastPathComponent();
578: model.removeNodeFromParent(node);
579: } else {
580: String name = (String) rrw.getResource()
581: .getValue("identifier");
582: Message.showInformationMessage(this , name
583: + " is not editable");
584: }
585: } catch (RemoteAccessException ex) {
586: Message.showErrorMessage(this , ex);
587: continue;
588: }
589: }
590: }
591: }
592: }
593:
594: /**
595: * Delete the resource wrapped by the given wrapper
596: * @param rrw The RemoteResourceWrapper
597: */
598: protected void deleteResource(RemoteResourceWrapper rrw)
599: throws RemoteAccessException {
600: rrw.getResource().delete();
601: }
602:
603: /**
604: * Display (in another frame) the reference documentation relative
605: * to the resource associated to the selected node.
606: * Display en error message (dialog) if no node is selected.
607: */
608: protected void showReferenceDocumentation() {
609: try {
610: RemoteResourceWrapper selected = getSelectedResourceWrapper();
611: if (selected == null) {
612: JOptionPane.showMessageDialog(this ,
613: "No Resource selected", "Error",
614: JOptionPane.ERROR_MESSAGE);
615: return;
616: } else {
617: String url = (String) selected.getResource().getValue(
618: "help-url");
619: MiniBrowser.showDocumentationURL(url,
620: "Reference documentation");
621: }
622: } catch (RemoteAccessException rae) {
623: Message.showErrorMessage(this , rae);
624: } catch (Exception ex) {
625:
626: }
627: }
628:
629: /**
630: * A simle click occured on the node with the given path.
631: * @param path The path where the click occured.
632: */
633: protected void simpleClick(TreePath path) {
634: }
635:
636: /**
637: * A double click occured on the node with the given path.
638: * @param path The path where the double click occured.
639: */
640: protected void doubleClick(TreePath path) {
641: if (path == null)
642: return;
643: RemoteResourceWrapperNode node = (RemoteResourceWrapperNode) path
644: .getLastPathComponent();
645: RemoteResourceWrapper rrw = node.getResourceWrapper();
646: PropertyManager pm = PropertyManager.getPropertyManager();
647: if (pm.isEditable(rrw))
648: popupResource(node.getResourceWrapper());
649: else {
650: try {
651: String name = (String) rrw.getResource().getValue(
652: "identifier");
653: Message.showInformationMessage(this , name
654: + " is not editable");
655: } catch (RemoteAccessException ex) {
656: Message.showErrorMessage(this , ex);
657: }
658: }
659: }
660:
661: /**
662: * Popup a dialog where the user can edit the resource properties.
663: * @param rrw the wrapper if the resource to edit.
664: */
665: protected void popupResource(RemoteResourceWrapper rrw) {
666: rrw.getServerBrowser().popupResource(rrw);
667: }
668:
669: /**
670: * Set the cursor.
671: * @param a cursor type
672: */
673: protected void setCursor(int cursor) {
674: rootNode.getResourceWrapper().getServerBrowser().setCursor(
675: cursor);
676: }
677:
678: /**
679: * The popup menu action listener.
680: */
681: ActionListener pmal = new ActionListener() {
682: public void actionPerformed(ActionEvent evt) {
683: setCursor(Cursor.WAIT_CURSOR);
684: String command = evt.getActionCommand();
685: if (command.equals("del")) {
686: deleteSelectedResources();
687: } else if (command.equals("add")) {
688: addResourceToSelectedContainer();
689: } else if (command.equals("reindex")) {
690: reindexSelectedResources(true);
691: } else if (command.equals("reindex-locally")) {
692: reindexSelectedResources(false);
693: } else if (command.equals("info")) {
694: showReferenceDocumentation();
695: } else if (command.equals("edit")) {
696: doubleClick(getSelectionPath());
697: }
698: setCursor(Cursor.DEFAULT_CURSOR);
699: }
700: };
701:
702: /**
703: * Get the popup menu relative to the selected resource.
704: * @param rrw the wrapper of the resource
705: * @return a JPopupMenu instance
706: */
707: protected JPopupMenu getPopupMenu(RemoteResourceWrapper rrw) {
708:
709: JPopupMenu popupMenu = new JPopupMenu();
710:
711: boolean container = false;
712: boolean editable = false;
713:
714: try {
715: PropertyManager pm = PropertyManager.getPropertyManager();
716: container = rrw.getResource().isContainer();
717: editable = pm.isEditable(rrw);
718: } catch (RemoteAccessException ex) {
719: container = false;
720: }
721:
722: JMenuItem menuItem = null;
723:
724: if (container) {
725: menuItem = new JMenuItem("Reindex", Icons.reindexIcon);
726: menuItem.addActionListener(pmal);
727: menuItem.setActionCommand("reindex");
728: popupMenu.add(menuItem);
729:
730: menuItem = new JMenuItem("Reindex Locally",
731: Icons.reindexIcon);
732: menuItem.addActionListener(pmal);
733: menuItem.setActionCommand("reindex-locally");
734: popupMenu.add(menuItem);
735:
736: menuItem = new JMenuItem("Add resource", Icons.addIcon);
737: menuItem.addActionListener(pmal);
738: menuItem.setActionCommand("add");
739: popupMenu.add(menuItem);
740: }
741:
742: if (editable) {
743: menuItem = new JMenuItem("Delete resource",
744: Icons.deleteIcon);
745: menuItem.addActionListener(pmal);
746: menuItem.setActionCommand("del");
747: popupMenu.add(menuItem);
748:
749: menuItem = new JMenuItem("Edit resource", Icons.editIcon);
750: menuItem.addActionListener(pmal);
751: menuItem.setActionCommand("edit");
752: popupMenu.add(menuItem);
753:
754: popupMenu.addSeparator();
755: }
756:
757: menuItem = new JMenuItem("Info", Icons.infoIcon);
758: menuItem.addActionListener(pmal);
759: menuItem.setActionCommand("info");
760: popupMenu.add(menuItem);
761:
762: return popupMenu;
763: }
764:
765: /**
766: * Constructor
767: * @param root The root node
768: */
769: protected ResourceTreeBrowser(RemoteResourceWrapperNode root) {
770: super (root);
771: this .rootNode = root;
772: dropTarget = new DropTarget(this , this );
773: setEditable(true);
774: setLargeModel(true);
775: setScrollsOnExpand(true);
776: setUI(new ResourceTreeUI());
777: addTreeWillExpandListener(twel);
778: KeyStroke delK = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
779: registerKeyboardAction(al, DELETE_RESOURCE_AC, delK,
780: WHEN_FOCUSED);
781: addMouseListener(mouseAdapter);
782: }
783:
784: /**
785: * Get a ResourceTreeBrowser.
786: * @param rrw The root resource
787: * @param rootName The root identifier.
788: * @return a ResourceTreeBrowser instance
789: */
790: public static ResourceTreeBrowser getResourceTreeBrowser(
791: RemoteResourceWrapper rrw, String rootName) {
792: RemoteResourceWrapperNode rnode = new RemoteResourceWrapperNode(
793: rrw, rootName);
794: ResourceTreeBrowser treebrowser = new ResourceTreeBrowser(rnode);
795: return treebrowser;
796: }
797: }
|