1 19 20 package org.netbeans.spi.java.project.support.ui; 21 22 import java.awt.Component ; 23 import java.awt.Image ; 24 import java.beans.PropertyChangeEvent ; 25 import java.beans.PropertyChangeListener ; 26 import java.util.ArrayList ; 27 import java.util.Collection ; 28 import java.util.IdentityHashMap ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.SortedSet ; 32 import java.util.TreeSet ; 33 import javax.swing.ComboBoxModel ; 34 import javax.swing.DefaultComboBoxModel ; 35 import javax.swing.Icon ; 36 import javax.swing.ImageIcon ; 37 import javax.swing.JLabel ; 38 import javax.swing.JList ; 39 import javax.swing.ListCellRenderer ; 40 import javax.swing.plaf.UIResource ; 41 import org.netbeans.api.progress.ProgressHandle; 42 import org.netbeans.api.progress.ProgressHandleFactory; 43 import org.netbeans.api.project.SourceGroup; 44 import org.netbeans.api.queries.VisibilityQuery; 45 import org.netbeans.modules.java.project.PackageDisplayUtils; 46 import org.netbeans.modules.java.project.JavaProjectSettings; 47 import org.openide.filesystems.FileObject; 48 import org.openide.filesystems.FileUtil; 49 import org.openide.nodes.AbstractNode; 50 import org.openide.nodes.FilterNode; 51 import org.openide.nodes.Node; 52 import org.openide.util.NbBundle; 53 import org.openide.util.WeakListeners; 54 55 60 public class PackageView { 61 62 private PackageView() {} 63 64 76 public static Node createPackageView( SourceGroup group ) { 77 return new RootNode (group); 78 } 79 80 88 public static Node findPath(Node rootNode, Object object) { 89 90 PackageRootNode.PathFinder pf = rootNode.getLookup().lookup(PackageRootNode.PathFinder.class); 91 92 if ( pf != null ) { 93 return pf.findPath( rootNode, object ); 94 } else { 95 TreeRootNode.PathFinder pf2 = rootNode.getLookup().lookup(TreeRootNode.PathFinder.class); 96 if (pf2 != null) { 97 return pf2.findPath(rootNode, object); 98 } else { 99 return null; 100 } 101 } 102 } 103 104 116 117 public static ComboBoxModel createListView(SourceGroup group) { 118 SortedSet <PackageItem> data = new TreeSet <PackageItem>(); 119 findNonExcludedPackages(null, data, group.getRootFolder(), group, false); 120 return new DefaultComboBoxModel (data.toArray(new PackageItem[data.size()])); 121 } 122 123 131 static void findNonExcludedPackages(PackageViewChildren children, Collection <PackageItem> target, FileObject fo, SourceGroup group, boolean showProgress) { 132 if (showProgress) { 133 ProgressHandle progress = ProgressHandleFactory.createHandle(NbBundle.getMessage(PackageView.class, "PackageView.find_packages_progress", FileUtil.getFileDisplayName(fo))); 134 progress.start(1000); 135 findNonExcludedPackages(children, target, fo, group, progress, 0, 1000); 136 progress.finish(); 137 } else { 138 findNonExcludedPackages(children, target, fo, group, null, 0, 0); 139 } 140 } 141 142 private static void findNonExcludedPackages(PackageViewChildren children, Collection <PackageItem> target, FileObject fo, SourceGroup group, ProgressHandle progress, int start, int end) { 143 144 assert fo.isFolder() : "Package view only accepts folders"; 146 if (progress != null) { 147 String path = FileUtil.getRelativePath(children.getRoot(), fo); 148 assert path != null : fo + " in " + children.getRoot(); 149 progress.progress(path.replace('/', '.'), start); 150 } 151 152 if ( !VisibilityQuery.getDefault().isVisible( fo ) ) { 153 return; } 155 156 boolean hasSubfolders = false; 157 boolean hasFiles = false; 158 List <FileObject> folders = new ArrayList <FileObject>(); 159 for (FileObject kid : fo.getChildren()) { 160 if (VisibilityQuery.getDefault().isVisible(kid) && group.contains(kid)) { 162 if (kid.isFolder()) { 163 folders.add(kid); 164 hasSubfolders = true; 165 } 166 else { 167 hasFiles = true; 168 } 169 } 170 } 171 if (hasFiles || !hasSubfolders) { 172 if (target != null) { 173 target.add( new PackageItem(group, fo, !hasFiles ) ); 174 } 175 else { 176 children.add( fo, !hasFiles ); 177 } 178 } 179 if (!folders.isEmpty()) { 180 int diff = (end - start) / folders.size(); 181 int c = 0; 182 for (FileObject kid : folders) { 183 findNonExcludedPackages(children, target, kid, group, progress, start + c * diff, start + (c + 1) * diff); 186 c++; 187 } 188 } 189 } 190 191 208 209 216 public static ListCellRenderer listRenderer() { 217 return new PackageListCellRenderer(); 218 } 219 220 225 private static final class RootNode extends FilterNode implements PropertyChangeListener { 226 227 private SourceGroup sourceGroup; 228 229 private RootNode (SourceGroup group) { 230 super(getOriginalNode(group)); 231 this.sourceGroup = group; 232 JavaProjectSettings.addPropertyChangeListener(WeakListeners.propertyChange(this, JavaProjectSettings.class)); 233 group.addPropertyChangeListener(WeakListeners.propertyChange(this, group)); 234 } 235 236 public void propertyChange (PropertyChangeEvent event) { 237 String prop = event.getPropertyName(); 238 if (JavaProjectSettings.PROP_PACKAGE_VIEW_TYPE.equals(prop) || SourceGroup.PROP_CONTAINERSHIP.equals(prop)) { 239 changeOriginal(getOriginalNode(sourceGroup), true); 240 } 241 } 242 243 private static Node getOriginalNode(SourceGroup group) { 244 FileObject root = group.getRootFolder(); 245 if ( root == null || !root.isValid()) { 248 return new AbstractNode (Children.LEAF); 249 } 250 switch (JavaProjectSettings.getPackageViewType()) { 251 case JavaProjectSettings.TYPE_PACKAGE_VIEW: 252 return new PackageRootNode(group); 253 case JavaProjectSettings.TYPE_TREE: 254 return new TreeRootNode(group); 255 default: 256 assert false : "Unknown PackageView Type"; return new PackageRootNode(group); 258 } 259 } 260 } 261 262 265 static final class PackageItem implements Comparable <PackageItem> { 266 267 private static Map <Image ,Icon > image2icon = new IdentityHashMap <Image ,Icon >(); 268 269 private final boolean empty; 270 private final FileObject pkg; 271 private final String pkgname; 272 private Icon icon; 273 274 public PackageItem(SourceGroup group, FileObject pkg, boolean empty) { 275 this.pkg = pkg; 276 this.empty = empty; 277 String path = FileUtil.getRelativePath(group.getRootFolder(), pkg); 278 assert path != null : "No " + pkg + " in " + group; 279 pkgname = path.replace('/', '.'); 280 } 281 282 public String toString() { 283 return pkgname; 284 } 285 286 public String getLabel() { 287 return PackageDisplayUtils.getDisplayLabel(pkgname); 288 } 289 290 public Icon getIcon() { 291 if ( icon == null ) { 292 Image image = PackageDisplayUtils.getIcon(pkg, pkgname, empty); 293 icon = image2icon.get(image); 294 if ( icon == null ) { 295 icon = new ImageIcon ( image ); 296 image2icon.put( image, icon ); 297 } 298 } 299 return icon; 300 } 301 302 public int compareTo(PackageItem p) { 303 return pkgname.compareTo(p.pkgname); 304 } 305 306 } 307 308 311 private static final class PackageListCellRenderer extends JLabel implements ListCellRenderer , UIResource { 312 313 public PackageListCellRenderer() { 314 setOpaque(true); 315 } 316 317 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 318 setName("ComboBox.listRenderer"); 321 if (value instanceof PackageItem) { 322 PackageItem pkgitem = (PackageItem) value; 323 setText(pkgitem.getLabel()); 324 setIcon(pkgitem.getIcon()); 325 } else { 326 String pkgitem = (String ) value; 328 setText(pkgitem); 329 setIcon(null); 330 } 331 332 if ( isSelected ) { 333 setBackground(list.getSelectionBackground()); 334 setForeground(list.getSelectionForeground()); 335 } 336 else { 337 setBackground(list.getBackground()); 338 setForeground(list.getForeground()); 339 } 340 341 return this; 342 } 343 344 public String getName() { 346 String name = super.getName(); 347 return name == null ? "ComboBox.renderer" : name; } 349 350 } 351 352 353 } 354 | Popular Tags |