KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > util > browser > core > common > DynamicTree


1 /*====================================================================
2
3 Objectweb Browser framework
4 Copyright (C) 2000-2004 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.
23 Contributor(s): ______________________________________.
24
25 ====================================================================*/

26
27 package org.objectweb.util.browser.core.common;
28
29 /** The console's imports */
30 import org.objectweb.util.browser.core.naming.DefaultEntry;
31 import org.objectweb.util.browser.core.naming.DefaultName;
32 import org.objectweb.util.browser.core.naming.InitialContextContainer;
33 import org.objectweb.util.browser.core.naming.InitialContextContainerFactory;
34 import org.objectweb.util.browser.core.naming.InitialEntry;
35 import org.objectweb.util.browser.api.Context;
36 import org.objectweb.util.browser.api.DropAction;
37 import org.objectweb.util.browser.api.Entry;
38 import org.objectweb.util.browser.api.Table;
39 import org.objectweb.util.browser.api.Tree;
40 import org.objectweb.util.browser.api.TreeView;
41 import org.objectweb.util.browser.api.Panel;
42 import org.objectweb.util.browser.api.Wrapper;
43 import org.objectweb.util.browser.api.Info;
44 import org.objectweb.util.browser.core.api.BrowserProperty;
45 import org.objectweb.util.browser.core.api.ContextContainer;
46 import org.objectweb.util.browser.core.api.ContextContainerFactory;
47 import org.objectweb.util.browser.core.api.ContextProperty;
48 import org.objectweb.util.browser.core.api.ExtendedEntry;
49 import org.objectweb.util.browser.core.api.Role;
50 import org.objectweb.util.browser.core.api.RoleManagement;
51 import org.objectweb.util.browser.core.api.StatusBar;
52 import org.objectweb.util.browser.core.api.ViewPanel;
53 import org.objectweb.util.browser.core.api.TreeConfiguration;
54 import org.objectweb.util.browser.core.dnd.DefaultDropTreeView;
55 import org.objectweb.util.browser.core.dnd.EntryViewTransferable;
56 import org.objectweb.util.browser.core.panel.WhitePanel;
57 import org.objectweb.util.browser.core.xmlparser.ContextXMLParser;
58 import org.objectweb.util.browser.core.xmlparser.XMLParser;
59 import org.objectweb.util.browser.core.xmlparser.BrowserXMLParser;
60
61 import org.objectweb.util.browser.core.popup.DefaultAction;
62
63 /** The java API's imports */
64 import java.util.Arrays JavaDoc;
65 import java.util.Comparator JavaDoc;
66 import java.util.Enumeration JavaDoc;
67 import java.util.HashMap JavaDoc;
68 import java.util.Iterator JavaDoc;
69 import java.util.List JavaDoc;
70 import java.util.Map JavaDoc;
71 import java.util.Vector JavaDoc;
72 import java.io.IOException JavaDoc;
73
74 /** The Drag and Drop API's imports */
75 import java.awt.datatransfer.DataFlavor JavaDoc;
76 import java.awt.datatransfer.Transferable JavaDoc;
77 import java.awt.datatransfer.UnsupportedFlavorException JavaDoc;
78 import java.awt.dnd.Autoscroll JavaDoc;
79 import java.awt.dnd.DnDConstants JavaDoc;
80 import java.awt.dnd.DragGestureEvent JavaDoc;
81 import java.awt.dnd.DragGestureListener JavaDoc;
82 import java.awt.dnd.DragSource JavaDoc;
83 import java.awt.dnd.DragSourceContext JavaDoc;
84 import java.awt.dnd.DragSourceDragEvent JavaDoc;
85 import java.awt.dnd.DragSourceDropEvent JavaDoc;
86 import java.awt.dnd.DragSourceEvent JavaDoc;
87 import java.awt.dnd.DragSourceListener JavaDoc;
88 import java.awt.dnd.DropTarget JavaDoc;
89 import java.awt.dnd.DropTargetDragEvent JavaDoc;
90 import java.awt.dnd.DropTargetDropEvent JavaDoc;
91 import java.awt.dnd.DropTargetEvent JavaDoc;
92 import java.awt.dnd.DropTargetListener JavaDoc;
93 import java.awt.dnd.InvalidDnDOperationException JavaDoc;
94
95 /** The java swing API's imports */
96 import javax.swing.AbstractAction JavaDoc;
97 import javax.swing.ButtonGroup JavaDoc;
98 import javax.swing.JCheckBoxMenuItem JavaDoc;
99 import javax.swing.JMenu JavaDoc;
100 import javax.swing.JMenuBar JavaDoc;
101 import javax.swing.JMenuItem JavaDoc;
102 import javax.swing.JOptionPane JavaDoc;
103 import javax.swing.JRadioButtonMenuItem JavaDoc;
104 import javax.swing.JToolBar JavaDoc;
105 import javax.swing.JTree JavaDoc;
106 import javax.swing.JPopupMenu JavaDoc;
107 import javax.swing.Icon JavaDoc;
108 import javax.swing.event.TreeWillExpandListener JavaDoc;
109 import javax.swing.event.TreeSelectionListener JavaDoc;
110 import javax.swing.event.TreeSelectionEvent JavaDoc;
111 import javax.swing.event.TreeExpansionEvent JavaDoc;
112 import javax.swing.event.TreeExpansionListener JavaDoc;
113
114 import java.awt.Dimension JavaDoc;
115 import java.awt.Insets JavaDoc;
116 import java.awt.Point JavaDoc;
117 import java.awt.Component JavaDoc;
118 import java.awt.Rectangle JavaDoc;
119 import java.awt.event.ActionEvent JavaDoc;
120 import java.awt.event.MouseAdapter JavaDoc;
121 import java.awt.event.MouseEvent JavaDoc;
122
123 /** The java swing tree API's imports */
124 import javax.swing.tree.DefaultMutableTreeNode JavaDoc;
125 import javax.swing.tree.DefaultTreeModel JavaDoc;
126 import javax.swing.tree.DefaultTreeSelectionModel JavaDoc;
127 import javax.swing.tree.DefaultTreeCellRenderer JavaDoc;
128 import javax.swing.tree.TreeNode JavaDoc;
129 import javax.swing.tree.TreePath JavaDoc;
130 import javax.swing.tree.TreeSelectionModel JavaDoc;
131
132 /**
133  * Implementation of a Entry tree which is dynamic.
134  * You can customize icons, panels and popup menus
135  * for every objects you display.
136  *
137  * @author <a HREF="mailto:Jerome.Moroy@lifl.fr">Jerome Moroy</a>
138  * @version 0.1
139  */

140 public class DynamicTree
141     extends JTree JavaDoc
142     implements TreeConfiguration, Tree, Autoscroll JavaDoc, RoleManagement {
143
144     // ==================================================================
145
//
146
// Internal states.
147
//
148
// ==================================================================
149

150     /** To access to the customization */
151     protected AdminCustomization custom;
152
153     /** Parent panel, use to refresh right panel */
154     protected ViewPanel viewPanel_;
155
156     /** Root node */
157     protected DefaultMutableTreeNode JavaDoc rootNode;
158
159     /** The graphical initial context (The entries might be replaced by their associated context) */
160     protected ContextContainer graphicalInitialContext_;
161     
162     /** The inital context. */
163     protected Vector JavaDoc initialContext_;
164
165     /** Model to manipulate node */
166     protected DefaultTreeModel JavaDoc treeModel;
167
168     /** Model to define what to do when a node is selected */
169     protected DefaultTreeSelectionModel JavaDoc selectionModel;
170
171     /** Model to display node */
172     protected DefaultTreeCellRenderer JavaDoc treeCellRenderer;
173
174     /** A map which informs about the node state (expanded or collapsed) */
175     protected Map JavaDoc nodeState_;
176
177     /** To know the selected node */
178     protected String JavaDoc selectedNode_;
179
180     /** To know the selected treepath*/
181     protected TreePath JavaDoc selectedTreePath_;
182
183     /** Panel display when any panel was found */
184     protected Panel blankPanel_;
185
186     /** The associated contextProperty */
187     protected ContextProperty contextProperty_;
188
189     /** The associated browserProperty */
190     protected XMLParser browserProperty_;
191     
192     /** The current TreeView*/
193     protected TreeView currentTreeView_;
194     
195     /** To know if the popup menus have to be enabled or not */
196     protected boolean popupEnabled_;
197     
198     /** To know if the Drag and Drop have to be enabled or not */
199     protected boolean dndEnabled_;
200     
201     /** To know if the application allows the selection of several roles at the same time. */
202     protected boolean multipleRolesEnabled_;
203     
204     /** The status bar */
205     protected StatusBar statusBar_;
206     
207     /** The MenuBar to use. */
208     protected JMenuBar JavaDoc menuBar_;
209
210     /** The ToolBar to use. */
211     protected JToolBar JavaDoc toolBar_ = null;
212     
213     /** The number of element of the toolBar which has to be removed. */
214     protected int nbElementsToRemove_ = 0;
215
216     /** The action menu. */
217     protected JMenu JavaDoc actionMenu_, roleMenu_;
218     
219     /** The PopupMenu corresponding to the selected node. */
220     protected JPopupMenu JavaDoc currentJPopupMenu_ = null;
221
222     /** List of elements which have already been added into the initial context. */
223     protected Vector JavaDoc alreadyInInitialContext_ = null;
224                 
225     // Drag and Drop attributes
226

227     /** The DragSource to use */
228     protected DragSource JavaDoc dragSource_;
229     
230     /** The DragGestureListener to use */
231     protected DragGestureListener JavaDoc dragGestureListener_;
232     
233     /** The DragSourceListener to use */
234     protected DragSourceListener JavaDoc dragSourceListener_;
235     
236     /** The dragAction */
237     protected int dragAction_ = DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK;
238     
239     /** The allowed drop action */
240     protected int acceptableActions_ = DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK;
241
242     /** The DropTarget */
243     protected DropTarget JavaDoc dropTarget_;
244         
245     /** The DropTargetListener to use */
246     protected DropTargetListener JavaDoc dropTargetListener_;
247     
248     // ==================================================================
249
//
250
// Constructors.
251
//
252
// ==================================================================
253

254     /**
255      * Calls by the constructor
256      */

257     private void buildDnD(){
258         // Drag
259
dragSource_ = DragSource.getDefaultDragSource();
260         dragSourceListener_ = new TreeDragSourceListener();
261         dragGestureListener_ = new TreeDragGestureListener();
262         dragSource_.createDefaultDragGestureRecognizer(this, dragAction_, dragGestureListener_);
263         
264         // Drop
265
dropTargetListener_ = new TreeDropTargetListener();
266         dropTarget_ = new DropTarget JavaDoc(this, acceptableActions_, dropTargetListener_, true);
267     }
268
269     /**
270      * Builds a new DynamicTree
271      * @param initialContext The context to be displayed
272      * @param initAll Uses to know if the constructor may initialize all the attribute
273      */

274     private void build(ContextContainer initialContext, boolean initAll) {
275         graphicalInitialContext_ = initialContext;
276         if(initialContext instanceof InitialContextContainer)
277             ((InitialContextContainer)initialContext).setDynamicTree(this);
278         
279         rootNode = new DefaultMutableTreeNode JavaDoc(new DefaultEntry(graphicalInitialContext_,new DefaultName("Root"),null));
280         treeModel = new MyTreeModel(rootNode);
281         setModel(treeModel);
282
283         if (initAll) {
284             nodeState_ = new HashMap JavaDoc();
285             initialContext_ = new Vector JavaDoc();
286             alreadyInInitialContext_ = new Vector JavaDoc();
287             selectedNode_ = "";
288             blankPanel_ = new WhitePanel();
289             selectionModel = new DefaultTreeSelectionModel JavaDoc();
290             selectionModel.setSelectionMode(
291                 TreeSelectionModel.SINGLE_TREE_SELECTION);
292             setSelectionModel(selectionModel);
293             addMouseListener(new MyMouseAdapter());
294             addTreeWillExpandListener(new MyTreeWillExpandListener());
295             addTreeExpansionListener(new MyTreeExpansionListener());
296             addTreeSelectionListener(new MyTreeSelectionListener());
297             setCellRenderer(new MyTreeCellRenderer());
298             popupEnabled_ = true;
299             dndEnabled_ = true;
300             multipleRolesEnabled_ = false;
301             buildDnD();
302             setToolTipText("");
303         }
304
305         setShowsRootHandles(true);
306         collapseRow(0);
307         expandRow(0);
308
309         setRootVisible(false);
310     }
311
312     /**
313      * Constructs a new DynamicTree.
314      */

315     public DynamicTree() {
316         ContextContainerFactory ccf = new InitialContextContainerFactory(null);
317         build(ccf.create(), true);
318     }
319
320     /**
321      * Constructs a new DynamicTree initialized with the specified context.
322      * @param initialContext The context to be displayed
323      */

324     public DynamicTree(ContextContainer initialContext) {
325         build(initialContext, true);
326     }
327
328     // ==================================================================
329
//
330
// Internal methods.
331
//
332
// ==================================================================
333

334     /**
335      * Adds an entry to a node.
336      * @param parent Node which is the parent of the new entry
337      * @param child Entry to add
338      * @return The created node
339      */

340     protected DefaultMutableTreeNode JavaDoc addObject(
341         DefaultMutableTreeNode JavaDoc parent,
342         ExtendedEntry child) {
343         if (custom != null) {
344             Context context = custom.getContext(child.getValue());
345             if (context != null) {
346                 child.setOWValue(context);
347                 child.setWrappedObject(((Wrapper) context).getWrapped());
348             }
349         }
350         DefaultMutableTreeNode JavaDoc childNode = new DefaultMutableTreeNode JavaDoc(child);
351         if (parent == null) {
352             parent = rootNode;
353         }
354         treeModel.insertNodeInto(childNode, parent, parent.getChildCount());
355
356         return childNode;
357     }
358
359     /**
360      * Gets a string representation of the path
361      *
362      * @param node The node
363      * @return The path from th root to the node
364      *
365      */

366     protected String JavaDoc pathToString(DefaultMutableTreeNode JavaDoc node) {
367         StringBuffer JavaDoc sf = new StringBuffer JavaDoc();
368         Object JavaDoc[] o = node.getUserObjectPath();
369         for (int i = 0; i < o.length; i++) {
370             sf.append(((Entry) o[i]).getName().toString());
371             if (i != o.length - 1)
372                 sf.append("/");
373         }
374         return sf.toString();
375     }
376
377     /**
378      * Returns the entry associates to a node
379      * @param o The node
380      * @return The associated entry
381      */

382     protected Entry objectToEntry(Object JavaDoc o) {
383         if (o != null) {
384             DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) o;
385             return (Entry) node.getUserObject();
386         }
387         return null;
388     }
389
390     /**
391      * Gives the path of the object pointing by the cursor
392      * @param p The position of the cursor
393      */

394     protected TreePath JavaDoc getPath(Point JavaDoc p){
395         if(p!=null){
396             return getPathForLocation((int) p.getX(), (int) p.getY());
397         }
398         return null;
399     }
400
401     /**
402      * Shows the associated PopupMenu, if exists and if displaying is enabled
403      * @param p Point which indicates where is the mouse
404      */

405     protected void showMenu(Point JavaDoc p) {
406         TreePath JavaDoc path = getPath(p);
407         if (path != null) {
408             selectionModel.setSelectionPath(path);
409             Entry entry = objectToEntry(getLastSelectedPathComponent());
410             if (custom != null) {
411                 JPopupMenu JavaDoc menu = custom.getMenu((ExtendedEntry) entry);
412                 if (menu != null) {
413                     menu.show((Component JavaDoc) this,(int) (p.getX()),(int) (p.getY()));
414                 }
415             }
416         }
417     }
418
419     /**
420      * Gives the TreePath correspoding to the given id
421      * @param id The id of the node of the tree
422      * @return The associated TreePath or null
423      */

424     protected TreePath JavaDoc getPathFromInitialContext(String JavaDoc id) {
425         if (id != null) {
426             Enumeration JavaDoc children = rootNode.children();
427             while (children.hasMoreElements()) {
428                 DefaultMutableTreeNode JavaDoc childNode = (DefaultMutableTreeNode JavaDoc) children.nextElement();
429                 Entry entry = (Entry) childNode.getUserObject();
430                 if (entry.getName().toString().equals(id))
431                     return new TreePath JavaDoc(childNode.getPath());
432             }
433         }
434         return null;
435     }
436
437     /**
438      * Copies the content of the initialContext into the graphicalIntialContext
439      */

440     protected void createGraphicalInitialContext() {
441         // Clears the existing initial context.
442
graphicalInitialContext_.clear();
443         if(custom!=null){
444             // Finds and copies the root context
445
Entry[] entries = custom.getRoot();
446             for (int i = 0 ; i < entries.length ; i++){
447                 InitialEntry initialEntry = null;
448                 try{
449                     initialEntry = (InitialEntry)entries[i];
450                 } catch (ClassCastException JavaDoc e) {
451                     initialEntry = new InitialEntry(entries[i].getName().toString(), entries[i].getValue(), 0);
452                 }
453                 addToInitialContext(initialEntry.getName().toString(), initialEntry.getValue(), initialEntry.getLevel());
454             }
455         }
456         // Copies the content of the initialContext
457
InitialEntry entryToAdd = null;
458         for(int i=0 ; i<initialContext_.size() ; i++) {
459             entryToAdd = (InitialEntry)initialContext_.get(i);
460             addToInitialContext(entryToAdd.getName().toString(), entryToAdd.getValue(), entryToAdd.getLevel());
461         }
462         
463     }
464
465     /**
466      * Open the tree nodes until a specific level
467      *
468      * @param root The root TreePath to develop
469      * @param level The level (>0 for a specific level)
470      */

471     protected void openTree(TreePath JavaDoc root, int level) {
472         if (level > 0) {
473             DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) root.getLastPathComponent();
474             Enumeration JavaDoc children = node.children();
475             while (children.hasMoreElements()) {
476                 DefaultMutableTreeNode JavaDoc childNode = (DefaultMutableTreeNode JavaDoc) children.nextElement();
477                 TreePath JavaDoc p = new TreePath JavaDoc(childNode.getPath());
478                 expandPath(p);
479                 openTree(p, level - 1);
480             }
481             // }else if (level <0){
482
// for(int i=0;i<getRowCount();i++)
483
// expandRow(i);
484
}
485     }
486
487     /**
488      * Refreshes the view panel
489      */

490     protected void refreshPanel(){
491         if(viewPanel_!=null){
492             // Obtaining the current panel
493
Panel currentPanel = viewPanel_.getViewPanel();
494             if(currentPanel!=null && currentTreeView_!=null)
495                 currentPanel.unselected(currentTreeView_);
496             Entry entry = null;
497             Object JavaDoc object = getLastSelectedPathComponent();
498             String JavaDoc newSelectedNode = null;
499             if (object != null) {
500                 DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) object;
501                 if (!node.equals(rootNode)) {
502                     newSelectedNode = pathToString(node);
503                 }
504                 entry = (Entry) node.getUserObject();
505             }
506             if (newSelectedNode==null || newSelectedNode.equals("")) {
507                 viewPanel_.setViewPanel(blankPanel_);
508             } else if (selectedNode_ != null && newSelectedNode != null && !selectedNode_.equals(newSelectedNode)) {
509                 // New selected node
510
selectedNode_ = newSelectedNode;
511                 // Obtaining the new panel
512
Panel panel = null;
513                 Table table = null;
514                 if (entry != null && custom != null) {
515                     
516                     panel = custom.getPanel((ExtendedEntry) entry);
517                     if (panel != null) {
518                         currentTreeView_ = new DefaultTreeView(this);
519                         panel.selected(currentTreeView_);
520                         viewPanel_.setViewPanel(panel);
521                     }
522                     
523                /* // Look for a panel for the wrapped object by the entry
524                     panel = custom.getPanel(((ExtendedEntry)entry).getWrappedObject(), true);
525                     if(panel==null) {
526                         // Look for a table for the wrapped object by the entry
527                         table = custom.getTable(((ExtendedEntry)entry).getWrappedObject(), true);
528                     }
529                     if(panel==null && table==null) {
530                         // Look for a panel for the value of the entry
531                         panel = custom.getPanel(entry.getValue());
532                         if(panel==null) {
533                             // Look for a table for the value of the entry
534                             table = custom.getTable(entry.getValue());
535                         }
536                     }
537                     // A table is defined
538                     if(panel == null && table != null){
539                         if(contextProperty_!=null)
540                             panel = new DefaultTablePanel(table, custom, contextProperty_.getDecoder());
541                         else
542                             panel = new DefaultTablePanel(table, custom);
543                     }
544                     if (panel != null) {
545                         currentTreeView_ = new DefaultTreeView(this);
546                         panel.selected(currentTreeView_);
547                         viewPanel_.setViewPanel(panel);
548                     }
549                */

550                 }
551                 if (entry == null || custom == null || panel == null) {
552                     viewPanel_.setViewPanel(blankPanel_);
553                 }
554             }
555         }
556     }
557
558     /**
559      * Refreshes the status bar depending on the selected object
560      */

561     protected void refreshStatusBar(){
562         if(statusBar_!=null){
563             Entry entry = null;
564             Object JavaDoc object = getLastSelectedPathComponent();
565             if (object != null) {
566                 DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) object;
567                 entry = (Entry) node.getUserObject();
568             }
569             if (entry != null && custom != null) {
570                 Info info = custom.getInfo((ExtendedEntry) entry);
571                 if (info != null) {
572                     statusBar_.setText(info.getInfo(new DefaultTreeView(this)));
573                 } else {
574                     statusBar_.setText("");
575                 }
576             } else {
577                 statusBar_.setText("");
578             }
579         }
580     }
581
582     /**
583      * Refreshes the action menu depending on the selected object.
584      */

585     protected void refreshActionMenu(){
586         if(menuBar_!=null && actionMenu_ != null){
587             Entry entry = null;
588             Object JavaDoc object = getLastSelectedPathComponent();
589             if (object != null) {
590                 DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) object;
591                 entry = (Entry) node.getUserObject();
592             }
593             if (entry != null && custom != null) {
594                 currentJPopupMenu_ = custom.getMenu((ExtendedEntry) entry);
595                 actionMenu_.removeAll();
596                 Component JavaDoc[] componentList = currentJPopupMenu_.getComponents();
597                 if(componentList.length>0){
598                     actionMenu_.setEnabled(true);
599                     for(int i=0; i<componentList.length;i++){
600                         if(JPopupMenu.Separator JavaDoc.class.isAssignableFrom(componentList[i].getClass()))
601                             actionMenu_.addSeparator();
602                         else
603                             actionMenu_.add((JMenuItem JavaDoc)componentList[i]);
604                     }
605                 } else {
606                     actionMenu_.setEnabled(false);
607                 }
608                 actionMenu_.revalidate();
609             }
610         }
611     }
612
613     protected void refreshToolBar(){
614         if(toolBar_!=null){
615             // Removes the old elements
616
if(nbElementsToRemove_>0){
617                 int nbComp = toolBar_.getComponentCount();
618                 for(int i = nbComp - 1 ; i >= nbComp - nbElementsToRemove_ ; i--)
619                     toolBar_.remove(i);
620                 nbElementsToRemove_ = 0;
621             }
622             
623             // Adds the new elements
624
Entry entry = null;
625             Object JavaDoc object = getLastSelectedPathComponent();
626             if (object != null) {
627                 DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) object;
628                 entry = (Entry) node.getUserObject();
629             }
630             if (entry != null && custom != null) {
631                 currentJPopupMenu_ = custom.getMenu((ExtendedEntry) entry);
632                 Component JavaDoc[] componentList = currentJPopupMenu_.getComponents();
633                 if(componentList.length>0){
634                     boolean isFirst = true;
635                     boolean iconDisplayed = false;
636                     for(int i=0; i<componentList.length;i++){
637                         if(!JPopupMenu.Separator JavaDoc.class.isAssignableFrom(componentList[i].getClass())){
638                             if(((DefaultAction)((JMenuItem JavaDoc)componentList[i]).getAction()).isUserIcon()){
639                                 if(isFirst){
640                                     isFirst = false;
641                                     if(toolBar_.getComponentCount()>0){
642                                         toolBar_.addSeparator();
643                                         nbElementsToRemove_++;
644                                     }
645                                 }
646                                 toolBar_.add(((JMenuItem JavaDoc)componentList[i]).getAction());
647                                 iconDisplayed = true;
648                                 nbElementsToRemove_++;
649                             }
650                         } else if(iconDisplayed){
651                             toolBar_.addSeparator();
652                             iconDisplayed = false;
653                             nbElementsToRemove_++;
654                         }
655                     }
656                 }
657             }
658             if(toolBar_.getComponentCount()==0){
659                 toolBar_.setVisible(false);
660             } else{
661                 toolBar_.setVisible(false);
662                 toolBar_.setVisible(true);
663             }
664         }
665     }
666
667     /**
668      * Returns true if the context has at least one child.
669      * @param context The context to check
670      * @return true if the context has children
671      */

672     protected boolean hasChild(Context context) {
673         if(context!=null){
674             Entry[] entries = context.getEntries();
675             return (entries.length > 0);
676         }
677         return false;
678     }
679
680     /**
681      * Add an object into the initial context and expands the ndoe until a specific level if this one is a context
682      *
683      * @param id Name of the object
684      * @param object The object to add
685      * @param level The level (>0 for a specific level)
686      */

687     protected void addToInitialContext(String JavaDoc id, Object JavaDoc object, int level) {
688         if (id != null && object != null) {
689             graphicalInitialContext_.addEntry(id, object);
690             refreshPath(new TreePath JavaDoc(rootNode.getPath()));
691             //TreePath path = getPathFromInitialContext(id);
692
//refreshPath(path);
693
if(!alreadyInInitialContext_.contains(id)){
694                 if (level > 0) {
695                     TreePath JavaDoc path = getPathFromInitialContext(id);
696                     if (path != null) {
697                         expandPath(path);
698                         openTree(path, level - 1);
699                     }
700                 }
701                 alreadyInInitialContext_.add(id);
702             }
703         }
704     }
705
706     /**
707      * Refreshes the liste of role in the menu item
708      * @param roles
709      */

710     protected void refreshRoleMenu(Role[] roles){
711         if(menuBar_!=null){
712             Arrays.sort(roles, new RoleComparator());
713             Role[] currentRoles = getCurrentRoles();
714             if(roleMenu_==null){
715                 roleMenu_ = new JMenu JavaDoc("Roles");
716                 menuBar_.add(roleMenu_);
717             }
718             roleMenu_.removeAll();
719             if(roles.length>0){
720                 roleMenu_.setVisible(true);
721                 if(multipleRolesEnabled_){
722                     List JavaDoc theRoles = Arrays.asList(currentRoles);
723                     for(int i=0; i<roles.length;i++){
724                         if(roles[i].isConcrete()){
725                             JCheckBoxMenuItem JavaDoc cbMenuItem = new JCheckBoxMenuItem JavaDoc(new RoleSelected(roles[i]));
726                             cbMenuItem.setSelected(theRoles.contains(roles[i]));
727                             roleMenu_.add(cbMenuItem);
728                         }
729                     }
730                 } else {
731                     ButtonGroup JavaDoc group = new ButtonGroup JavaDoc();
732                     JRadioButtonMenuItem JavaDoc rbMenuItem = null;
733                     for(int i=0; i<roles.length;i++){
734                         if(roles[i].isConcrete()){
735                             rbMenuItem = new JRadioButtonMenuItem JavaDoc(new RoleSelected(roles[i]));
736                             if(currentRoles!=null)
737                                 rbMenuItem.setSelected(currentRoles[0].getId().equals(roles[i].getId()));
738                             group.add(rbMenuItem);
739                             roleMenu_.add(rbMenuItem);
740                         }
741                     }
742                 }
743             } else {
744                 roleMenu_.setVisible(false);
745             }
746         }
747     }
748
749     /**
750      * Updates the name of the pathes.
751      * This method is only usable for initial entry.
752      * It has to be improved to order to be used in a larger context (such as all type of entries)
753      * @param currentName The current name of the node.
754      * @param newName The new name of the node.
755      */

756     protected void updateInitialPathes(String JavaDoc currentName, String JavaDoc newName){
757         String JavaDoc prefixe = selectedNode_.substring(0,selectedNode_.lastIndexOf(currentName.toString()));
758         Object JavaDoc[] keys = nodeState_.keySet().toArray();
759         for(int i=0 ; i<keys.length ; i++) {
760             if(keys[i].toString().startsWith(prefixe+currentName)){
761                 String JavaDoc suffixe = ((String JavaDoc)keys[i]).substring(prefixe.length() + currentName.length());
762                 String JavaDoc currentPath = prefixe + currentName + suffixe;
763                 String JavaDoc newPath = prefixe + newName + suffixe;
764                 nodeState_.put(newPath,nodeState_.get(currentPath));
765                 nodeState_.remove(currentPath);
766             }
767         }
768     }
769     
770     // ==================================================================
771
//
772
// Public methods overriden JComponent methods.
773
//
774
// ==================================================================
775

776     public String JavaDoc getToolTipText(MouseEvent JavaDoc evt) {
777         String JavaDoc label = "";
778         TreePath JavaDoc currentPath = getPathForLocation(evt.getX(), evt.getY());
779         if(currentPath!=null){
780             Entry entry = objectToEntry(currentPath.getLastPathComponent());
781             if(custom != null && entry!=null){
782                 label = custom.getDropLabel((ExtendedEntry) entry, -1);
783                 if(label != null && label.length()>0){
784                     label = "<html>Drop action: " + label + "</html>";
785                 }
786             }
787         }
788         return label;
789     }
790
791     // ==================================================================
792
//
793
// Public methods for TreeConfiguration interface.
794
//
795
// ==================================================================
796

797     /**
798      * Set a new property context.
799      * @param files An array of XML files to parse and to apply (It can be a single file or a directory)
800      */

801     public void setNewBrowserProperty(String JavaDoc[] files) {
802         if (files != null) {
803             XMLParser config = new BrowserXMLParser(this);
804             config.setPropertyFile(files);
805             setNewBrowserProperty((BrowserProperty) config);
806             browserProperty_ = config;
807         }
808     }
809
810     /**
811      * Set a new property context
812      */

813     public void setNewBrowserProperty(BrowserProperty properties) {
814         if (properties != null) {
815             properties.setContextProperty(contextProperty_);
816             custom = new AdminCustomization(properties, this);
817         }
818         refreshRoleMenu(((RoleManagement)properties).getRoleList());
819         refreshAll();
820     }
821
822     /**
823      * Adds the new properties
824      * @param files The properties files to add
825      */

826     public void addBrowserProperty(String JavaDoc[] files){
827         if (files != null) {
828             if(browserProperty_!=null){
829                 browserProperty_.setPropertyFile(files);
830                 setNewBrowserProperty((BrowserProperty) browserProperty_);
831                 refreshRoleMenu(((RoleManagement)browserProperty_).getRoleList());
832             } else {
833                 setNewBrowserProperty(files);
834             }
835         }
836         refreshAll();
837     }
838
839     /**
840      * Gives the current BrowserProperty.
841      * @return The current BrowserProperty
842      */

843     public BrowserProperty getBrowserProperty() {
844         return custom.getBrowserProperty();
845     }
846
847     /**
848      * Creates a new context property with the given file
849      * @param file The properties file to parse and to apply
850      */

851     public void setNewContextProperty(String JavaDoc file) {
852         if (file != null && !file.equals("")) {
853             XMLParser config = new ContextXMLParser();
854             config.setPropertyFile(file);
855             setNewContextProperty((ContextProperty) config);
856         }
857     }
858
859     /**
860      * Sets a new context property
861      * @param properties The properties to apply
862      */

863     public void setNewContextProperty(ContextProperty properties) {
864         if (properties != null) {
865             contextProperty_ = properties;
866             // Updates the graphicalInitialContext_
867
ContextContainerFactory ccf = new InitialContextContainerFactory(properties.getDecoder());
868             ContextContainer newContext = ccf.create();
869             if (graphicalInitialContext_ != null) {
870                 Entry[] entries = graphicalInitialContext_.getEntries();
871                 for (int i = 0; i < entries.length; i++) {
872                     Entry entry = entries[i];
873                     newContext.addEntry(entry.getName().toString(),entry.getValue());
874                 }
875             }
876             build(newContext, false);
877         }
878     }
879
880     /**
881      * Gives the current ContextProperty.
882      * @return The current ContextProperty
883      */

884     public ContextProperty getContextProperty() {
885         return contextProperty_;
886     }
887
888     /**
889      * Returns the selected entry
890      */

891     public Entry getSelectedEntry() {
892         Object JavaDoc object = getLastSelectedPathComponent();
893         if (object != null)
894             return objectToEntry(object);
895         return null;
896     }
897
898     /**
899      * Returns the parent of the selected entry
900      */

901     public Entry getSelectedEntryParent() {
902         Object JavaDoc object = getLastSelectedPathComponent();
903         if (object != null)
904             return objectToEntry(((DefaultMutableTreeNode JavaDoc) object).getParent());
905         return null;
906     }
907
908     /**
909      * Refreshes the given path.
910      */

911     protected void refreshPath(TreePath JavaDoc treePath){
912         collapsePath(treePath);
913         expandPath(treePath);
914     }
915
916     /**
917      * Refresh all the tree
918      */

919     public void refreshAll() {
920         createGraphicalInitialContext();
921         TreePath JavaDoc p = new TreePath JavaDoc(rootNode.getPath());
922         refreshPath(p);
923         selectedNode_ = "";
924         refreshPanel();
925         refreshActionMenu();
926         refreshToolBar();
927     }
928
929     /**
930      * Refresh the selected node
931      */

932     public void refreshSelectedNode() {
933         TreePath JavaDoc path = getSelectionPath();
934         DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) path.getLastPathComponent();
935         if (isExpanded(path)) {
936             collapsePath(path);
937             expandPath(path);
938         } else if (node.isLeaf()) {
939             fireTreeExpanded(path);
940         }
941         selectedNode_ = "";
942         refreshPanel();
943         refreshActionMenu();
944         refreshToolBar();
945     }
946
947     /**
948      * Gives the initial context
949      * @return The initial context
950      */

951     public Context getInitialContext() {
952         return graphicalInitialContext_;
953     }
954
955     /**
956      * Returns true if this initial context contains an entry for the specified id.
957      * @param id Key whose presence in this initial context is to be tested.
958      * @return True if this initial context contains an entry for the specified id.
959      */

960     public boolean containsEntry(String JavaDoc id) {
961         Entry entry = graphicalInitialContext_.getLocalEntry(id);
962         return entry != null;
963     }
964
965     /**
966      * Fixes the view panel for the tree (Where the associated panels will be displayed).
967      * @param viewPanel The panel to use to display associated panels
968      */

969     public void setTargetPanel(ViewPanel viewPanel) {
970         viewPanel_ = viewPanel;
971     }
972
973     /**
974      * Fixes the status bar for the tree (Where info will be displayed)
975      * @param statusField
976      */

977     public void setStatusBar(StatusBar statusBar){
978         statusBar_ = statusBar;
979     }
980
981     /**
982      * Indicates if the popup are enabled or not. By default, the popup menus are enabled.
983      * @param popupEnabled True if the popup menu have to be enabled, false either.
984      */

985     public void setPopupEnabled(boolean popupEnabled){
986         popupEnabled_ = popupEnabled;
987     }
988     
989     /**
990      * Returns true if the popup menus are enabled.
991      * @return true if the popup menus are enabled.
992      */

993     public boolean isPopupEnabled(){
994         return popupEnabled_;
995     }
996
997     /**
998      * Indicates if the Drag and Drop is enabled or not. By default, the Drag and Drop is available.
999      * @param dndEnabled True if the popup menu have to be enabled, false either.
1000     */

1001    public void setDragAndDropEnabled(boolean dndEnabled){
1002        dndEnabled_ = dndEnabled;
1003    }
1004        
1005    /**
1006     * Returns true if the Drag and Drop is enabled.
1007     * @return true if the Drag and Drop is enabled.
1008     */

1009    public boolean isDragAndDropEnabled(){
1010        return dndEnabled_;
1011    }
1012    
1013    /**
1014     * Indicates if the application allows the selection of several roles at the same time.
1015     * @param multipleRolesEnabled True if the application allows the selection of several roles at the same time, false either.
1016     */

1017    public void setMultipleRolesEnabled(boolean multipleRolesEnabled){
1018        multipleRolesEnabled_ = multipleRolesEnabled;
1019    }
1020    
1021    /**
1022     * Returns true if the application allows the selection of several roles at the same time.
1023     * @return true if the application allows the selection of several roles at the same time, false either.
1024     */

1025    public boolean isMultipleRolesEnabled(){
1026        return multipleRolesEnabled_;
1027    }
1028    
1029    /**
1030     * Provides the customizations to use for the dynamic tree.
1031     * @return The AdminCustomization to use.
1032     */

1033    public AdminCustomization getAdminCustomization(){
1034        return custom;
1035    }
1036    
1037    /**
1038     * Fixes the menu bar to use
1039     * @param jMenuBar
1040     */

1041    public void setJMenuBar(JMenuBar JavaDoc jMenuBar) {
1042        menuBar_ = jMenuBar;
1043        actionMenu_ = new JMenu JavaDoc("Actions");
1044        actionMenu_.setEnabled(false);
1045        menuBar_.add(actionMenu_);
1046        if(browserProperty_!=null)
1047            refreshRoleMenu(((RoleManagement)browserProperty_).getRoleList());
1048    }
1049
1050    /**
1051     * Fixes the toolBar to use
1052     * @param jToolBar The toolBar to use
1053     */

1054    public void setJToolBar(JToolBar JavaDoc jToolBar){
1055        toolBar_ = jToolBar;
1056        if(toolBar_!=null && toolBar_.getComponents().length==0)
1057            toolBar_.setVisible(false);
1058    }
1059    
1060    // ==================================================================
1061
//
1062
// Public methods for Tree interface.
1063
//
1064
// ==================================================================
1065

1066    /**
1067     * Refresh the selected node.
1068     */

1069    public void
1070    refresh(){
1071        refreshSelectedNode();
1072    }
1073
1074    /**
1075     * Closes the tree
1076     * Unselects the selected panel
1077     */

1078    public void
1079    close(){
1080        if(viewPanel_!=null){
1081            Panel currentPanel = viewPanel_.getViewPanel();
1082            if(currentPanel!=null && currentTreeView_!=null)
1083                currentPanel.unselected(currentTreeView_);
1084        }
1085    }
1086    
1087    /**
1088     * Adds an object into the initial context.
1089     *
1090     * @param name Name of the object
1091     * @param value The object to add
1092     */

1093    public void
1094    addEntry(Object JavaDoc name, Object JavaDoc value){
1095        addEntry(name,value,0);
1096    }
1097
1098    /**
1099     * Adds an object into the initial context and expands the node until a specific level if this one is a context.
1100     *
1101     * @param name Name of the object
1102     * @param value The object to add
1103     * @param level The level (>0 for a specific level or <0 for all levels)
1104     */

1105    public void
1106    addEntry(Object JavaDoc name, Object JavaDoc value, int level){
1107        initialContext_.add(new InitialEntry(name.toString(),value,level));
1108        addToInitialContext(name.toString(),value,level);
1109    }
1110    
1111    /**
1112     * Refreshes the selected node name.
1113     *
1114     * @param oldName The old name.
1115     * @param newName The new name.
1116     */

1117    public void
1118    renameSelectedNode(String JavaDoc oldName, String JavaDoc newName){
1119        Object JavaDoc object = getLastSelectedPathComponent();
1120        if (object != null && oldName!=null && newName!=null) {
1121            DefaultMutableTreeNode JavaDoc node = (DefaultMutableTreeNode JavaDoc) object;
1122            String JavaDoc selectedNode = pathToString(node);
1123            String JavaDoc prefixe = selectedNode.substring(0,selectedNode.lastIndexOf(oldName));
1124            if(!selectedNode.equals(prefixe)){
1125                // The oldName is contained by the selected node
1126
Object JavaDoc[] keys = nodeState_.keySet().toArray();
1127                for(int i=0 ; i<keys.length ; i++) {
1128                    if(keys[i].toString().startsWith(prefixe+oldName)){
1129                        boolean valid = true;
1130                        String JavaDoc oldSuffixe = ((String JavaDoc)keys[i]).substring(prefixe.length() + oldName.length());
1131                        String JavaDoc newSuffixe = oldSuffixe;
1132                        if(oldSuffixe!=null && !oldSuffixe.equals("")){
1133                            int index = oldSuffixe.indexOf("/");
1134                            if(index==-1 || index>0) {
1135                                valid = false;
1136                            }
1137                        }
1138                        if(valid){
1139                            String JavaDoc oldEntry = prefixe + oldName + oldSuffixe;
1140                            String JavaDoc newEntry = prefixe + newName + newSuffixe;
1141                            nodeState_.put(newEntry,nodeState_.get(oldEntry));
1142                            nodeState_.remove(oldEntry);
1143                        }
1144                    }
1145                }
1146            }
1147        }
1148    }
1149
1150    /**
1151     * Removes the entry identified by the given name. This entry must be found within the InitialContext.
1152     *
1153     * @param name The name
1154     */

1155    public void
1156    removeEntry(Object JavaDoc name){
1157        Iterator JavaDoc it = initialContext_.iterator();
1158        InitialEntry elementToRemove = null;
1159        while (it.hasNext()) {
1160            InitialEntry element = (InitialEntry) it.next();
1161            if(element.getName().toString().equals(name.toString())) {
1162                elementToRemove = element;
1163                break;
1164            }
1165        }
1166        if(elementToRemove!=null)
1167            initialContext_.remove(elementToRemove);
1168    }
1169
1170    /**
1171     * Renames the entry identified by the given name.
1172     * This entry must be found within the InitialContext.
1173     *
1174     * @param currentName The current name of the entry.
1175     * @param newName The new name.
1176     */

1177    public void
1178    renameInitialEntry(Object JavaDoc currentName, Object JavaDoc newName){
1179        Iterator JavaDoc it = initialContext_.iterator();
1180        InitialEntry elementToRemove = null;
1181        while (it.hasNext()) {
1182            InitialEntry element = (InitialEntry) it.next();
1183            if(element.getName().toString().equals(currentName.toString())) {
1184                element.setName(newName.toString());
1185                break;
1186            }
1187        }
1188        // Fixes the selected path, because the use of this DynamicTree in the ArgoUML project
1189
// makes that the selectedNode_ is not well initialized.
1190
selectedNode_ = "Root/" + currentName;
1191        // Updates the pathes
1192
updateInitialPathes(currentName.toString(), newName.toString());
1193        // Updates the selected node
1194
String JavaDoc prefixe = selectedNode_.substring(0,selectedNode_.lastIndexOf(currentName.toString()));
1195        selectedNode_ = prefixe + newName.toString();
1196    }
1197
1198    
1199    /**
1200     * Removes all the entries contained within the InitialContext.
1201     */

1202    public void
1203    clear(){
1204        initialContext_.clear();
1205    }
1206
1207    /**
1208     * Provides the number of entries contained within the InitialContext.
1209     * @return
1210     */

1211    public int
1212    getInitialContextSize(){
1213        return graphicalInitialContext_.getSize();
1214    }
1215    
1216    // ==================================================================
1217
//
1218
// Public methods for Autoscroll interface.
1219
//
1220
// ==================================================================
1221

1222    public void autoscroll(Point JavaDoc cursorLocn){
1223        Rectangle JavaDoc rect=getVisibleRect();
1224        Dimension JavaDoc dim=getSize();
1225        
1226        // Vertival autoscroll
1227
if(cursorLocn.y>rect.y+rect.height-10) {
1228            rect.y=Math.min(rect.y+10,dim.height-rect.height);
1229        } else if(cursorLocn.y<rect.y+10) {
1230            int i = rect.y+rect.height-10;
1231            rect.y=Math.max(rect.y-10,0);
1232        }
1233        
1234        // Horizontal autoscroll
1235
if(cursorLocn.x>rect.x+rect.width-10) {
1236            rect.x=Math.min(rect.x+10,dim.width-rect.width);
1237        } else if(cursorLocn.x<rect.x+10) {
1238            rect.x=Math.max(rect.x-10,0);
1239        }
1240        
1241        scrollRectToVisible(rect);
1242    }
1243              
1244    public Insets JavaDoc getAutoscrollInsets(){
1245        Rectangle JavaDoc rect=getVisibleRect();
1246        Dimension JavaDoc dim=getSize();
1247        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);
1248        return inset;
1249    }
1250
1251    // ==================================================================
1252
//
1253
// Internal classes for JTree management.
1254
//
1255
// ==================================================================
1256

1257    /**
1258     * Mouse Adapter
1259     * Use to draw Popup Menu
1260     */

1261    final class MyMouseAdapter extends MouseAdapter JavaDoc {
1262        public void mousePressed(MouseEvent JavaDoc e) {
1263            popupLayout(e);
1264        }
1265        public void mouseReleased(MouseEvent JavaDoc e) {
1266            popupLayout(e);
1267        }
1268        private void popupLayout(MouseEvent JavaDoc e) {
1269            if (e.isPopupTrigger()&& popupEnabled_) {
1270                showMenu(e.getPoint());
1271            }
1272        }
1273    }
1274
1275    /**
1276     * Tree Will Expand Listener
1277     * Use to complete node : it adds child to current node
1278     */

1279    final class MyTreeWillExpandListener implements TreeWillExpandListener JavaDoc {
1280        public void treeWillCollapse(TreeExpansionEvent JavaDoc event) {
1281            DefaultMutableTreeNode JavaDoc currentNode = (DefaultMutableTreeNode JavaDoc) event.getPath().getLastPathComponent();
1282            Entry e = (Entry) currentNode.getUserObject();
1283            nodeState_.put(pathToString(currentNode), new GraphicState(false));
1284        }
1285
1286        public void treeWillExpand(TreeExpansionEvent JavaDoc event) {
1287            DefaultMutableTreeNode JavaDoc currentNode = (DefaultMutableTreeNode JavaDoc) event.getPath().getLastPathComponent();
1288            Entry e = (Entry) currentNode.getUserObject();
1289            Object JavaDoc userObject = e.getValue();
1290            nodeState_.put(pathToString(currentNode), new GraphicState(true));
1291            currentNode.removeAllChildren();
1292            Entry[] entries = ((Context) userObject).getEntries();
1293            for (int i = 0; i < entries.length; i++) {
1294                Entry entry = entries[i];
1295                DefaultMutableTreeNode JavaDoc childNode = addObject(currentNode, (ExtendedEntry) entry);
1296            }
1297            treeModel.reload(currentNode);
1298        }
1299    }
1300
1301    /**
1302     * Tree Expansion Listener
1303     * Use to refresh node
1304     */

1305    final class MyTreeExpansionListener implements TreeExpansionListener JavaDoc {
1306        public void treeCollapsed(TreeExpansionEvent JavaDoc event) {
1307        }
1308
1309        public void treeExpanded(TreeExpansionEvent JavaDoc event) {
1310            DefaultMutableTreeNode JavaDoc node =
1311                (DefaultMutableTreeNode JavaDoc) (event.getPath()).getLastPathComponent();
1312            if (!node.isLeaf()) {
1313                Enumeration JavaDoc children = node.children();
1314                while (children.hasMoreElements()) {
1315                    DefaultMutableTreeNode JavaDoc childNode = (DefaultMutableTreeNode JavaDoc) children.nextElement();
1316                    Entry entry = (Entry) childNode.getUserObject();
1317                    if (nodeState_.containsKey(pathToString(childNode))) {
1318                        GraphicState gs = (GraphicState) nodeState_.get(pathToString(childNode));
1319                        if (gs.isExpanded()) {
1320                            expandPath(new TreePath JavaDoc(childNode.getPath()));
1321                        }
1322                    }
1323
1324                    if (selectedNode_.equals(pathToString(childNode))) {
1325                        setSelectionPath(
1326                            new TreePath JavaDoc(treeModel.getPathToRoot(childNode)));
1327                    }
1328                }
1329            }
1330        }
1331    }
1332
1333    /**
1334     * Tree Selection Listener
1335     * Use to put the panel corresponding to the selected node
1336     */

1337    final class MyTreeSelectionListener implements TreeSelectionListener JavaDoc {
1338
1339        public void valueChanged(TreeSelectionEvent JavaDoc e) {
1340            refreshPanel();
1341            refreshActionMenu();
1342            refreshToolBar();
1343            refreshStatusBar();
1344        }
1345    }
1346
1347    /**
1348     * Tree Cell Renderer
1349     * Use to put the icon corresponding to the class
1350     * of the Value object of the Entry
1351     */

1352    final class MyTreeCellRenderer extends DefaultTreeCellRenderer JavaDoc {
1353
1354        public Component JavaDoc getTreeCellRendererComponent(JTree JavaDoc tree,Object JavaDoc value,boolean selected,boolean expanded,boolean leaf,int row,boolean hasFocus) {
1355            super.getTreeCellRendererComponent(tree,value,selected,expanded,leaf,row,hasFocus);
1356
1357            // Put the appropriate icon if one is defined.
1358
Entry entry = objectToEntry(value);
1359            if (custom != null) {
1360                Icon JavaDoc icon = custom.getIcon((ExtendedEntry)entry);
1361                if (icon != null)
1362                    setIcon(icon);
1363            }
1364
1365            // Put the name of the entry as the label of the node
1366
setText(entry.getName().toString());
1367
1368            //setToolTipText("Essai");
1369
return this;
1370        }
1371
1372    }
1373
1374    /**
1375     * Tree Model
1376     * Uses to know if a node is leaf or not
1377     */

1378    final class MyTreeModel extends DefaultTreeModel JavaDoc {
1379
1380        public MyTreeModel(TreeNode JavaDoc root) {
1381            super(root);
1382        }
1383
1384        public boolean isLeaf(Object JavaDoc node) {
1385            Entry entry = objectToEntry(node);
1386            Object JavaDoc o = entry.getValue();
1387            // Optimzed version : An entry is a leaf if it is not a Context instance
1388
return !(o instanceof Context);
1389            // An entry is a leaf if it is not a Context instance or if it's a Context instance without child.
1390
//return (!(o instanceof Context) || ((o instanceof Context) && !hasChild((Context) o)));
1391
}
1392
1393    }
1394
1395    /**
1396     * Uses to know if a node is expanded
1397     */

1398    protected class GraphicState {
1399
1400        protected boolean isExpanded_;
1401
1402        public GraphicState(boolean isExpanded) {
1403            isExpanded_ = isExpanded;
1404        }
1405
1406        public boolean isExpanded() {
1407            return isExpanded_;
1408        }
1409
1410        public void isEspanded(boolean value) {
1411            isExpanded_ = value;
1412        }
1413
1414    }
1415
1416    // ==================================================================
1417
//
1418
// Public methods of RoleManagement interface.
1419
//
1420
// ==================================================================
1421

1422    /**
1423     * Provides the current role.
1424     *
1425     * @return The current role.
1426     */

1427    public Role[] getCurrentRoles(){
1428        if(browserProperty_!=null){
1429            return ((RoleManagement)browserProperty_).getCurrentRoles();
1430        }
1431        return null;
1432    }
1433    
1434    /**
1435     * Fixes the current role.
1436     *
1437     * @param role_id The id of the role.
1438     */

1439    public void setCurrentRole(String JavaDoc[] role_ids){
1440        if(browserProperty_!=null){
1441            ((RoleManagement)browserProperty_).setCurrentRole(role_ids);
1442            custom.clear();
1443        }
1444        if(browserProperty_!=null)
1445            refreshRoleMenu(((RoleManagement)browserProperty_).getRoleList());
1446        refreshAll();
1447    }
1448
1449    /**
1450     * Fixes the current role.
1451     *
1452     * @param role The role to define as current role.
1453     */

1454    public void setCurrentRole(Role[] roles){
1455        if(browserProperty_!=null){
1456            ((RoleManagement)browserProperty_).setCurrentRole(roles);
1457            custom.clear();
1458        }
1459        if(browserProperty_!=null)
1460            refreshRoleMenu(((RoleManagement)browserProperty_).getRoleList());
1461        refreshAll();
1462    }
1463
1464    /**
1465     * Provides the list of all define roles.
1466     *
1467     * @return The list of roles.
1468     */

1469    public Role[] getRoleList(){
1470        if(browserProperty_!=null){
1471            ((RoleManagement)browserProperty_).getRoleList();
1472        }
1473        return null;
1474    }
1475        
1476    // ==================================================================
1477
//
1478
// Internal classes for Drag & Drop.
1479
//
1480
// ==================================================================
1481

1482    /**
1483     * Implementation of DragGestureListener interface.
1484     *
1485     * @author <a HREF="mailto:Jerome.Moroy@lifl.fr">Jerome Moroy</a>
1486     *
1487     * @version 0.1
1488     */

1489    protected class TreeDragGestureListener implements DragGestureListener JavaDoc {
1490
1491        /*
1492         * @see java.awt.dnd.DragGestureListener#dragGestureRecognized(java.awt.dnd.DragGestureEvent)
1493         */

1494        public void dragGestureRecognized(DragGestureEvent JavaDoc dge) {
1495            if(dndEnabled_){
1496                Transferable transferable = new EntryViewTransferable(new EntryView(DynamicTree.this.getSelectedEntry()));
1497                try {
1498                    dragSource_.startDrag(dge,DragSource.DefaultLinkDrop, transferable, dragSourceListener_);
1499                }catch(InvalidDnDOperationException JavaDoc idoe) {
1500                    System.out.println( idoe );
1501                }
1502            }
1503        }
1504    }
1505    
1506    /**
1507     * Implementation of DragSourceListener interface
1508     *
1509     *
1510     * @author <a HREF="mailto:Jerome.Moroy@lifl.fr">Jerome Moroy</a>
1511     *
1512     * @version 0.1
1513     */

1514    public class TreeDragSourceListener implements DragSourceListener JavaDoc {
1515
1516        /** The current dropAction */
1517        protected int dropAction_;
1518        
1519        /*
1520         * DnD problem:
1521         * This way to implement a Drag&Drop mechanism seems to be bad
1522         * because the DragSourceDragEvent is not correctly initialized.
1523         * Indeed, when the Drag&Drop begins (entering in dragStart state),
1524         * no problem is detected, but when the drop action change (call
1525         * to the dropActionChanged method), the associated dropAction refers
1526         * to an unknown action. That why, in order to know the refering drop
1527         * action we use the current state of the input devices:
1528         * 16 -> left click -> Move
1529         * 18 -> Ctrl + left click -> Copy
1530         * 19 -> Ctrl + Shift + left click -> Link
1531         */

1532        
1533        /**
1534         * Provides the dropAction depending on the current state of the input devices.
1535         * @param The current state of the input devices.
1536         * @return The corresponding dropAction identifier.
1537         */

1538        protected int getDropAction(int gestureModifiers){
1539            if(gestureModifiers==16)
1540                return DnDConstants.ACTION_MOVE;
1541            else if(gestureModifiers==18)
1542                return DnDConstants.ACTION_COPY;
1543            else if(gestureModifiers==19)
1544                return DnDConstants.ACTION_LINK;
1545            else
1546                return 0;
1547        }
1548        
1549        /**
1550         * Fixes the appropriate icon.
1551         */

1552        protected void setIcon(DragSourceDragEvent JavaDoc dsde){
1553            DragSourceContext JavaDoc context = dsde.getDragSourceContext();
1554            dropAction_ = getDropAction(dsde.getGestureModifiers());
1555            if (dropAction_ == DnDConstants.ACTION_COPY) {
1556                context.setCursor(DragSource.DefaultCopyDrop);
1557            } else if (dropAction_ == DnDConstants.ACTION_MOVE) {
1558                context.setCursor(DragSource.DefaultMoveDrop);
1559            } else if (dropAction_ == DnDConstants.ACTION_LINK) {
1560                context.setCursor(DragSource.DefaultLinkDrop);
1561            } else {
1562                context.setCursor(DragSource.DefaultLinkNoDrop);
1563            }
1564        }
1565        
1566        /**
1567         * Fixes the appropriate icon.
1568         */

1569        protected void setForbiddenIcon(DragSourceEvent JavaDoc dse){
1570            DragSourceContext JavaDoc context = dse.getDragSourceContext();
1571            if (dropAction_ == DnDConstants.ACTION_COPY) {
1572                context.setCursor(DragSource.DefaultCopyNoDrop);
1573            } else if (dropAction_ == DnDConstants.ACTION_MOVE) {
1574                context.setCursor(DragSource.DefaultMoveNoDrop);
1575            } else if (dropAction_ == DnDConstants.ACTION_LINK) {
1576                context.setCursor(DragSource.DefaultLinkNoDrop);
1577            } else {
1578                context.setCursor(DragSource.DefaultLinkNoDrop);
1579            }
1580        }
1581        
1582        /*
1583         * @see java.awt.dnd.DragSourceListener#dragEnter(java.awt.dnd.DragSourceDragEvent)
1584         */

1585        public void dragEnter(DragSourceDragEvent JavaDoc dsde) {
1586            setIcon(dsde);
1587        }
1588
1589        /*
1590         * @see java.awt.dnd.DragSourceListener#dragOver(java.awt.dnd.DragSourceDragEvent)
1591         */

1592        public void dragOver(DragSourceDragEvent JavaDoc dsde) {
1593        }
1594
1595        /*
1596         * @see java.awt.dnd.DragSourceListener#dropActionChanged(java.awt.dnd.DragSourceDragEvent)
1597         */

1598        public void dropActionChanged(DragSourceDragEvent JavaDoc dsde) {
1599            setIcon(dsde);
1600        }
1601        
1602        /*
1603         * @see java.awt.dnd.DragSourceListener#dragExit(java.awt.dnd.DragSourceEvent)
1604         */

1605        public void dragExit(DragSourceEvent JavaDoc dse) {
1606            setForbiddenIcon(dse);
1607        }
1608
1609        /*
1610         * @see java.awt.dnd.DragSourceListener#dragDropEnd(java.awt.dnd.DragSourceDropEvent)
1611         */

1612        public void dragDropEnd(DragSourceDropEvent JavaDoc dsde) {
1613        }
1614
1615    }
1616
1617    /**
1618     * Implementation of DropTargetListener interface.
1619     *
1620     * @author <a HREF="mailto:Jerome.Moroy@lifl.fr">Jerome Moroy</a>
1621     *
1622     * @version 0.1
1623     */

1624    protected class TreeDropTargetListener implements DropTargetListener JavaDoc {
1625
1626        /** The old position of the cursor */
1627        protected Point JavaDoc oldPosition_ = new Point JavaDoc(0,0);
1628
1629        /** The old Path*/
1630        protected TreePath JavaDoc oldPath_ = null;
1631        
1632        /** The currentAction_ */
1633        protected boolean actionChanged_ = false;
1634        
1635        /*
1636         * @see java.awt.dnd.DropTargetListener#dragEnter(java.awt.dnd.DropTargetDragEvent)
1637         */

1638        public void dragEnter(DropTargetDragEvent JavaDoc dtde) {
1639            dtde.acceptDrag(dtde.getDropAction());
1640        }
1641
1642        /*
1643         * @see java.awt.dnd.DropTargetListener#dragOver(java.awt.dnd.DropTargetDragEvent)
1644         */

1645        public void dragOver(DropTargetDragEvent JavaDoc dtde) {
1646            dtde.acceptDrag(dtde.getDropAction());
1647            String JavaDoc label = "";
1648            TreePath JavaDoc path = getPath(dtde.getLocation());
1649            if(path==null){
1650                if(statusBar_!=null)
1651                    statusBar_.setText(label);
1652                oldPath_ = null;
1653            } else if(oldPath_ == null || (path != null && !path.equals(oldPath_)) || actionChanged_){
1654                actionChanged_ = false;
1655                oldPath_ = path;
1656                Entry entry = objectToEntry(path.getLastPathComponent());
1657                if(custom != null){
1658                    label = custom.getDropLabel((ExtendedEntry) entry, dtde.getDropAction());
1659                    if(label == null)
1660                        label = "";
1661                    if(statusBar_ != null)
1662                        statusBar_.setText(label);
1663                }
1664            }
1665        }
1666
1667        /*
1668         * @see java.awt.dnd.DropTargetListener#dropActionChanged(java.awt.dnd.DropTargetDragEvent)
1669         */

1670        public void dropActionChanged(DropTargetDragEvent JavaDoc dtde) {
1671            dtde.acceptDrag(dtde.getDropAction());
1672            actionChanged_ = true;
1673        }
1674
1675        /*
1676         * @see java.awt.dnd.DropTargetListener#dragExit(java.awt.dnd.DropTargetEvent)
1677         */

1678        public void dragExit(DropTargetEvent JavaDoc dte) {
1679        }
1680
1681        /*
1682         * @see java.awt.dnd.DropTargetListener#drop(java.awt.dnd.DropTargetDropEvent)
1683         */

1684        public void drop(DropTargetDropEvent JavaDoc dtde) {
1685            
1686            DataFlavor JavaDoc[] df = EntryViewTransferable.flavors_;
1687            DataFlavor JavaDoc chosen = null;
1688            for (int i = 0; i < df.length; i++) {
1689                if(dtde.isDataFlavorSupported(df[i])){
1690                    chosen = df[i];
1691                    break;
1692                }
1693            }
1694            
1695            EntryView entryView = null;
1696            // This method is responsible of a bug (it is waiting for ???)
1697
// dtde.acceptDrop(acceptableActions_);
1698
try {
1699                entryView = (EntryView)dtde.getTransferable().getTransferData(chosen);
1700            } catch (UnsupportedFlavorException JavaDoc e1) {
1701                e1.printStackTrace();
1702            } catch (IOException JavaDoc e1) {
1703                e1.printStackTrace();
1704            }
1705            
1706            TreePath JavaDoc path = getPath(dtde.getLocation());
1707            if (path != null) {
1708                selectionModel.setSelectionPath(path);
1709                Entry entry = objectToEntry(getLastSelectedPathComponent());
1710                if(custom != null) {
1711                    DropAction dropAction = custom.getDropAction((ExtendedEntry) entry, dtde.getDropAction());
1712                    if(dropAction!=null && entryView!=null){
1713                        try{
1714                            dropAction.execute(new DefaultDropTreeView(DynamicTree.this, entryView.getCurrentEntry()));
1715                        }catch(Exception JavaDoc e){
1716                            JOptionPane.showMessageDialog(null, e.getMessage(), "Drag & Drop error ! (" + e.getClass().getName() + ")", JOptionPane.ERROR_MESSAGE);
1717                        }
1718                        DynamicTree.this.refreshAll();
1719                    }
1720                }
1721            }
1722        }
1723    }
1724
1725    private final class RoleComparator implements Comparator JavaDoc{
1726
1727        protected int compare(Role r1, Role r2) {
1728            return r1.getId().compareTo(r2.getId());
1729        }
1730
1731        public int compare(Object JavaDoc o1, Object JavaDoc o2) {
1732            return compare((Role)o1,(Role)o2);
1733        }
1734
1735    }
1736
1737    private final class RoleSelected extends AbstractAction JavaDoc{
1738
1739        protected Role role_;
1740        
1741        public RoleSelected(Role role){
1742            super(role.getId());
1743            role_ = role;
1744        }
1745        
1746        public void actionPerformed(ActionEvent JavaDoc e) {
1747            if(DynamicTree.this.multipleRolesEnabled_){
1748                Role[] currentRoles = DynamicTree.this.getCurrentRoles();
1749                Vector JavaDoc theRoles = new Vector JavaDoc(Arrays.asList(currentRoles));
1750                if(theRoles.contains(role_))
1751                    theRoles.remove(role_);
1752                else
1753                    theRoles.add(role_);
1754                DynamicTree.this.setCurrentRole((Role[])theRoles.toArray(new Role[0]));
1755            } else {
1756                Role currentRole = (DynamicTree.this.getCurrentRoles())[0];
1757                if(!role_.getId().equals(currentRole.getId())) {
1758                    DynamicTree.this.setCurrentRole(new Role[]{role_});
1759                }
1760            }
1761            refreshAll();
1762        }
1763
1764    }
1765
1766}
1767
Popular Tags