KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > enode > ExtensibleNode


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Nokia. Portions Copyright 2003 Nokia.
17  * All Rights Reserved.
18  */

19
20 package org.netbeans.api.enode;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.awt.Image JavaDoc;
26 import javax.swing.Action JavaDoc;
27 import javax.swing.ImageIcon JavaDoc;
28 import javax.swing.Icon JavaDoc;
29
30 import org.openide.nodes.AbstractNode;
31 import org.openide.nodes.Children;
32 import org.openide.util.Lookup;
33
34
35 /**
36  * A node capable of reading the list of actions from
37  * the system file system. The content of its lookup can also be
38  * specified declaratively.
39  * @author David Strupl
40  */

41 public class ExtensibleNode extends AbstractNode {
42     
43     /** Folder on the system filesystem (context in the Registry)
44      * where actions for extensible nodes are stored.
45      */

46     public static final String JavaDoc E_NODE_ACTIONS = "/ExtensibleNode/Actions/"; // NOI18N
47

48     /** Folder on the system filesystem (context in the Registry)
49      * where lookup objects for extensible nodes are stored.
50      */

51     public static final String JavaDoc E_NODE_LOOKUP = "/ExtensibleNode/Lookup/"; // NOI18N
52

53     /** Folder on the system filesystem (context in the Registry)
54      * where the icons base dirs are stored.
55      */

56     public static final String JavaDoc E_NODE_ICONS = "/ExtensibleNode/Icons/"; // NOI18N
57

58     /** Folder on the system filesystem (context in the Registry)
59      * where submenu information is kept.
60      */

61     public static final String JavaDoc E_NODE_SUBMENUS = "/ExtensibleNode/SubMenu/"; // NOI18N
62
/**
63      * Our Registry context paths.
64      */

65     private String JavaDoc[] paths;
66
67     /**
68      * Reference the implementation of the actions finder.
69      */

70     private ExtensibleActions actionManager;
71     
72     /**
73      * Reference the implementation of the icons finder.
74      */

75     private ExtensibleIcons iconManager;
76     
77     /**
78      * Listener attached to iconManager.
79      */

80     private IconChangeListener iconChangeListener;
81     
82     /**
83      * The configured icons can be switched via setting the icon name.
84      */

85     private String JavaDoc iconName;
86     
87     /**
88      * Creates a new instance of ExtensibleNode. The paths
89      * parameter is used as a base directory for finding
90      * actions, lookup objects and icon.
91      * @param path folder path on the system file system
92      * @param useHierarchicalPath whether the content of parent folders
93      * up to the root for a given entity (actions, lookup) is to be
94      * taken into account when searching for the objects
95      */

96     public ExtensibleNode(String JavaDoc path, boolean useHierarchicalPath) {
97         this(useHierarchicalPath ?
98                 computeHierarchicalPaths(path) :
99                 new String JavaDoc[] { path }
100         );
101     }
102     
103     /**
104      * Creates a new instance of ExtensibleNode. The paths
105      * parameter is used as a base directory for finding
106      * actions, lookup objects and icon.
107      * @param path folder path on the system file system
108      */

109     public ExtensibleNode(String JavaDoc[] paths) {
110         this(Children.LEAF, paths);
111     }
112     
113     /**
114      * Creates a new instance of ExtensibleNode. The paths
115      * parameter is used as a base directory for finding
116      * actions, lookup objects and icon.
117      * @param ch children of the node
118      * @param path folder path on the system file system
119      * @param useHierarchicalPath whether the content of parent folders
120      * up to the root for a given entity (actions, lookup) is to be
121      * taken into account when searching for the objects
122      */

123     public ExtensibleNode(Children ch, String JavaDoc path, boolean useHierarchicalPath) {
124         this(ch, useHierarchicalPath ?
125                 computeHierarchicalPaths(path) :
126                 new String JavaDoc[] { path }
127         );
128     }
129     
130     /**
131      * Creates a new instance of ExtensibleNode. The paths
132      * parameter is used as a base directory for finding
133      * actions, lookup objects and icon.
134      * @param ch children of the node
135      * @param path folder path on the system file system
136      */

137     public ExtensibleNode(Children ch, String JavaDoc[] paths) {
138         this(ch, paths, new ExtensibleLookup());
139     }
140     
141     /**
142      * Creates a new instance of ExtensibleNode. The paths
143      * parameter is used as a base directory for finding
144      * actions and icon. <EM> Warning:</EM> By using this constructor
145      * you are responsible for creating the lookup for this node. The
146      * extensible lookup is NOT used in this case.
147      * @param ch children of the node
148      * @param path folder path on the system file system
149      * @param Lookup l used as a lookup for this node.
150      * <EM> Warning:</EM> By using this constructor
151      * you are responsible for creating the lookup for this node. The
152      * extensible lookup is NOT used in this case.
153      * @param useHierarchicalPath whether the content of parent folders
154      * up to the root for a given entity (actions, lookup) is to be
155      * taken into account when searching for the objects
156      */

157     public ExtensibleNode(Children ch, Lookup l, String JavaDoc path, boolean useHierarchicalPath) {
158         this(ch, l, useHierarchicalPath ?
159                 computeHierarchicalPaths(path) :
160                 new String JavaDoc[] { path }
161         );
162     }
163     
164     /**
165      * Creates a new instance of ExtensibleNode. The paths
166      * parameter is used as a base directory for finding
167      * actions and icon. <EM> Warning:</EM> By using this constructor
168      * you are responsible for creating the lookup for this node. The
169      * extensible lookup is NOT used in this case.
170      * @param ch children of the node
171      * @param path folder path on the system file system
172      * @param Lookup l used as a lookup for this node.
173      * <EM> Warning:</EM> By using this constructor
174      * you are responsible for creating the lookup for this node. The
175      * extensible lookup is NOT used in this case.
176      */

177     public ExtensibleNode(Children ch, Lookup l, String JavaDoc[] paths) {
178         super(ch, l);
179         this.paths = paths;
180     }
181     
182     /**
183      * Private constructor taking the lookup argument. The lookup is
184      * not fully initialized until the call to <code>setExtensibleNode</code>.
185      */

186     private ExtensibleNode(Children ch, String JavaDoc[] paths, ExtensibleLookup l) {
187         super(ch, l);
188         this.paths = paths;
189         l.setNode(this);
190     }
191     
192     /**
193      * Overriding superclass method. This implementaion can call
194      * super.getActions or reads the actions list from the system file system
195      * (layer files, Registry).
196      * @param context please see <code>AbstractNode.getActions(boolean)</code>
197      * for details regarding this argument
198      */

199     public Action JavaDoc[] getActions (boolean context) {
200         if (context) {
201             return super.getActions(context);
202         }
203         return getActionManager().getActions();
204     }
205     
206     /**
207      * Overriden to fetch the icons from the ExtensibleIcons instance.
208      */

209     public Image JavaDoc getIcon(int type) {
210         int size = (type == 1 || type == 3) ? 16 : 32;
211         ImageIcon JavaDoc ii = null;
212         if (getIconName() == null) {
213             ii = getIconManager().getDefaultIcon(size);
214         } else {
215             ii = getIconManager().getIcon(getIconName(), size);
216         }
217         return ii.getImage();
218     }
219     
220     /**
221      * Overriden to fetch the icons from the ExtensibleIcons instance.
222      */

223     public Image JavaDoc getOpenedIcon(int type) {
224         return getIcon(type);
225     }
226     
227     /**
228      * Lazy initialization of the actions manager
229      */

230     private ExtensibleActions getActionManager() {
231         if (actionManager == null) {
232             actionManager = ExtensibleActions.getInstance(getPaths());
233         }
234         return actionManager;
235     }
236     
237     /**
238      * Lazy initialization of the icon manager
239      */

240     private ExtensibleIcons getIconManager() {
241         if (iconManager == null) {
242             iconManager = ExtensibleIcons.getInstance(getPaths());
243             iconManager.addPropertyChangeListener(getIconChangeListener());
244         }
245         return iconManager;
246     }
247     
248     /**
249      * Getter for the paths on the system file system (Registry).
250      * @return String[] the entries in the resulting array do not contain
251      * the prefix E_NODE_ACTIONS, E_NODE_LOOKUP. So the returned paths are
252      * not absolute but relative (the same paths as are passed to one of the
253      * constructors)
254      */

255     public final String JavaDoc[] getPaths() {
256         return paths;
257     }
258     
259     /** Sets new paths. The paths
260      * parameter is used as a base directory for finding
261      * actions, lookup objects and icon.
262      * @param path folder path on the system file system
263      * @param useHierarchicalPath whether the content of parent folders
264      * up to the root for a given entity (actions, lookup) is to be
265      * taken into account when searching for the objects
266      */

267     public final void setPaths(String JavaDoc path, boolean useHierarchicalPath) {
268         setPaths(useHierarchicalPath ?
269                 computeHierarchicalPaths(path) :
270                 new String JavaDoc[] { path });
271     }
272     
273     /** Sets new paths. The paths
274      * parameter is used as a base directory for finding
275      * actions, lookup objects and icon.
276      * @param paths folders on the system file system
277      */

278     public final void setPaths(String JavaDoc[] paths) {
279         if (iconChangeListener != null) {
280             iconManager.removePropertyChangeListener(iconChangeListener);
281         }
282         
283         // clear cached values for icons and actions
284
iconManager = null;
285         actionManager = null;
286         
287         // lookup update
288
Lookup myLookup = getLookup();
289         if (myLookup instanceof ExtensibleLookup) {
290             ExtensibleLookup el = (ExtensibleLookup)myLookup;
291             el.setNode(this);
292         }
293         
294         // fire
295
Object JavaDoc oldValue = this.paths;
296         this.paths = paths;
297         firePropertyChange("paths", oldValue, paths);
298         
299         fireIconChange();
300         fireOpenedIconChange();
301     }
302     
303     /**
304      * Currently selected name of the icon. Please set the icon name using
305      * method setIconName. If setIconName was not called a defualt icon
306      * will be used instead.
307      */

308     public final String JavaDoc getIconName() {
309         return iconName;
310     }
311     
312     /**
313      * Setter for the name of the currently used icon. Calling this method
314      * will refresh the displayed icon.
315      */

316     public final void setIconName(String JavaDoc name) {
317         Object JavaDoc oldVal = iconName;
318         iconName = name;
319         firePropertyChange("iconName", oldVal, iconName); // NOI18N
320
fireIconChange();
321         fireOpenedIconChange();
322     }
323     
324     /**
325      * Lazy initialization of iconChangeListener.
326      */

327     private IconChangeListener getIconChangeListener() {
328         if (iconChangeListener == null) {
329             iconChangeListener = new IconChangeListener();
330         }
331         return iconChangeListener;
332     }
333     
334     /**
335      * For one folder returns an array containing the folder and
336      * all of its parents. Uses '/' as the folder delimiter.
337      * @return String[] For "a/b/c" returns { "a/b/c", "a/b", "a", "" }
338      */

339     static String JavaDoc[] computeHierarchicalPaths(String JavaDoc path) {
340         if (path == null) {
341             return new String JavaDoc[0];
342         }
343         String JavaDoc tmp = path;
344         ArrayList JavaDoc list = new ArrayList JavaDoc();
345         while (tmp.length() > 0) {
346             list.add(tmp);
347             if (tmp.lastIndexOf('/') >= 0) {
348                 tmp = tmp.substring(0, tmp.lastIndexOf('/'));
349             } else {
350                 tmp = "";
351             }
352         }
353         list.add(tmp); // add also the last ""
354
return (String JavaDoc[])list.toArray(new String JavaDoc[list.size()]);
355     }
356
357     /**
358      * Listener attached to the ExtensibleIcons intstance.
359      */

360     private final class IconChangeListener implements PropertyChangeListener JavaDoc {
361         public void propertyChange(PropertyChangeEvent JavaDoc ev) {
362             fireIconChange();
363             fireOpenedIconChange();
364         }
365     }
366 }
367
Popular Tags