1 19 20 package org.netbeans.spi.java.project.support.ui; 21 22 import java.awt.Image ; 23 import java.beans.PropertyChangeEvent ; 24 import java.beans.PropertyChangeListener ; 25 import java.util.ArrayList ; 26 import java.util.Collections ; 27 import java.util.List ; 28 import java.util.StringTokenizer ; 29 import javax.swing.Icon ; 30 import javax.swing.event.ChangeEvent ; 31 import javax.swing.event.ChangeListener ; 32 import javax.swing.event.EventListenerList ; 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 54 59 final class TreeRootNode extends FilterNode implements PropertyChangeListener { 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 )); 78 this.g = g; 79 g.addPropertyChangeListener(WeakListeners.propertyChange(this, g)); 80 } 81 82 83 private Image computeIcon(boolean opened, int type) { 84 Icon icon = g.getIcon(opened); 85 if (icon == null) { 86 Image 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 getIcon(int type) { 94 return computeIcon(false, type); 95 } 96 97 public Image getOpenedIcon(int type) { 98 return computeIcon(true, type); 99 } 100 101 public String getName() { 102 return g.getName(); 103 } 104 105 public String 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 ev) { 122 fireNameChange(null, null); 124 fireDisplayNameChange(null, null); 125 fireIconChange(); 126 fireOpenedIconChange(); 127 } 128 129 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 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) ) { 149 FileObject folder = fo.isFolder() ? fo : fo.getParent(); 150 String relPath = FileUtil.getRelativePath(groupRoot, folder); 151 List <String > path = new ArrayList <String >(); 152 StringTokenizer strtok = new StringTokenizer (relPath, "/"); while (strtok.hasMoreTokens()) { 154 String 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 , PropertyChangeListener , ChangeableDataFilter { 181 182 private static final long serialVersionUID = 1L; 184 private final EventListenerList ell = new EventListenerList (); 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 e) { 199 fireChange(); 200 } 201 202 public void propertyChange(PropertyChangeEvent e) { 203 if (SourceGroup.PROP_CONTAINERSHIP.equals(e.getPropertyName())) { 204 fireChange(); 205 } 206 } 207 208 private void fireChange() { 209 Object [] listeners = ell.getListenerList(); 210 ChangeEvent event = null; 211 for (int i = listeners.length - 2; i >= 0; i -= 2) { 212 if (listeners[i] == ChangeListener .class) { 213 if (event == null) { 214 event = new ChangeEvent (this); 215 } 216 ((ChangeListener ) listeners[i+1]).stateChanged(event); 217 } 218 } 219 } 220 221 public void addChangeListener(ChangeListener listener) { 222 ell.add(ChangeListener .class, listener); 223 } 224 225 public void removeChangeListener(ChangeListener listener) { 226 ell.remove(ChangeListener .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 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 252 public void setName (final String 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 |