KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > spi > java > project > support > ui > TreeRootNode


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 Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.spi.java.project.support.ui;
21
22 import java.awt.Image JavaDoc;
23 import java.beans.PropertyChangeEvent JavaDoc;
24 import java.beans.PropertyChangeListener JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29 import javax.swing.Icon JavaDoc;
30 import javax.swing.event.ChangeEvent JavaDoc;
31 import javax.swing.event.ChangeListener JavaDoc;
32 import javax.swing.event.EventListenerList JavaDoc;
33 import org.netbeans.api.project.SourceGroup;
34 import org.netbeans.api.queries.VisibilityQuery;
35 import org.openide.DialogDisplayer;
36 import org.openide.NotifyDescriptor;
37 import org.openide.filesystems.FileObject;
38 import org.openide.filesystems.FileUtil;
39 import org.openide.loaders.ChangeableDataFilter;
40 import org.openide.loaders.DataFolder;
41 import org.openide.loaders.DataObject;
42 import org.openide.nodes.FilterNode;
43 import org.openide.nodes.Node;
44 import org.openide.nodes.NodeNotFoundException;
45 import org.openide.nodes.NodeOp;
46 import org.openide.util.NbBundle;
47 import org.openide.util.Utilities;
48 import org.openide.util.WeakListeners;
49 import org.openide.util.lookup.Lookups;
50 import org.openide.util.lookup.ProxyLookup;
51
52 // XXX need unit test
53

54 /**
55  * Displays a package root in a tree.
56  * @see "#42151"
57  * @author Jesse Glick
58  */

59 final class TreeRootNode extends FilterNode implements PropertyChangeListener JavaDoc {
60     
61     private final SourceGroup g;
62     
63     public TreeRootNode(SourceGroup g) {
64         this(DataFolder.findFolder(g.getRootFolder()), g);
65     }
66     
67     private TreeRootNode(DataFolder folder, SourceGroup g) {
68         this(new FilterNode(folder.getNodeDelegate(), folder.createNodeChildren(new VisibilityQueryDataFilter(g))), g);
69     }
70     
71     private TreeRootNode (Node originalNode, SourceGroup g) {
72         super(originalNode, new PackageFilterChildren(originalNode),
73             new ProxyLookup(
74                 originalNode.getLookup(),
75                 Lookups.singleton(new PathFinder(g))
76                 // no need for explicit search info
77
));
78         this.g = g;
79         g.addPropertyChangeListener(WeakListeners.propertyChange(this, g));
80     }
81
82     /** Copied from PackageRootNode with modifications. */
83     private Image JavaDoc computeIcon(boolean opened, int type) {
84         Icon JavaDoc icon = g.getIcon(opened);
85         if (icon == null) {
86             Image JavaDoc image = opened ? super.getOpenedIcon(type) : super.getIcon(type);
87             return Utilities.mergeImages(image, PackageRootNode.PACKAGE_BADGE, 7, 7);
88         } else {
89             return Utilities.icon2Image(icon);
90         }
91     }
92     
93     public Image JavaDoc getIcon(int type) {
94         return computeIcon(false, type);
95     }
96
97     public Image JavaDoc getOpenedIcon(int type) {
98         return computeIcon(true, type);
99     }
100
101     public String JavaDoc getName() {
102         return g.getName();
103     }
104
105     public String JavaDoc getDisplayName() {
106         return g.getDisplayName();
107     }
108
109     public boolean canRename() {
110         return false;
111     }
112
113     public boolean canDestroy() {
114         return false;
115     }
116
117     public boolean canCut() {
118         return false;
119     }
120
121     public void propertyChange(PropertyChangeEvent JavaDoc ev) {
122         // XXX handle SourceGroup.rootFolder change too
123
fireNameChange(null, null);
124         fireDisplayNameChange(null, null);
125         fireIconChange();
126         fireOpenedIconChange();
127     }
128
129     /** Copied from PhysicalView and PackageRootNode. */
130     public static final class PathFinder {
131         
132         private final SourceGroup g;
133         
134         PathFinder(SourceGroup g) {
135             this.g = g;
136         }
137         
138         public Node findPath(Node rootNode, Object JavaDoc o) {
139             FileObject fo;
140             if (o instanceof FileObject) {
141                 fo = (FileObject) o;
142             } else if (o instanceof DataObject) {
143                 fo = ((DataObject) o).getPrimaryFile();
144             } else {
145                 return null;
146             }
147             FileObject groupRoot = g.getRootFolder();
148             if (FileUtil.isParentOf(groupRoot, fo) /* && group.contains(fo) */) {
149                 FileObject folder = fo.isFolder() ? fo : fo.getParent();
150                 String JavaDoc relPath = FileUtil.getRelativePath(groupRoot, folder);
151                 List JavaDoc<String JavaDoc> path = new ArrayList JavaDoc<String JavaDoc>();
152                 StringTokenizer JavaDoc strtok = new StringTokenizer JavaDoc(relPath, "/"); // NOI18N
153
while (strtok.hasMoreTokens()) {
154                     String JavaDoc token = strtok.nextToken();
155                    path.add(token);
156                 }
157                 try {
158                     Node folderNode = folder.equals(groupRoot) ? rootNode : NodeOp.findPath(rootNode, Collections.enumeration(path));
159                     if (fo.isFolder()) {
160                         return folderNode;
161                     } else {
162                         Node[] childs = folderNode.getChildren().getNodes(true);
163                         for (int i = 0; i < childs.length; i++) {
164                            DataObject dobj = childs[i].getLookup().lookup(DataObject.class);
165                            if (dobj != null && dobj.getPrimaryFile().getNameExt().equals(fo.getNameExt())) {
166                                return childs[i];
167                            }
168                         }
169                     }
170                 } catch (NodeNotFoundException e) {
171                     e.printStackTrace();
172                 }
173             } else if (groupRoot.equals(fo)) {
174                 return rootNode;
175             }
176             return null;
177         }
178     }
179     
180     private static final class VisibilityQueryDataFilter implements ChangeListener JavaDoc, PropertyChangeListener JavaDoc, ChangeableDataFilter {
181         
182         private static final long serialVersionUID = 1L; // in case a DataFolder.ClonedFilterHandle saves me
183

184         private final EventListenerList JavaDoc ell = new EventListenerList JavaDoc();
185         private final SourceGroup g;
186         
187         public VisibilityQueryDataFilter(SourceGroup g) {
188             this.g = g;
189             VisibilityQuery.getDefault().addChangeListener(WeakListeners.change(this, VisibilityQuery.getDefault()));
190             g.addPropertyChangeListener(WeakListeners.propertyChange(this, g));
191         }
192         
193         public boolean acceptDataObject(DataObject obj) {
194             FileObject fo = obj.getPrimaryFile();
195             return g.contains(fo) && VisibilityQuery.getDefault().isVisible(fo);
196         }
197         
198         public void stateChanged(ChangeEvent JavaDoc e) {
199             fireChange();
200         }
201         
202         public void propertyChange(PropertyChangeEvent JavaDoc e) {
203             if (SourceGroup.PROP_CONTAINERSHIP.equals(e.getPropertyName())) {
204                 fireChange();
205             }
206         }
207
208         private void fireChange() {
209             Object JavaDoc[] listeners = ell.getListenerList();
210             ChangeEvent JavaDoc event = null;
211             for (int i = listeners.length - 2; i >= 0; i -= 2) {
212                 if (listeners[i] == ChangeListener JavaDoc.class) {
213                     if (event == null) {
214                         event = new ChangeEvent JavaDoc(this);
215                     }
216                     ((ChangeListener JavaDoc) listeners[i+1]).stateChanged(event);
217                 }
218             }
219         }
220         
221         public void addChangeListener(ChangeListener JavaDoc listener) {
222             ell.add(ChangeListener JavaDoc.class, listener);
223         }
224         
225         public void removeChangeListener(ChangeListener JavaDoc listener) {
226             ell.remove(ChangeListener JavaDoc.class, listener);
227         }
228         
229     }
230     
231     
232     private static final class PackageFilterChildren extends FilterNode.Children {
233         
234         public PackageFilterChildren (final Node originalNode) {
235             super (originalNode);
236         }
237                 
238         @Override JavaDoc
239         protected Node copyNode(final Node originalNode) {
240             DataObject dobj = originalNode.getLookup().lookup(DataObject.class);
241             return (dobj instanceof DataFolder) ? new PackageFilterNode (originalNode) : super.copyNode(originalNode);
242         }
243     }
244     
245     private static final class PackageFilterNode extends FilterNode {
246         
247         public PackageFilterNode (final Node origNode) {
248             super (origNode, new PackageFilterChildren (origNode));
249         }
250         
251         @Override JavaDoc
252         public void setName (final String JavaDoc name) {
253             if (Utilities.isJavaIdentifier (name)) {
254                 super.setName (name);
255             }
256             else {
257                 DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message (
258                     NbBundle.getMessage(TreeRootNode.class,"MSG_InvalidPackageName"), NotifyDescriptor.INFORMATION_MESSAGE));
259             }
260         }
261         
262     }
263     
264 }
265
Popular Tags