KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > util > explorer > swing > lib > DynamicTree


1 /*====================================================================
2
3 Objectweb Explorer Framework
4 Copyright (C) 2000-2005 INRIA - USTL - LIFL - GOAL
5 Contact: openccm@objectweb.org
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA
21
22 Initial developer(s): Jerome Moroy, Philippe Merle.
23 Contributor(s): ______________________________________.
24
25 ====================================================================
26 $Id: DynamicTree.java,v 1.5 2005/07/06 15:36:02 moroy Exp $
27 ====================================================================*/

28
29 package org.objectweb.util.explorer.swing.lib;
30
31 import java.awt.Component JavaDoc;
32 import java.awt.Dimension JavaDoc;
33 import java.awt.Insets JavaDoc;
34 import java.awt.Point JavaDoc;
35 import java.awt.Rectangle JavaDoc;
36 import java.awt.datatransfer.DataFlavor JavaDoc;
37 import java.awt.datatransfer.Transferable JavaDoc;
38 import java.awt.datatransfer.UnsupportedFlavorException JavaDoc;
39 import java.awt.dnd.Autoscroll JavaDoc;
40 import java.awt.dnd.DnDConstants JavaDoc;
41 import java.awt.dnd.DragGestureEvent JavaDoc;
42 import java.awt.dnd.DragGestureListener JavaDoc;
43 import java.awt.dnd.DragSource JavaDoc;
44 import java.awt.dnd.DragSourceContext JavaDoc;
45 import java.awt.dnd.DragSourceDragEvent JavaDoc;
46 import java.awt.dnd.DragSourceDropEvent JavaDoc;
47 import java.awt.dnd.DragSourceEvent JavaDoc;
48 import java.awt.dnd.DragSourceListener JavaDoc;
49 import java.awt.dnd.DropTarget JavaDoc;
50 import java.awt.dnd.DropTargetDragEvent JavaDoc;
51 import java.awt.dnd.DropTargetDropEvent JavaDoc;
52 import java.awt.dnd.DropTargetEvent JavaDoc;
53 import java.awt.dnd.DropTargetListener JavaDoc;
54 import java.awt.dnd.InvalidDnDOperationException JavaDoc;
55 import java.awt.event.ActionEvent JavaDoc;
56 import java.awt.event.MouseAdapter JavaDoc;
57 import java.awt.event.MouseEvent JavaDoc;
58 import java.io.IOException JavaDoc;
59 import java.net.URL JavaDoc;
60 import java.util.Arrays JavaDoc;
61 import java.util.Enumeration JavaDoc;
62 import java.util.HashMap JavaDoc;
63 import java.util.Iterator JavaDoc;
64 import java.util.List JavaDoc;
65 import java.util.Map JavaDoc;
66 import java.util.StringTokenizer JavaDoc;
67 import java.util.Vector JavaDoc;
68
69 import javax.swing.AbstractAction JavaDoc;
70 import javax.swing.ButtonGroup JavaDoc;
71 import javax.swing.Icon JavaDoc;
72 import javax.swing.JCheckBoxMenuItem JavaDoc;
73 import javax.swing.JMenu JavaDoc;
74 import javax.swing.JMenuBar JavaDoc;
75 import javax.swing.JMenuItem JavaDoc;
76 import javax.swing.JOptionPane JavaDoc;
77 import javax.swing.JPopupMenu JavaDoc;
78 import javax.swing.JRadioButtonMenuItem JavaDoc;
79 import javax.swing.JSeparator JavaDoc;
80 import javax.swing.JToolBar JavaDoc;
81 import javax.swing.JTree JavaDoc;
82 import javax.swing.event.TreeExpansionEvent JavaDoc;
83 import javax.swing.event.TreeExpansionListener JavaDoc;
84 import javax.swing.event.TreeSelectionEvent JavaDoc;
85 import javax.swing.event.TreeSelectionListener JavaDoc;
86 import javax.swing.event.TreeWillExpandListener JavaDoc;
87 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
88 import javax.swing.tree.DefaultTreeCellRenderer JavaDoc;
89 import javax.swing.tree.DefaultTreeModel JavaDoc;
90 import javax.swing.tree.DefaultTreeSelectionModel JavaDoc;
91 import javax.swing.tree.TreeNode JavaDoc;
92 import javax.swing.tree.TreePath JavaDoc;
93 import javax.swing.tree.TreeSelectionModel JavaDoc;
94
95 import org.objectweb.fractal.api.NoSuchInterfaceException;
96 import org.objectweb.fractal.api.control.BindingController;
97 import org.objectweb.fractal.api.control.ContentController;
98 import org.objectweb.fractal.api.control.IllegalBindingException;
99 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
100 import org.objectweb.fractal.api.control.LifeCycleController;
101 import org.objectweb.fractal.api.control.NameController;
102 import org.objectweb.fractal.api.control.SuperController;
103 import org.objectweb.fractal.api.factory.Factory;
104 import org.objectweb.fractal.api.factory.InstantiationException;
105 import org.objectweb.fractal.util.Fractal;
106 import org.objectweb.util.explorer.api.Context;
107 import org.objectweb.util.explorer.api.DropAction;
108 import org.objectweb.util.explorer.api.Entry;
109 import org.objectweb.util.explorer.api.IconProvider;
110 import org.objectweb.util.explorer.api.Info;
111 import org.objectweb.util.explorer.api.MenuItemTreeView;
112 import org.objectweb.util.explorer.api.RootContext;
113 import org.objectweb.util.explorer.api.RootEntry;
114 import org.objectweb.util.explorer.api.Tree;
115 import org.objectweb.util.explorer.api.TreeView;
116 import org.objectweb.util.explorer.context.api.ContextContainerFactory;
117 import org.objectweb.util.explorer.core.common.api.ContextContainer;
118 import org.objectweb.util.explorer.core.common.api.Description;
119 import org.objectweb.util.explorer.core.common.api.ExplorerConstants;
120 import org.objectweb.util.explorer.core.common.api.Synchronization;
121 import org.objectweb.util.explorer.core.common.api.TextComponent;
122 import org.objectweb.util.explorer.core.common.lib.BindingFeature;
123 import org.objectweb.util.explorer.core.common.lib.DefaultTreeView;
124 import org.objectweb.util.explorer.core.common.lib.RootContextContainer;
125 import org.objectweb.util.explorer.core.common.lib.TreeBindingFeature;
126 import org.objectweb.util.explorer.core.dnd.api.DnDDescription;
127 import org.objectweb.util.explorer.core.dnd.api.DnDDescriptions;
128 import org.objectweb.util.explorer.core.dnd.lib.DefaultDropTreeView;
129 import org.objectweb.util.explorer.core.dnd.lib.EntryTransferable;
130 import org.objectweb.util.explorer.core.menu.lib.DefaultMenuItemTreeView;
131 import org.objectweb.util.explorer.core.naming.lib.DefaultEntry;
132 import org.objectweb.util.explorer.core.role.api.RoleManager;
133 import org.objectweb.util.explorer.core.role.api.RoleProvider;
134 import org.objectweb.util.explorer.core.root.lib.DefaultRootEntry;
135 import org.objectweb.util.explorer.interpreter.api.DescriptionInterpreter;
136 import org.objectweb.util.explorer.resolver.api.PropertyResolver;
137 import org.objectweb.util.explorer.swing.api.Explorer;
138 import org.objectweb.util.explorer.swing.icon.IconFileProvider;
139 import org.objectweb.util.explorer.swing.menu.GenericAction;
140 import org.objectweb.util.trace.Trace;
141 import org.objectweb.util.trace.TraceSystem;
142
143 /**
144  *
145  *
146  * @author <a HREF="mailto:Jerome.Moroy@lifl.fr">Jérôme Moroy</a>,
147  * <a HREF="mailto:Philippe.Merle@lifl.fr">Philippe Merle</a>.
148  *
149  * @version 0.1
150  */

151 public class DynamicTree
152      extends JTree JavaDoc
153   implements Tree JavaDoc, BindingController, LifeCycleController, Explorer, Autoscroll JavaDoc
154 {
155
156     //===================================================================
157
//
158
// Internal States.
159
//
160
// ==================================================================
161

162     /**
163      * The binding feature to use.
164      */

165     protected BindingFeature bindingFeature_ = null;
166
167     /**
168      * The root node
169      */

170     protected DefaultMutableTreeNode JavaDoc rootNode_;
171
172     /**
173      * Model to handle nodes.
174      */

175     protected DefaultTreeModel JavaDoc treeModel_;
176
177     /**
178      * The context containing the initial entries of the tree.
179      */

180     protected List JavaDoc initialContext_;
181
182     /**
183      * The graphical initial context (The entries might be replaced by their
184      * associated context)
185      */

186     protected ContextContainer graphicalInitialContext_;
187
188     /**
189      * List of elements which have already been added into the initial context.
190      * This list is used to register the fact that the entry has already been
191      * added into the tree. Then, it hasn't to take into account the expansion
192      * level defined in the RootEntry.
193      */

194     protected List JavaDoc alreadyInInitialContext_ = null;
195
196     /**
197      * Model to manage node selection
198      */

199     protected DefaultTreeSelectionModel JavaDoc selectionModel_;
200     
201     
202     /** To know if popup menus have to be displayed or not. */
203     protected boolean popupEnabled_ = true;
204
205     /**
206      * Registers the state of the node.
207      */

208     protected Map JavaDoc nodeStates_ = null;
209
210     /**
211      * Refers to the selected node.
212      */

213     protected JMenuBar JavaDoc menuBar_ = null;
214
215     /**
216      * The customizable menus.
217      */

218     protected JMenu JavaDoc actionMenu_ = null;
219
220     /**
221      * The customizable menus.
222      */

223     protected JMenu JavaDoc roleMenu_ = null;
224
225     /**
226      * The menu bar of the frame.
227      */

228     protected JToolBar JavaDoc toolBar_ = null;
229
230     /** The number of element of the toolBar which has to be removed. */
231     protected int nbElementsToRemove_ = 0;
232
233     /**
234      * To know if the application allows the selection of several roles at the
235      * same time.
236      */

237     protected boolean multipleRoles_ = false;
238
239     // Drag and Drop attributes
240

241     /** To know if the Drag and Drop have to be enabled or not */
242     protected boolean dndEnabled_ = true;
243
244     /** The DragSource to use */
245     protected DragSource JavaDoc dragSource_;
246
247     /** The DragGestureListener to use */
248     protected DragGestureListener JavaDoc dragGestureListener_;
249
250     /** The DragSourceListener to use */
251     protected DragSourceListener JavaDoc dragSourceListener_;
252
253     /** The dragAction */
254     protected int dragAction_ = DnDConstants.ACTION_COPY_OR_MOVE
255             | DnDConstants.ACTION_LINK;
256
257     /** The allowed drop action */
258     protected int acceptableActions_ = DnDConstants.ACTION_COPY_OR_MOVE
259             | DnDConstants.ACTION_LINK;
260
261     /** The DropTarget */
262     protected DropTarget JavaDoc dropTarget_;
263
264     /** The DropTargetListener to use */
265     protected DropTargetListener JavaDoc dropTargetListener_;
266     
267     // ==================================================================
268
//
269
// Constructors.
270
//
271
// ==================================================================
272

273     /**
274      * Calls by the constructor
275      */

276     private void initDragAndDrop(){
277         // Drag
278
dragSource_ = DragSource.getDefaultDragSource();
279         dragSourceListener_ = new TreeDragSourceListener();
280         dragGestureListener_ = new TreeDragGestureListener();
281         dragSource_.createDefaultDragGestureRecognizer(this, dragAction_, dragGestureListener_);
282         
283         // Drop
284
dropTargetListener_ = new TreeDropTargetListener();
285         dropTarget_ = new DropTarget JavaDoc(this, acceptableActions_, dropTargetListener_, true);
286     }
287     
288     public DynamicTree() {
289         super();
290         
291         bindingFeature_ = new TreeBindingFeature();
292         
293         initialContext_ = new Vector JavaDoc();
294         alreadyInInitialContext_ = new Vector JavaDoc();
295
296         nodeStates_ = new HashMap JavaDoc();
297         //selectedNode_ = "";
298

299         rootNode_ = new DefaultMutableTreeNode JavaDoc(new DefaultEntry("Root",graphicalInitialContext_));
300         treeModel_ = new MyTreeModel(rootNode_);
301         setModel(treeModel_);
302         
303         selectionModel_ = new DefaultTreeSelectionModel JavaDoc();
304         selectionModel_.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
305         setSelectionModel(selectionModel_);
306         addMouseListener(new MyMouseAdapter());
307         addTreeWillExpandListener(new MyTreeWillExpandListener());
308         addTreeExpansionListener(new MyTreeExpansionListener());
309         addTreeSelectionListener(new MyTreeSelectionListener());
310         setCellRenderer(new MyTreeCellRenderer());
311         
312         initDragAndDrop();
313         
314         setToolTipText("");
315         setShowsRootHandles(true);
316         collapseRow(0);
317         expandRow(0);
318         setRootVisible(false);
319     }
320
321     // ==================================================================
322
//
323
// Internal methods.
324
//
325
// ==================================================================
326

327     protected Trace getTrace(){
328         return TraceSystem.get("explorer");
329     }
330
331     /**
332      * Returns the entry associates to a node
333      *
334      * @param o The node
335      * @return The associated entry
336      */

337     protected Entry objectToEntry(Object JavaDoc o) {
338         if (o != null) {
339             DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) o;
340             return (Entry) node.getUserObject();
341         }
342         return null;
343     }
344
345     /**
346      * Gets a string representation of the path
347      *
348      * @param node The node
349      * @return The path from th root to the node
350      *
351      */

352     protected String JavaDoc pathToString(DefaultMutableTreeNode JavaDoc node) {
353         StringBuffer JavaDoc sf = new StringBuffer JavaDoc();
354         Object JavaDoc[] o = node.getUserObjectPath();
355         for (int i = 1; i < o.length; i++) {
356             sf.append(((Entry) o[i]).getName().toString());
357             if (i != o.length - 1)
358                 sf.append("/");
359         }
360         return sf.toString();
361     }
362     
363     /**
364      * Gets a string representation of the path
365      *
366      * @param node The node
367      * @return The path from th root to the node
368      *
369      */

370     protected String JavaDoc pathToString(TreePath JavaDoc path) {
371         if(path!=null)
372             return pathToString((DefaultMutableTreeNode JavaDoc)path.getLastPathComponent());
373         return "";
374         
375     }
376     
377     protected DefaultMutableTreeNode JavaDoc getChildren(DefaultMutableTreeNode JavaDoc parent, String JavaDoc name){
378         Enumeration JavaDoc enumeration = parent.children();
379         while (enumeration.hasMoreElements()) {
380             DefaultMutableTreeNode JavaDoc childNode = (DefaultMutableTreeNode JavaDoc) enumeration.nextElement();
381             Entry entry = (Entry)childNode.getUserObject();
382             if(name.equals(entry.getName())){
383                 return childNode;
384             }
385             
386         }
387         return null;
388     }
389     
390     /**
391      * Provides the path associated to the given representation.
392      * Each node needs to be separated by the '/' character.
393      * @param path The representation of the path
394      * @return The associated path from the tree.
395      */

396     protected TreePath JavaDoc stringToPath(String JavaDoc path) {
397         if (path != null && !path.equals("")) {
398             // Splits the path representation
399
// and for each element, tries to obtain the child
400
// of the current element.
401
StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(path,"/");
402             DefaultMutableTreeNode JavaDoc parentNode = rootNode_;
403             DefaultMutableTreeNode JavaDoc childNode = null;
404             while (st.hasMoreTokens()) {
405                 String JavaDoc currentPath = st.nextToken();
406                 childNode = getChildren(parentNode, currentPath);
407                 if(childNode!=null){
408                     parentNode = childNode;
409                 } else {
410                     return new TreePath JavaDoc(parentNode.getPath());
411                 }
412             }
413             return new TreePath JavaDoc(childNode.getPath());
414         }
415         return null;
416     }
417     
418     /**
419      * Gives the path of the object pointing by the cursor
420      *
421      * @param p The position of the cursor
422      */

423     protected TreePath JavaDoc getPath(Point JavaDoc p) {
424         if (p != null) {
425             return getPathForLocation((int) p.getX(), (int) p.getY());
426         }
427         return null;
428     }
429
430     /**
431      * Return the selected object
432      */

433     protected Object JavaDoc getSelectedObject(){
434         Entry entry = getSelectedEntry();
435         if(entry!=null){
436             return entry.getValue();
437         }
438         return null;
439     }
440     
441     /**
442      * Returns the parent of the selected entry
443      */

444     protected Entry getParentEntry() {
445         Object JavaDoc object = getLastSelectedPathComponent();
446         if (object != null)
447             return objectToEntry(((DefaultMutableTreeNode JavaDoc) object).getParent());
448         return null;
449     }
450     
451     /**
452      * Provides a view on the tree for the selected node.
453      * @return The view on the tree.
454      */

455     protected TreeView getTreeView() {
456         return new DefaultTreeView((Tree JavaDoc)this, getSelectedEntry(), getParentEntry());
457     }
458
459     /**
460      * Provides a menu item view for the selected node.
461      * @return The view on the tree.
462      */

463     protected MenuItemTreeView getMenuItemTreeView() {
464         return new DefaultMenuItemTreeView((Tree JavaDoc)this, getSelectedEntry(), getParentEntry());
465     }
466
467     /**
468      * Copies the content of the initialContext into the graphicalIntialContext
469      */

470     protected void createGraphicalInitialContext() {
471         // Clears the existing initial context.
472
getGraphicalInitialContext().clear();
473         // Finds and copies the root entries
474
Description desc = getPropertyResolver().resolve(ExplorerConstants.ROOT_PROPERTY, null);
475         if(desc!=null && ! desc.isEmpty()){
476             RootContext rootContext = (RootContext) getDescriptionInterpreter().interprete(desc, null);
477             RootEntry[] entries = rootContext.getEntries();
478             for (int i = 0; i < entries.length; i++) {
479                 addToInitialContext(entries[i]);
480             }
481         }
482         // Copies the content of the initialContext
483
for(int i=0 ; i<initialContext_.size() ; i++) {
484             RootEntry rootEntry = (RootEntry)initialContext_.get(i);
485             // Create a new RootEntry in oder to avoid having undefined context
486
// when the role changes.
487
RootEntry newRootEntry = new DefaultRootEntry(rootEntry.getName(), rootEntry.getValue(), rootEntry.getLevel());
488             addToInitialContext(newRootEntry);
489         }
490      }
491
492     /**
493      * Add an object into the initial context and expands the ndoe until a specific level if this one is a context
494      *
495      * @param id Name of the object
496      * @param object The object to add
497      * @param level The level (>0 for a specific level)
498      */

499     protected void addToInitialContext(RootEntry entry) {
500         if (entry!=null) {
501             getGraphicalInitialContext().addEntry(entry);
502             refreshRootNode();
503             //TreePath path = getPathFromInitialContext(id);
504
//refreshPath(path);
505
String JavaDoc id = entry.getName().toString();
506             if(!alreadyInInitialContext_.contains(id)){
507                 if (entry.getLevel() > 0) {
508                     TreePath JavaDoc path = stringToPath(id);
509                     if (path != null) {
510                         expandPath(path);
511                         openTree(path, entry.getLevel() - 1);
512                     }
513                 }
514                 alreadyInInitialContext_.add(id);
515             }
516         }
517     }
518
519     /**
520      * Open the tree nodes until a specific level
521      *
522      * @param root The root TreePath to develop
523      * @param level The level (>0 for a specific level)
524      */

525     protected void openTree(TreePath JavaDoc root, int level) {
526         if (level > 0) {
527             DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) root.getLastPathComponent();
528             Enumeration JavaDoc enumeration = node.children();
529             while (enumeration.hasMoreElements()) {
530                 DefaultMutableTreeNode JavaDoc childNode = (DefaultMutableTreeNode JavaDoc) enumeration.nextElement();
531                 TreePath JavaDoc p = new TreePath JavaDoc(childNode.getPath());
532                 expandPath(p);
533                 openTree(p, level - 1);
534             }
535             // }else if (level <0){
536
// for(int i=0;i<getRowCount();i++)
537
// expandRow(i);
538
}
539     }
540
541     /**
542      * Updates the name of the pathes.
543      * This method is only usable for initial entry.
544      * It has to be improved to order to be used in a larger context (such as all type of entries)
545      * @param currentName The current name of the node.
546      * @param newName The new name of the node.
547      */

548     protected void updateInitialPathes(String JavaDoc currentName, String JavaDoc newName){
549         Object JavaDoc[] keys = nodeStates_.keySet().toArray();
550         for(int i=0 ; i<keys.length ; i++) {
551             if(keys[i].toString().startsWith(currentName)){
552                 String JavaDoc suffixe = ((String JavaDoc)keys[i]).substring(currentName.length());
553                 String JavaDoc currentPath = currentName + suffixe;
554                 String JavaDoc newPath = newName + suffixe;
555                 nodeStates_.put(newPath,nodeStates_.get(currentPath));
556                 nodeStates_.remove(currentPath);
557             }
558         }
559     }
560     
561     // ==================================================================
562
// Access to Fractal interfaces
563
// ==================================================================
564

565     /**
566      * Provides the PropertyResolver to use.
567      */

568     protected PropertyResolver getPropertyResolver() {
569         try {
570             return (PropertyResolver) bindingFeature_.lookupFc(PropertyResolver.PROPERTY_RESOLVER);
571         } catch (NoSuchInterfaceException e) {
572             getTrace().warn(PropertyResolver.PROPERTY_RESOLVER + ": interface not found!");
573             return null;
574         }
575     }
576
577     /**
578      * Provides the descriptionInterpreter to use.
579      */

580     protected DescriptionInterpreter getDescriptionInterpreter() {
581         try {
582             return (DescriptionInterpreter) bindingFeature_.lookupFc(DescriptionInterpreter.DESCRIPTION_INTERPRETER);
583         } catch (NoSuchInterfaceException e) {
584             getTrace().warn(DescriptionInterpreter.DESCRIPTION_INTERPRETER + ": interface not found!");
585             return null;
586         }
587     }
588
589     /**
590      * Provides the roleManeger to use.
591      */

592     protected RoleManager getRoleManager() {
593         try {
594             return (RoleManager) bindingFeature_.lookupFc(RoleManager.ROLE_MANAGER);
595         } catch (NoSuchInterfaceException e) {
596             getTrace().warn(RoleManager.ROLE_MANAGER + ": interface not found!");
597             return null;
598         }
599     }
600
601     /**
602      * Provides the descriptionInterpreter to use.
603      */

604     protected RoleProvider getRoleProvider() {
605         try {
606             return (RoleProvider) bindingFeature_.lookupFc(RoleProvider.ROLE_PROVIDER);
607         } catch (NoSuchInterfaceException e) {
608             getTrace().warn(RoleProvider.ROLE_PROVIDER + ": interface not found!");
609             return null;
610         }
611     }
612     
613     /**
614      * Provides the TextComponent to use.
615      */

616     protected TextComponent getTextComponent(){
617         try {
618             return (TextComponent) bindingFeature_.lookupFc(TextComponent.TEXT_COMPONENT);
619         } catch (NoSuchInterfaceException e) {
620             getTrace().warn(TextComponent.TEXT_COMPONENT + ": interface not found!");
621             return null;
622         }
623     }
624     
625     /**
626      * Provides the TreeTemplate to use.
627      */

628     protected org.objectweb.fractal.api.Component getTreeTemplate(){
629         try {
630             return (org.objectweb.fractal.api.Component) bindingFeature_.lookupFc(Tree.TREE_TMPL);
631         } catch (NoSuchInterfaceException e) {
632             getTrace().warn(Tree.TREE_TMPL + ": interface not found!");
633             return null;
634         }
635     }
636
637     /**
638      * Provides the TreeTemplate to use.
639      */

640     protected ContextContainerFactory getContextContainerFactory(){
641         try {
642             return (ContextContainerFactory) bindingFeature_.lookupFc(ContextContainerFactory.CONTEXT_CONTAINER_FACTORY);
643         } catch (NoSuchInterfaceException e) {
644             getTrace().warn(ContextContainerFactory.CONTEXT_CONTAINER_FACTORY + ": interface not found!");
645             return null;
646         }
647     }
648     
649     // ==================================================================
650
// Refresh Management
651
// ==================================================================
652

653     /**
654      * Refreshes all the components bound with the tree via the
655      * <code>Synchronisation</code> interface.
656      */

657     protected void dispatchSynchronization(TreeView treeView){
658         String JavaDoc[] clientIftNames = listFc();
659         for (int i = 0; i < clientIftNames.length; i++) {
660             if(clientIftNames[i].startsWith(Synchronization.SYNCHRONIZATION)){
661                 try {
662                     ((Synchronization)lookupFc(clientIftNames[i])).refresh(treeView);
663                 } catch (NoSuchInterfaceException e) {
664                     getTrace().warn(e.getMessage());
665                 } catch (Exception JavaDoc e) {
666                     getTrace().warn(e.getMessage());
667                     e.printStackTrace();
668                     JOptionPane.showMessageDialog(null, e.getMessage(), "Error! (" + e.getClass().getName() + ")", JOptionPane.ERROR_MESSAGE);
669                 }
670             }
671         }
672     }
673     
674     protected void dispatchSynchronization(){
675         dispatchSynchronization(getTreeView());
676     }
677     
678     /**
679      * Refreshes the given path.
680      */

681     protected void refreshPath(TreePath JavaDoc treePath){
682         collapsePath(treePath);
683         expandPath(treePath);
684     }
685     
686     /**
687      * Refreshes the root node.
688      */

689     protected void refreshRootNode(){
690         refreshPath(new TreePath JavaDoc(rootNode_.getPath()));
691     }
692
693     /**
694      * Refreshes the action menu depending on the selected object.
695      * @param entry The selected entry
696      */

697     protected void refreshActionMenu(Entry entry){
698         if(actionMenu_!=null && entry!=null){
699             actionMenu_.removeAll();
700             Description desc = getPropertyResolver().resolve(ExplorerConstants.MENU_PROPERTY, entry, getParentEntry());
701             if(desc!=null && ! desc.isEmpty()){
702                 JPopupMenu JavaDoc menu = (JPopupMenu JavaDoc) getDescriptionInterpreter().interprete(desc, getMenuItemTreeView());
703                 Component JavaDoc[] componentList = menu.getComponents();
704                 for(int i=0; i<componentList.length;i++){
705                     if(JSeparator JavaDoc.class.isAssignableFrom(componentList[i].getClass())){
706                         actionMenu_.addSeparator();
707                     } else {
708                         actionMenu_.add((JMenuItem JavaDoc)componentList[i]);
709                     }
710                 }
711                 actionMenu_.setEnabled(true);
712                 //actionMenu_.revalidate();
713
} else {
714                 actionMenu_.setEnabled(false);
715             }
716         }
717     }
718
719     /**
720      * Refreshes the tool bar depending on the selected object.
721      * @param entry The selected entry
722      */

723     protected void refreshToolBar(Entry entry){
724         if(toolBar_!=null && entry!=null){
725             // Removes the old elements
726
if(nbElementsToRemove_>0){
727                 int nbComp = toolBar_.getComponentCount();
728                 for(int i = nbComp - 1 ; i >= nbComp - nbElementsToRemove_ ; i--)
729                     toolBar_.remove(i);
730                 nbElementsToRemove_ = 0;
731             }
732
733             Description desc = getPropertyResolver().resolve(ExplorerConstants.MENU_PROPERTY, entry, getParentEntry());
734             if(desc!=null && ! desc.isEmpty()){
735                 boolean iconDisplayed = false;
736                 JPopupMenu JavaDoc menu = (JPopupMenu JavaDoc) getDescriptionInterpreter().interprete(desc, getMenuItemTreeView());
737                 Component JavaDoc[] componentList = menu.getComponents();
738                 for(int i=0; i<componentList.length;i++){
739                     if(!JSeparator JavaDoc.class.isAssignableFrom(componentList[i].getClass())){
740                         if(((GenericAction)((JMenuItem JavaDoc)componentList[i]).getAction()).isUserIcon()){
741                             // An action must be added
742
toolBar_.add(((JMenuItem JavaDoc)componentList[i]).getAction());
743                             nbElementsToRemove_++;
744                             iconDisplayed = true;
745                         }
746                     } else if (iconDisplayed) {
747                         // A seperator must be displayed
748
toolBar_.addSeparator();
749                         iconDisplayed = false;
750                         nbElementsToRemove_++;
751                     }
752                 }
753             }
754
755             if(toolBar_.getComponentCount()==0){
756                 toolBar_.setVisible(false);
757             } else{
758                 toolBar_.setVisible(false);
759                 toolBar_.setVisible(true);
760             }
761         }
762         
763     }
764         
765     /**
766      * Refreshes the action menu depending on the selected object.
767      * It computes the selected entry.
768      * @see DynamicTree#refreshActionMenu(Entry)
769      */

770     protected void refreshActionMenu(){
771         refreshActionMenu(getSelectedEntry());
772     }
773
774     /**
775      * Refreshes the tool bar depending on the selected object.
776      * It computes the selected entry.
777      * @see DynamicTree#refreshToolBar(Entry)
778      */

779     protected void refreshToolBar(){
780         refreshToolBar(getSelectedEntry());
781     }
782     
783     /**
784      * Refreshes all the tree.
785      */

786     protected void refreshAllPathes(){
787         //Entry selectedEntry = getSelectedEntry();
788
String JavaDoc selectedPath = pathToString(getSelectionPath());
789         createGraphicalInitialContext();
790         //selectedNode_ = pathToString(getSelectionPath());
791
refreshRootNode();
792         selectPath(selectedPath);
793         Entry selectedEntry = getSelectedEntry();
794         //refreshPanel();
795
refreshActionMenu(selectedEntry);
796         refreshToolBar(selectedEntry);
797     }
798
799     /**
800      * Refreshes the role menu contained in the menu bar.
801      */

802     protected void refreshRoleMenu(){
803         if(menuBar_!=null){
804             String JavaDoc[] roleList = getRoleProvider().getRoleList(true, true);
805             String JavaDoc[] currentRoles = getRoleManager().getCurrentRoleIds();
806             if(roleMenu_ == null){
807                 roleMenu_ = new JMenu JavaDoc("Roles");
808                 menuBar_.add(roleMenu_);
809             }
810             roleMenu_.removeAll();
811             if(roleList.length<=0){
812                 roleMenu_.setVisible(false);
813             } else {
814                 roleMenu_.setVisible(true);
815                 if(multipleRoles_){
816                     List JavaDoc theRoles = Arrays.asList(currentRoles);
817                     for (int i = 0; i < roleList.length; i++) {
818                         JCheckBoxMenuItem JavaDoc cbMenuItem = new JCheckBoxMenuItem JavaDoc(new RoleSelected(roleList[i]));
819                         cbMenuItem.setSelected(theRoles.contains(roleList[i]));
820                         roleMenu_.add(cbMenuItem);
821                     }
822                 } else {
823                     ButtonGroup JavaDoc roleGroup = new ButtonGroup JavaDoc();
824                     JRadioButtonMenuItem JavaDoc rbMenuItem = null;
825                     for(int i=0; i<roleList.length;i++){
826                         rbMenuItem = new JRadioButtonMenuItem JavaDoc(new RoleSelected(roleList[i]));
827                         if(currentRoles.length>0)
828                             rbMenuItem.setSelected(currentRoles[0].equals(roleList[i]));
829                         roleGroup.add(rbMenuItem);
830                         roleMenu_.add(rbMenuItem);
831                     }
832                 }
833             }
834         }
835     }
836     
837     // ==================================================================
838
// Wrapper Management
839
// ==================================================================
840

841     /**
842      * Adds an entry to a node.
843      * @param parent Node which is the parent of the new entry
844      * @param child Entry to add
845      * @return The created node
846      */

847     protected DefaultMutableTreeNode JavaDoc addObject(DefaultMutableTreeNode JavaDoc parent, Entry child) {
848         Description desc = getPropertyResolver().resolve(ExplorerConstants.WRAPPER_PROPERTY, child);
849         if(desc!=null){
850             Context JavaDoc context = (Context JavaDoc) getDescriptionInterpreter().interprete(desc, getTreeView());
851             if (context != null) {
852                 child.setWrapper(getContextContainerFactory().create(context));
853             }
854         }
855         DefaultMutableTreeNode JavaDoc childNode = new DefaultMutableTreeNode JavaDoc(child);
856         if (parent == null) {
857             parent = rootNode_;
858         }
859         treeModel_.insertNodeInto(childNode, parent, parent.getChildCount());
860         return childNode;
861     }
862     
863     // ==================================================================
864
// Popup Menu Management
865
// ==================================================================
866

867     /**
868      * Shows the associated PopupMenu, if exists and if displaying is enabled
869      *
870      * @param p Point which indicates where is the mouse
871      */

872     protected void showMenu(Point JavaDoc p) {
873         TreePath JavaDoc path = getPath(p);
874         if (path != null) {
875             selectionModel_.setSelectionPath(path);
876             Description desc = getPropertyResolver().resolve(ExplorerConstants.MENU_PROPERTY, getSelectedEntry(), getParentEntry());
877             JPopupMenu JavaDoc menu = (JPopupMenu JavaDoc) getDescriptionInterpreter().interprete(desc, getMenuItemTreeView());
878             if (menu != null) {
879                 menu.show((Component JavaDoc) this, (int) (p.getX()), (int) (p.getY()));
880             }
881         }
882     }
883
884     // ==================================================================
885
// Icon Management
886
// ==================================================================
887

888     protected Icon JavaDoc getImageIcon(Entry entry){
889         if(getPropertyResolver()!=null){
890             Description desc = getPropertyResolver().resolve(ExplorerConstants.ICON_PROPERTY, entry);
891             IconProvider iconProvider = (IconProvider) getDescriptionInterpreter().interprete(desc, getTreeView());
892             if(iconProvider!=null){
893                 Object JavaDoc object = iconProvider.newIcon(entry.getValue());
894                 if(object instanceof Icon JavaDoc){
895                     return (Icon JavaDoc)object;
896                 } else if(object instanceof String JavaDoc) {
897                     return (Icon JavaDoc)(new IconFileProvider((String JavaDoc)object)).newIcon(entry.getValue());
898                 } else if (object instanceof URL JavaDoc) {
899                     return (Icon JavaDoc)(new IconFileProvider((URL JavaDoc)object)).newIcon(entry.getValue());
900                 }
901             }
902         }
903         return null;
904     }
905
906     // ==================================================================
907
// Info Management
908
// ==================================================================
909

910     protected void displayInfo(Entry entry){
911         if (getTextComponent() != null){
912             String JavaDoc message = "";
913             Description desc = getPropertyResolver().resolve(ExplorerConstants.INFO_PROPERTY, entry);
914             if(desc!=null){
915                 Info info = (Info) getDescriptionInterpreter().interprete(desc, null);
916                 if (info != null) {
917                     message = info.getInfo(getTreeView());
918                 }
919             }
920             getTextComponent().setText(message);
921         }
922     }
923     
924     // ==================================================================
925
//
926
// Public methods for Tree interface.
927
//
928
// ==================================================================
929

930     /* (non-Javadoc)
931      * @see org.objectweb.util.explorer.api.Tree#refreshAll()
932      */

933     public void refreshAll() {
934         refreshAllPathes();
935     }
936     
937     /*
938      * (non-Javadoc)
939      *
940      * @see org.objectweb.util.explorer.api.Tree#addEntry(java.lang.Object,
941      * java.lang.Object)
942      */

943     public void addEntry(Object JavaDoc name, Object JavaDoc value) {
944         addEntry(name, value, 0);
945     }
946
947     /*
948      * (non-Javadoc)
949      *
950      * @see org.objectweb.util.explorer.api.Tree#addEntry(java.lang.Object,
951      * java.lang.Object)
952      */

953     public void addEntry(Object JavaDoc name, Object JavaDoc value, int level) {
954         RootEntry rootEntry = new DefaultRootEntry(name, value, level);
955         initialContext_.add(rootEntry);
956         addToInitialContext(rootEntry);
957     }
958
959     /* (non-Javadoc)
960      * @see org.objectweb.util.explorer.api.Tree#selectPath(java.lang.String)
961      */

962     public void
963     selectPath(String JavaDoc path){
964         TreePath JavaDoc treePath = stringToPath(path);
965         setSelectionPath(treePath);
966     }
967     
968     /* (non-Javadoc)
969      * @see org.objectweb.util.explorer.api.Tree#clear()
970      */

971     public void clear() {
972         initialContext_.clear();
973     }
974     
975     /* (non-Javadoc)
976      * @see org.objectweb.util.explorer.api.Tree#getInitialContextSize()
977      */

978     public int getInitialContextSize() {
979         return getGraphicalInitialContext().getSize();
980     }
981     
982     /* (non-Javadoc)
983      * @see org.objectweb.util.explorer.api.Tree#removeEntry(java.lang.Object)
984      */

985     public void removeEntry(Object JavaDoc name) {
986         Iterator JavaDoc it = initialContext_.iterator();
987         RootEntry elementToRemove = null;
988         while (it.hasNext()) {
989             RootEntry element = (RootEntry) it.next();
990             if(element.getName().toString().equals(name.toString())) {
991                 elementToRemove = element;
992                 break;
993             }
994         }
995         if(elementToRemove!=null)
996             initialContext_.remove(elementToRemove);
997     }
998     
999     /* (non-Javadoc)
1000     * @see org.objectweb.util.explorer.api.Tree#renameInitialEntry(java.lang.Object, java.lang.Object)
1001     */

1002    public void
1003    renameInitialEntry(Object JavaDoc currentName, Object JavaDoc newName){
1004        Iterator JavaDoc it = initialContext_.iterator();
1005        while (it.hasNext()) {
1006            RootEntry element = (RootEntry) it.next();
1007            if(element.getName().toString().equals(currentName.toString())) {
1008                element.setName(newName.toString());
1009                break;
1010            }
1011        }
1012        updateInitialPathes(currentName.toString(), newName.toString());
1013        refreshAll();
1014        selectPath(newName.toString());
1015    }
1016
1017    
1018    
1019    /* (non-Javadoc)
1020     * @see org.objectweb.util.explorer.api.Tree#duplicate()
1021     */

1022    public org.objectweb.fractal.api.Component duplicate() {
1023        return duplicate(true);
1024    }
1025    
1026    /* (non-Javadoc)
1027     * @see org.objectweb.util.explorer.api.Tree#getSelectedEntry()
1028     */

1029    public Entry getSelectedEntry() {
1030        Object JavaDoc object = getLastSelectedPathComponent();
1031        if (object != null)
1032            return objectToEntry(object);
1033        return null;
1034    }
1035    
1036    /* (non-Javadoc)
1037     * @see org.objectweb.util.explorer.api.Tree#duplicate(boolean)
1038     */

1039    public org.objectweb.fractal.api.Component duplicate(boolean withData) {
1040        try {
1041            // Creates a new instance of a tree.
1042
org.objectweb.fractal.api.Component tmpl = getTreeTemplate();
1043            Factory factory = (Factory) tmpl.getFcInterface("factory");
1044            org.objectweb.fractal.api.Component instance = factory.newFcInstance();
1045            
1046            // Renames the new instance of the component.
1047
NameController nameController = (NameController)instance.getFcInterface("name-controller");
1048            nameController.setFcName("tree-cpt-" + System.currentTimeMillis());
1049            
1050            // Moves the new instance of the tree component into the explorer component.
1051
org.objectweb.fractal.api.Component treeComponent = (org.objectweb.fractal.api.Component)lookupFc(Tree.TREE_ITSELF);
1052            SuperController sc = (SuperController)treeComponent.getFcInterface("super-controller");
1053            org.objectweb.fractal.api.Component[] superComponents = sc.getFcSuperComponents();
1054            if(superComponents !=null && superComponents.length > 0){
1055                org.objectweb.fractal.api.Component superComponent = superComponents[0];
1056                ContentController cc = (ContentController)superComponent.getFcInterface("content-controller");
1057                cc.addFcSubComponent(instance);
1058            }
1059            
1060            // Dynamically connect the new instance of the tree to the existing instances of mandatory components.
1061
BindingController bc = (BindingController)instance.getFcInterface("binding-controller");
1062            bc.bindFc(PropertyResolver.PROPERTY_RESOLVER, bindingFeature_.lookupFc(PropertyResolver.PROPERTY_RESOLVER));
1063            bc.bindFc(DescriptionInterpreter.DESCRIPTION_INTERPRETER, bindingFeature_.lookupFc(DescriptionInterpreter.DESCRIPTION_INTERPRETER));
1064            bc.bindFc(ContextContainerFactory.CONTEXT_CONTAINER_FACTORY, bindingFeature_.lookupFc(ContextContainerFactory.CONTEXT_CONTAINER_FACTORY));
1065            
1066            Fractal.getLifeCycleController(instance).startFc();
1067            if(withData) {
1068                Tree JavaDoc tree = (Tree JavaDoc)instance.getFcInterface(Tree.TREE);
1069                Entry[] entries = getGraphicalInitialContext().getEntries(null);
1070                for (int i = 0; i < entries.length; i++) {
1071                    try{
1072                        tree.addEntry(entries[i].getName(), entries[i].getValue(),1);
1073                    } catch(Exception JavaDoc e){
1074                        e.printStackTrace();
1075                    }
1076                }
1077            }
1078            return instance;
1079        } catch (NoSuchInterfaceException ex) {
1080            ex.printStackTrace();
1081        } catch (IllegalLifeCycleException ex) {
1082            ex.printStackTrace();
1083        } catch (InstantiationException JavaDoc ex) {
1084            ex.printStackTrace();
1085        } catch (IllegalBindingException ex) {
1086            ex.printStackTrace();
1087        } catch (Exception JavaDoc ex) {
1088            ex.printStackTrace();
1089            throw new RuntimeException JavaDoc("Error during replication!!!");
1090        }
1091        return null;
1092    }
1093
1094    /* (non-Javadoc)
1095     * @see org.objectweb.util.explorer.api.Tree#renameSelectedNode(java.lang.Object, java.lang.Object)
1096     */

1097    public void renameSelectedNode(Object JavaDoc oldName, Object JavaDoc newName) {
1098        String JavaDoc selectedPath = pathToString(getSelectionPath());
1099        String JavaDoc prefixe = selectedPath.substring(0,selectedPath.lastIndexOf(oldName.toString()));
1100        if(!selectedPath.equals(prefixe)){
1101            updateInitialPathes(prefixe + oldName, prefixe + newName);
1102            refreshAll();
1103            selectPath(prefixe + newName);
1104        }
1105    }
1106
1107    /* (non-Javadoc)
1108     * @see org.objectweb.util.explorer.api.Tree#close()
1109     */

1110    public void close() {
1111        dispatchSynchronization(null);
1112    }
1113    
1114    // ==================================================================
1115
//
1116
// Public methods for Explorer interface.
1117
//
1118
// ==================================================================
1119

1120    /*
1121     * (non-Javadoc)
1122     *
1123     * @see org.objectweb.util.explorer.swing.api.Explorer#getTree()
1124     */

1125    public JTree JavaDoc getTree() {
1126        return this;
1127    }
1128
1129    /* (non-Javadoc)
1130     * @see org.objectweb.util.explorer.swing.api.Explorer#setMenuBar(javax.swing.JMenuBar)
1131     */

1132    public void setMenuBar(JMenuBar JavaDoc menuBar) {
1133        menuBar_ = menuBar;
1134        actionMenu_ = new JMenu JavaDoc("Actions");
1135        actionMenu_.setEnabled(false);
1136        menuBar_.add(actionMenu_);
1137        refreshRoleMenu();
1138    }
1139    
1140    /* (non-Javadoc)
1141     * @see org.objectweb.util.explorer.swing.api.Explorer#setToolBar(javax.swing.JToolBar)
1142     */

1143    public void setToolBar(JToolBar JavaDoc toolBar) {
1144        toolBar_ = toolBar;
1145        if(toolBar_!=null && toolBar_.getComponents().length==0){
1146            toolBar_.setVisible(false);
1147        } else {
1148            toolBar_.addSeparator();
1149        }
1150    }
1151
1152    /* (non-Javadoc)
1153     * @see org.objectweb.util.explorer.swing.api.Explorer#isMultipleRoles()
1154     */

1155    public boolean isMultipleRoles() {
1156        return multipleRoles_;
1157    }
1158    
1159    /* (non-Javadoc)
1160     * @see org.objectweb.util.explorer.swing.api.Explorer#setCurrentRoleIds(java.lang.String[])
1161     */

1162    public void setCurrentRoles(String JavaDoc[] roleIds) {
1163        getRoleManager().setCurrentRoleIds(roleIds);
1164        refreshRoleMenu();
1165        refreshAllPathes();
1166    }
1167    
1168    /* (non-Javadoc)
1169     * @see org.objectweb.util.explorer.swing.api.Explorer#setMultipleRoles(boolean)
1170     */

1171    public void setMultipleRoles(boolean multipleRoles) {
1172        multipleRoles_ = multipleRoles;
1173        refreshRoleMenu();
1174    }
1175    
1176    /* (non-Javadoc)
1177     * @see org.objectweb.util.explorer.swing.api.Explorer#isDragAndDropEnabled()
1178     */

1179    public boolean isDragAndDropEnabled() {
1180        return dndEnabled_;
1181    }
1182    /* (non-Javadoc)
1183     * @see org.objectweb.util.explorer.swing.api.Explorer#isPopupEnabled()
1184     */

1185    public boolean isPopupEnabled() {
1186        return popupEnabled_;
1187    }
1188    /* (non-Javadoc)
1189     * @see org.objectweb.util.explorer.swing.api.Explorer#setDragAndDropEnabled(boolean)
1190     */

1191    public void setDragAndDropEnabled(boolean dndEnabled) {
1192        dndEnabled_ = dndEnabled;
1193    }
1194    /* (non-Javadoc)
1195     * @see org.objectweb.util.explorer.swing.api.Explorer#setPopupEnabled(boolean)
1196     */

1197    public void setPopupEnabled(boolean popupEnabled) {
1198        popupEnabled_ = popupEnabled;
1199    }
1200    
1201    // ==================================================================
1202
//
1203
// Public methods for BindingController interface.
1204
//
1205
// ==================================================================
1206

1207    /*
1208     * (non-Javadoc)
1209     *
1210     * @see org.objectweb.fractal.api.control.BindingController#bindFc(java.lang.String,
1211     * java.lang.Object)
1212     */

1213    public void bindFc(String JavaDoc itfName, Object JavaDoc itfValue)
1214            throws NoSuchInterfaceException, IllegalBindingException,
1215            IllegalLifeCycleException {
1216        bindingFeature_.bindFc(itfName, itfValue);
1217    }
1218
1219    /*
1220     * (non-Javadoc)
1221     *
1222     * @see org.objectweb.fractal.api.control.BindingController#listFc()
1223     */

1224    public String JavaDoc[] listFc() {
1225        return bindingFeature_.listFc();
1226    }
1227
1228    /*
1229     * (non-Javadoc)
1230     *
1231     * @see org.objectweb.fractal.api.control.BindingController#lookupFc(java.lang.String)
1232     */

1233    public Object JavaDoc lookupFc(String JavaDoc itfName) throws NoSuchInterfaceException {
1234        return bindingFeature_.lookupFc(itfName);
1235    }
1236
1237    /*
1238     * (non-Javadoc)
1239     *
1240     * @see org.objectweb.fractal.api.control.BindingController#unbindFc(java.lang.String)
1241     */

1242    public void unbindFc(String JavaDoc itfName) throws NoSuchInterfaceException,
1243            IllegalBindingException, IllegalLifeCycleException {
1244        bindingFeature_.unbindFc(itfName);
1245    }
1246
1247    // ==================================================================
1248
//
1249
// Public methods for LifeCycleController interface.
1250
//
1251
// ==================================================================
1252

1253    public String JavaDoc getFcState () {
1254        return null;
1255    }
1256
1257    public void startFc () {
1258        /*
1259        System.err.println("startFC");
1260        System.err.print("initial context initialization... ");
1261        //graphicalInitialContext_ = getContextContainerFactory().create();
1262        graphicalInitialContext_ = new RootContextContainer();
1263        System.err.print("OK");*/

1264    }
1265
1266    public void stopFc () {
1267        // Nothing to do!
1268
}
1269    
1270    protected ContextContainer getGraphicalInitialContext(){
1271        if(graphicalInitialContext_==null){
1272            graphicalInitialContext_ = getContextContainerFactory().create(new RootContextContainer());
1273            rootNode_ = new DefaultMutableTreeNode JavaDoc(new DefaultEntry("Root",graphicalInitialContext_));
1274            treeModel_ = new MyTreeModel(rootNode_);
1275            setModel(treeModel_);
1276        }
1277        return graphicalInitialContext_;
1278    }
1279    
1280    // ==================================================================
1281
//
1282
// Internal class for JTree management.
1283
//
1284
// ==================================================================
1285

1286    /**
1287     * Mouse Adapter
1288     * Use to draw Popup Menu
1289     */

1290    final class MyMouseAdapter extends MouseAdapter JavaDoc {
1291        public void mousePressed(MouseEvent JavaDoc e) {
1292            popupLayout(e);
1293        }
1294
1295        public void mouseReleased(MouseEvent JavaDoc e) {
1296            popupLayout(e);
1297        }
1298
1299        private void popupLayout(MouseEvent JavaDoc e) {
1300            if (e.isPopupTrigger() && popupEnabled_) {
1301                showMenu(e.getPoint());
1302            }
1303        }
1304    }
1305
1306    /**
1307     * Tree Will Expand Listener
1308     * Use to complete node : it adds child to current node
1309     */

1310    final class MyTreeWillExpandListener implements TreeWillExpandListener JavaDoc {
1311        public void treeWillCollapse(TreeExpansionEvent JavaDoc event) {
1312            DefaultMutableTreeNode JavaDoc currentNode = (DefaultMutableTreeNode JavaDoc) event.getPath().getLastPathComponent();
1313            Entry e = (Entry) currentNode.getUserObject();
1314            nodeStates_.put(pathToString(currentNode), Boolean.FALSE);
1315        }
1316
1317        public void treeWillExpand(TreeExpansionEvent JavaDoc event) {
1318            DefaultMutableTreeNode JavaDoc currentNode = (DefaultMutableTreeNode JavaDoc) event.getPath().getLastPathComponent();
1319            Entry e = (Entry) currentNode.getUserObject();
1320            nodeStates_.put(pathToString(currentNode), Boolean.TRUE);
1321            currentNode.removeAllChildren();
1322            Entry[] entries = e.getWrapper().getEntries(e.getValue());
1323            for (int i = 0; i < entries.length; i++) {
1324                DefaultMutableTreeNode JavaDoc childNode = addObject(currentNode, entries[i]);
1325            }
1326            treeModel_.reload(currentNode);
1327        }
1328    }
1329    
1330    /**
1331     * Tree Expansion Listener
1332     * Use to refresh node
1333     */

1334    final class MyTreeExpansionListener implements TreeExpansionListener JavaDoc {
1335        public void treeCollapsed(TreeExpansionEvent JavaDoc event) {
1336        }
1337
1338        public void treeExpanded(TreeExpansionEvent JavaDoc event) {
1339            DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) (event.getPath()).getLastPathComponent();
1340            if (!node.isLeaf()) {
1341                Enumeration JavaDoc enumeration = node.children();
1342                while (enumeration.hasMoreElements()) {
1343                    DefaultMutableTreeNode JavaDoc childNode = (DefaultMutableTreeNode JavaDoc) enumeration.nextElement();
1344                    Entry entry = (Entry) childNode.getUserObject();
1345                    String JavaDoc pathName = pathToString(childNode);
1346                    if (nodeStates_.containsKey(pathName)) {
1347                        if (((Boolean JavaDoc)nodeStates_.get(pathName)).booleanValue()) {
1348                            expandPath(new TreePath JavaDoc(childNode.getPath()));
1349                        }
1350                    }
1351                    //if (selectedNode_.equals(pathName)) {
1352
// setSelectionPath(new TreePath(treeModel_.getPathToRoot(childNode)));
1353
//}
1354
}
1355            }
1356        }
1357    }
1358    
1359    /**
1360     * Tree Cell Renderer
1361     * Use to put the icon defined for the given entry.
1362     */

1363    final class MyTreeCellRenderer extends DefaultTreeCellRenderer JavaDoc {
1364
1365        public Component JavaDoc getTreeCellRendererComponent(JTree JavaDoc tree,Object JavaDoc value,boolean selected,boolean expanded,boolean leaf,int row,boolean hasFocus) {
1366            super.getTreeCellRendererComponent(tree,value,selected,expanded,leaf,row,hasFocus);
1367
1368            // Put the appropriate icon if one is defined.
1369
Entry entry = objectToEntry(value);
1370            Icon JavaDoc icon = getImageIcon(entry);
1371            if(icon!=null){
1372                setIcon(icon);
1373            }
1374            
1375            // Put the name of the entry as the label of the node
1376
setText(entry.getName().toString());
1377
1378            return this;
1379        }
1380
1381    }
1382
1383    /**
1384     * Tree Selection Listener
1385     * Use to put the panel corresponding to the selected node
1386     */

1387    final class MyTreeSelectionListener implements TreeSelectionListener JavaDoc {
1388
1389        public void valueChanged(TreeSelectionEvent JavaDoc e) {
1390            // Compute the selected node
1391
//TreePath treePath = e.getNewLeadSelectionPath();
1392
//selectedNode_ = treePath!=null?pathToString(e.getNewLeadSelectionPath()):"";
1393

1394            // Refresh the diplay
1395
Entry selectedEntry = getSelectedEntry();
1396            displayInfo(selectedEntry);
1397            refreshActionMenu(selectedEntry);
1398            refreshToolBar(selectedEntry);
1399            dispatchSynchronization();
1400            
1401            /*
1402            refreshPanel();
1403            refreshActionMenu();
1404            refreshToolBar();
1405            */

1406        }
1407    }
1408    
1409    /**
1410     * Tree Model
1411     * Uses to know if a node is leaf or not.
1412     */

1413    final class MyTreeModel extends DefaultTreeModel JavaDoc {
1414
1415        public MyTreeModel(TreeNode JavaDoc root) {
1416            super(root);
1417        }
1418
1419        public boolean isLeaf(Object JavaDoc node) {
1420            Entry entry = objectToEntry(node);
1421            return (entry.getWrapper()==null && !(entry.getValue() instanceof Context JavaDoc));
1422        }
1423
1424    }
1425
1426    // ==================================================================
1427
//
1428
// Public methods overriden JComponent methods.
1429
//
1430
// ==================================================================
1431

1432    public String JavaDoc getToolTipText(MouseEvent JavaDoc evt) {
1433        StringBuffer JavaDoc label = new StringBuffer JavaDoc();
1434        TreePath JavaDoc currentPath = getPathForLocation(evt.getX(), evt.getY());
1435        if(currentPath!=null){
1436            Entry entry = objectToEntry(currentPath.getLastPathComponent());
1437            DnDDescriptions desc = (DnDDescriptions)getPropertyResolver().resolve(ExplorerConstants.DND_PROPERTY, entry);
1438            if(desc != null && !desc.isEmpty()){
1439                String JavaDoc[] labels = desc.getActionsDescription();
1440                if(labels.length>0){
1441                    label.append("<html>");
1442                    label.append("Drop action:");
1443                    for (int i = 0; i < labels.length; i++) {
1444                        label.append("<br> - " + labels[i]);
1445                    }
1446                    label.append("</html>");
1447                }
1448            }
1449        }
1450        return label.toString();
1451    }
1452    
1453    // ==================================================================
1454
//
1455
// Public methods for Autoscroll interface.
1456
//
1457
// ==================================================================
1458

1459    public void autoscroll(Point JavaDoc cursorLocn){
1460        Rectangle JavaDoc rect=getVisibleRect();
1461        Dimension JavaDoc dim=getSize();
1462        
1463        // Vertival autoscroll
1464
if(cursorLocn.y>rect.y+rect.height-10) {
1465            rect.y=Math.min(rect.y+10,dim.height-rect.height);
1466        } else if(cursorLocn.y<rect.y+10) {
1467            int i = rect.y+rect.height-10;
1468            rect.y=Math.max(rect.y-10,0);
1469        }
1470        
1471        // Horizontal autoscroll
1472
if(cursorLocn.x>rect.x+rect.width-10) {
1473            rect.x=Math.min(rect.x+10,dim.width-rect.width);
1474        } else if(cursorLocn.x<rect.x+10) {
1475            rect.x=Math.max(rect.x-10,0);
1476        }
1477        
1478        scrollRectToVisible(rect);
1479    }
1480              
1481    public Insets JavaDoc getAutoscrollInsets(){
1482        Rectangle JavaDoc rect=getVisibleRect();
1483        Dimension JavaDoc dim=getSize();
1484        Insets JavaDoc inset=new Insets JavaDoc(rect.y+10,rect.x+10,dim.height-(rect.y+rect.height)+10,dim.width-(rect.x+rect.width)+10);
1485        return inset;
1486    }
1487
1488    // ==================================================================
1489
//
1490
// Internal classes for Drag & Drop.
1491
//
1492
// ==================================================================
1493

1494    /**
1495     * Implementation of DragGestureListener interface.
1496     *
1497     * @author <a HREF="mailto:Jerome.Moroy@lifl.fr">Jerome Moroy</a>
1498     *
1499     * @version 0.1
1500     */

1501    protected class TreeDragGestureListener implements DragGestureListener JavaDoc {
1502
1503        /*
1504         * @see java.awt.dnd.DragGestureListener#dragGestureRecognized(java.awt.dnd.DragGestureEvent)
1505         */

1506        public void dragGestureRecognized(DragGestureEvent JavaDoc dge) {
1507            if(dndEnabled_){
1508                Transferable JavaDoc transferable = new EntryTransferable(DynamicTree.this.getSelectedEntry());
1509                try {
1510                    dragSource_.startDrag(dge,DragSource.DefaultLinkDrop, transferable, dragSourceListener_);
1511                }catch(InvalidDnDOperationException JavaDoc idoe) {
1512                    System.out.println( idoe );
1513                }
1514            }
1515        }
1516    }
1517    
1518    /**
1519     * Implementation of DragSourceListener interface
1520     *
1521     *
1522     * @author <a HREF="mailto:Jerome.Moroy@lifl.fr">Jerome Moroy</a>
1523     *
1524     * @version 0.1
1525     */

1526    public class TreeDragSourceListener implements DragSourceListener JavaDoc {
1527
1528        /** The current dropAction */
1529        protected int dropAction_;
1530        
1531        /*
1532         * DnD problem:
1533         * This way to implement a Drag&Drop mechanism seems to be bad
1534         * because the DragSourceDragEvent is not correctly initialized.
1535         * Indeed, when the Drag&Drop begins (entering in dragStart state),
1536         * no problem is detected, but when the drop action change (call
1537         * to the dropActionChanged method), the associated dropAction refers
1538         * to an unknown action. That why, in order to know the refering drop
1539         * action we use the current state of the input devices:
1540         * 16 -> left click -> Move
1541         * 18 -> Ctrl + left click -> Copy
1542         * 19 -> Ctrl + Shift + left click -> Link
1543         */

1544
1545        /**
1546         * Provides the dropAction depending on the current state of the input devices.
1547         * @param The current state of the input devices.
1548         * @return The corresponding dropAction identifier.
1549         */

1550        protected int getDropAction(int gestureModifiers){
1551            if(gestureModifiers==16)
1552                return DnDConstants.ACTION_MOVE;
1553            else if(gestureModifiers==18)
1554                return DnDConstants.ACTION_COPY;
1555            else if(gestureModifiers==19)
1556                return DnDConstants.ACTION_LINK;
1557            else
1558                return 0;
1559        }
1560
1561        /**
1562         * Fixes the appropriate icon.
1563         */

1564        protected void setIcon(DragSourceDragEvent JavaDoc dsde){
1565            DragSourceContext JavaDoc context = dsde.getDragSourceContext();
1566            dropAction_ = getDropAction(dsde.getGestureModifiers());
1567            if (dropAction_ == DnDConstants.ACTION_COPY) {
1568                context.setCursor(DragSource.DefaultCopyDrop);
1569            } else if (dropAction_ == DnDConstants.ACTION_MOVE) {
1570                context.setCursor(DragSource.DefaultMoveDrop);
1571            } else if (dropAction_ == DnDConstants.ACTION_LINK) {
1572                context.setCursor(DragSource.DefaultLinkDrop);
1573            } else {
1574                context.setCursor(DragSource.DefaultLinkNoDrop);
1575            }
1576        }
1577
1578        /**
1579         * Fixes the appropriate icon.
1580         */

1581        protected void setForbiddenIcon(DragSourceEvent JavaDoc dse){
1582            DragSourceContext JavaDoc context = dse.getDragSourceContext();
1583            if (dropAction_ == DnDConstants.ACTION_COPY) {
1584                context.setCursor(DragSource.DefaultCopyNoDrop);
1585            } else if (dropAction_ == DnDConstants.ACTION_MOVE) {
1586                context.setCursor(DragSource.DefaultMoveNoDrop);
1587            } else if (dropAction_ == DnDConstants.ACTION_LINK) {
1588                context.setCursor(DragSource.DefaultLinkNoDrop);
1589            } else {
1590                context.setCursor(DragSource.DefaultLinkNoDrop);
1591            }
1592        }
1593
1594        /*
1595         * @see java.awt.dnd.DragSourceListener#dragEnter(java.awt.dnd.DragSourceDragEvent)
1596         */

1597        public void dragEnter(DragSourceDragEvent JavaDoc dsde) {
1598            setIcon(dsde);
1599        }
1600
1601        /*
1602         * @see java.awt.dnd.DragSourceListener#dragOver(java.awt.dnd.DragSourceDragEvent)
1603         */

1604        public void dragOver(DragSourceDragEvent JavaDoc dsde) {
1605        }
1606
1607        /*
1608         * @see java.awt.dnd.DragSourceListener#dropActionChanged(java.awt.dnd.DragSourceDragEvent)
1609         */

1610        public void dropActionChanged(DragSourceDragEvent JavaDoc dsde) {
1611            setIcon(dsde);
1612        }
1613        
1614        /*
1615         * @see java.awt.dnd.DragSourceListener#dragExit(java.awt.dnd.DragSourceEvent)
1616         */

1617        public void dragExit(DragSourceEvent JavaDoc dse) {
1618            setForbiddenIcon(dse);
1619        }
1620
1621        /*
1622         * @see java.awt.dnd.DragSourceListener#dragDropEnd(java.awt.dnd.DragSourceDropEvent)
1623         */

1624        public void dragDropEnd(DragSourceDropEvent JavaDoc dsde) {
1625        }
1626
1627    }
1628
1629    /**
1630     * Implementation of DropTargetListener interface.
1631     *
1632     * @author <a HREF="mailto:Jerome.Moroy@lifl.fr">Jerome Moroy</a>
1633     *
1634     * @version 0.1
1635     */

1636    protected class TreeDropTargetListener implements DropTargetListener JavaDoc {
1637
1638        /** The old Path*/
1639        protected TreePath JavaDoc oldPath_ = null;
1640        
1641        /** The currentAction_ */
1642        protected boolean actionChanged_ = false;
1643
1644        protected String JavaDoc getDropActionName(int dropAction){
1645            if(dropAction==DnDConstants.ACTION_MOVE)
1646                return DnDDescription.MOVE_ACTION;
1647            else if(dropAction==DnDConstants.ACTION_COPY)
1648                return DnDDescription.COPY_ACTION;
1649            else if(dropAction==DnDConstants.ACTION_LINK)
1650                return DnDDescription.LINK_ACTION;
1651            else
1652                return "";
1653        }
1654
1655        protected String JavaDoc computeActionDesc(Entry entry, String JavaDoc dropAction){
1656            DnDDescriptions desc = (DnDDescriptions)getPropertyResolver().resolve(ExplorerConstants.DND_PROPERTY, entry);
1657            if(desc!=null){
1658                DnDDescription dndDesc = desc.getDropAction(dropAction);
1659                if(dndDesc !=null){
1660                    return dndDesc.getLabel();
1661                }
1662            }
1663            return "";
1664        }
1665                
1666        /*
1667         * @see java.awt.dnd.DropTargetListener#dragEnter(java.awt.dnd.DropTargetDragEvent)
1668         */

1669        public void dragEnter(DropTargetDragEvent JavaDoc dtde) {
1670            dtde.acceptDrag(dtde.getDropAction());
1671        }
1672
1673        /*
1674         * @see java.awt.dnd.DropTargetListener#dragOver(java.awt.dnd.DropTargetDragEvent)
1675         */

1676        public void dragOver(DropTargetDragEvent JavaDoc dtde) {
1677            dtde.acceptDrag(dtde.getDropAction());
1678            String JavaDoc label = "";
1679            TreePath JavaDoc path = getPath(dtde.getLocation());
1680            if(path==null){
1681                oldPath_ = null;
1682                if(getTextComponent()!=null){
1683                    getTextComponent().setText("");
1684                }
1685            } else if(oldPath_ == null || (path != null && !path.equals(oldPath_)) || actionChanged_){
1686                actionChanged_ = false;
1687                oldPath_ = path;
1688                Entry entry = objectToEntry(path.getLastPathComponent());
1689                String JavaDoc value = computeActionDesc(entry, getDropActionName(dtde.getDropAction()));
1690                if(getTextComponent()!=null){
1691                    getTextComponent().setText(value);
1692                }
1693            }
1694        }
1695
1696        /*
1697         * @see java.awt.dnd.DropTargetListener#dropActionChanged(java.awt.dnd.DropTargetDragEvent)
1698         */

1699        public void dropActionChanged(DropTargetDragEvent JavaDoc dtde) {
1700            dtde.acceptDrag(dtde.getDropAction());
1701            actionChanged_ = true;
1702        }
1703
1704        /*
1705         * @see java.awt.dnd.DropTargetListener#dragExit(java.awt.dnd.DropTargetEvent)
1706         */

1707        public void dragExit(DropTargetEvent JavaDoc dte) {
1708        }
1709
1710        /*
1711         * @see java.awt.dnd.DropTargetListener#drop(java.awt.dnd.DropTargetDropEvent)
1712         */

1713        public void drop(DropTargetDropEvent JavaDoc dtde) {
1714            
1715            DataFlavor JavaDoc[] df = EntryTransferable.flavors_;
1716            DataFlavor JavaDoc chosen = null;
1717            for (int i = 0; i < df.length; i++) {
1718                if(dtde.isDataFlavorSupported(df[i])){
1719                    chosen = df[i];
1720                    break;
1721                }
1722            }
1723
1724            if(getTextComponent()!=null){
1725                getTextComponent().setText("");
1726            }
1727                        
1728            Entry dragEntry = null;
1729            // This method is responsible of a bug (it is waiting for ???)
1730
// dtde.acceptDrop(acceptableActions_);
1731
try {
1732                dragEntry = (Entry)dtde.getTransferable().getTransferData(chosen);
1733            } catch (UnsupportedFlavorException JavaDoc e1) {
1734                getTrace().warn("[" + getClass().getName() + "] UnsupportedFlavorException: " + e1.getMessage());
1735            } catch (IOException JavaDoc e1) {
1736                e1.printStackTrace();
1737            }
1738            
1739            TreePath JavaDoc path = getPath(dtde.getLocation());
1740            if (path != null) {
1741                selectionModel.setSelectionPath(path);
1742                Entry dropEntry = objectToEntry(getLastSelectedPathComponent());
1743                DnDDescriptions desc = (DnDDescriptions)getPropertyResolver().resolve(ExplorerConstants.DND_PROPERTY, dropEntry);
1744                if(desc!=null){
1745                    DnDDescription dndDesc = desc.getDropAction(getDropActionName(dtde.getDropAction()));
1746                    if(dndDesc !=null){
1747                        DropAction dropAction = (DropAction)getDescriptionInterpreter().interprete(dndDesc.getCodeDescription(),null);
1748                        if(dropAction!=null && dragEntry!=null){
1749                            try{
1750                                dropAction.execute(new DefaultDropTreeView((Tree JavaDoc)DynamicTree.this, dropEntry, getParentEntry(), dragEntry));
1751                            }catch(Exception JavaDoc e){
1752                                JOptionPane.showMessageDialog(null, e.getMessage(), "Drag & Drop error ! (" + e.getClass().getName() + ")", JOptionPane.ERROR_MESSAGE);
1753                            }
1754                            DynamicTree.this.refreshAllPathes();
1755                        }
1756                    }
1757                }
1758            }
1759            
1760        }
1761    }
1762
1763    /**
1764     * This class defines the action performed when a role is selected into the associated menu.
1765     *
1766     * @author <a HREF="mailto:Jerome.Moroy@lifl.fr">Jérôme Moroy</a>,
1767     * <a HREF="mailto:Philippe.Merle@lifl.fr">Philippe Merle</a>.
1768     *
1769     * @version 0.1
1770     */

1771    protected final class RoleSelected extends AbstractAction JavaDoc{
1772
1773        protected String JavaDoc roleId_;
1774        
1775        public RoleSelected(String JavaDoc roleId){
1776            super(roleId);
1777            roleId_ = roleId;
1778        }
1779        
1780        public void actionPerformed(ActionEvent JavaDoc e) {
1781            if(DynamicTree.this.multipleRoles_){
1782                String JavaDoc[] currentRoles = getRoleManager().getCurrentRoleIds();
1783                Vector JavaDoc theRoles = new Vector JavaDoc(Arrays.asList(currentRoles));
1784                if(theRoles.contains(roleId_))
1785                    theRoles.remove(roleId_);
1786                else
1787                    theRoles.add(roleId_);
1788                getRoleManager().setCurrentRoleIds((String JavaDoc[])theRoles.toArray(new String JavaDoc[theRoles.size()]));
1789            } else {
1790                String JavaDoc currentRoleId = getRoleManager().getCurrentRoleIds()[0];
1791                if(!roleId_.equals(currentRoleId)) {
1792                    getRoleManager().setCurrentRoleIds(new String JavaDoc[]{roleId_});
1793                }
1794            }
1795            refreshAllPathes();
1796        }
1797
1798    }
1799    
1800    
1801}
1802  
1803
Popular Tags