Once you begin to understand it, the Netbeans Nodes API is quite elegant, and a useful way to display information in navigator tree structures. One particular feature of the Nodes API is the FilterNode class. Typically used as a Node that proxies a Node referencing a DataObject, the FilterNode provides a mechanism by which to filter the displayed contents of a navigator's tree.
An example scenario for using FilterNode, similar to what I read about in a wiki post, is to hide the project settings directory inside the project Navigator; but display all other files. This is accomplished using the Project UI API, Nodes API, (and a few others).
First, create a project factory and implement its methods.
@org.openide.util.lookup.ServiceProvider(service=ProjectFactory.class) public class MyProjectFactory implements ProjectFactory { public static final String PROJECT_SUBDIR = "mymetadata"; public static final String PROJECT_FILE = "myproject.xml"; public static final String PROJECT_FILE_PATH = PROJECT_SUBDIR + "/" + PROJECT_FILE; public boolean isProject(FileObject projectDirectory) { File dirFile, xmlFile; dirFile = FileUtil.toFile(projectDirectory); if (dirFile == null) return false; // The directory is not valid. xmlFile = new File(new File(dirFile, PROJECT_SUBDIR), PROJECT_FILE); return xmlFile.isFile(); // Does XML file exist? } public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException { return null; } public void saveProject(final Project project) throws IOException, ClassCastException { } }
Second, create a LogicalViewProvider that filters out the project subdirectory. Take special note of the createNodes method of the ProxyChildren inner class. A lot of additional implementation is omitted here to emphasize the inner class that extends FilterNode.Children.
class MyLogicalView implements LogicalViewProvider { private final MyProject project; public MyLogicalView(MyProject project) { this.project = project; } public @Override Node createLogicalView() { try { // Find the project directory. FileObject dir = project.getProjectDirectory(); // Find the data object for the directory. DataFolder dirDF = DataFolder.findFolder(dir); // Create a proxy node. return new ProxyNode(dirDF.getNodeDelegate(), project); } catch (DataObjectNotFoundException e) { Exceptions.printStackTrace(e); return new AbstractNode(Children.LEAF); } } public @Override Node findPath(Node root, Object target) { return null; // Unimplemented. } /** * This the actual visible node displayed * in the project tab for the project. */ public static final class ProxyNode extends FilterNode { protected final MyProject project; public ProxyNode(Node node, MyProject project) throws DataObjectNotFoundException { super(node, new ProxyChildren(node), new ProxyLookup(new Lookup[]{Lookups.singleton(project), node.getLookup()})); this.project = project; } } public static class ProxyChildren extends FilterNode.Children { public ProxyChildren(Node owner) { super(owner); } protected @Override Node[] createNodes (Node key) { List<Node> result = new ArrayList<Node>(); for (Node node : super.createNodes(key)) if (accept(node)) result.add(node); return result.toArray(new Node[0]); } private boolean accept (Node node) { // The project subdirectory is hidden. DataFolder f = node.getLookup().lookup(DataFolder.class); if (f != null) { String name = f.getName(); if (name.equalsIgnoreCase(MyProjectFactory.PROJECT_SUBDIR)) return false; } return true; } } }
| © Copyright Timothy Stotts 2002-2009. All rights reserved. | ^ top of page |