blob: 3248fe9a3b2ad41181d08193f8a0c762cfeb28a5 [file] [log] [blame]
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
= NetBeans Project Type Extension Module Tutorial
:jbake-type: platform_tutorial
:jbake-tags: tutorials
:jbake-status: published
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:icons: font
:experimental:
:description: NetBeans Project Type Extension Module Tutorial - Apache NetBeans
:keywords: Apache NetBeans Platform, Platform Tutorials, NetBeans Project Type Extension Module Tutorial
This tutorial demonstrates how to extend an existing project type.
NOTE: This document uses the NetBeans IDE 6.5 Release. If you are using an earlier version, see link:60/nbm-projectextension.html[the 6.0/6.1 version of this document].
You will also make use of this icon, which you can right-click here and download:
image::images/projectextensions_webPagesBadge.gif[]
Optionally, for troubleshooting purposes, you can link:http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=14034[download the completed sample] and inspect the sources.
== Introduction to Project Extensions
New APIs since NetBeans IDE 6.0 enable you to add new nodes to an existing project type's logical view, additions to an existing project type's lookup, and new panels to an existing project type's Project Properties dialog box. To illustrate these extensions, we extend the web application project type, by adding a new 'Important Files' node, exposing the content of the project's 'nbproject' folder, as shown here:
image::images/projectextensions_result-65.png[]
Prior to NetBeans IDE 6.0, no APIs existed for extending existing project types. Instead, you would need to create new project types from scratch. From 6.0 onwards, you are recommended to extend existing project types rather than create new ones. This will keep the number of project types to a minimum and avoid a large number of project types with very small differences. However, it is still possible to create project types from scratch, as before.
== Creating the Module Project
We begin by working through the New Module Project wizard. At the end of it, we will have a basic source structure, with some default files, that every NetBeans module requires.
[start=1]
1. Choose File > New Project (Ctrl+Shift+N). Under Categories, select NetBeans Modules. Under Projects, select Module. Click Next.
[start=2]
1. In the Name and Location panel, type ``ImportantWebFiles`` in the Project Name field. Change the Project Location to any directory on your computer. Leave the Standalone Module option and Set as Main Project checkbox selected. Click Next.
[start=3]
1. In the Basic Module Configuration panel, type ``org.netbeans.modules.importantwebfiles`` in Code Name Base.
[start=4]
1. Select "Generate XML Layer". Leave the locations of both the localizing bundle and the XML layer file so that they will be stored in a package with the name ``org/netbeans/modules/importantwebfiles`` . Click Finish.
The IDE creates the ``ImportantWebFiles`` project. The project contains all of your sources and project metadata, such as the project's Ant build script. The project opens in the IDE. You can view its logical structure in the Projects window (Ctrl-1) and its file structure in the Files window (Ctrl-2).
== Setting Dependencies
We will need to make use of several NetBeans APIs. In this step, we select the modules that provide the NetBeans APIs that we will need.
[start=1]
1. Right-click the project node and choose Properties. The Project Properties dialog box opens.
[start=2]
1. In the Libraries panel, add dependencies on the following modules:
* Datasystems API
* File System API
* Nodes API
* Project API
* Project UI API
* Utilities API
* Web APIs
The Libraries panel should now look as follows:
image::images/projectextensions_add-deps.png[]
[start=3]
1. Click OK.
== Registering the New Extensions
Before we create the classes that implement the APIs that we registered above, we will add entries to the layer file.
[start=1]
1. Expand the Important Files node and double-click the XML Layer node to open the file in the editor.
[start=2]
1. Add the following entries to the layer file:
[source,xml]
----
<folder name="Projects">
<folder name="org-netbeans-modules-web-project">
<folder name="Lookup">
<file name="org.netbeans.modules.importantwebfiles.LookupProviderImpl.instance"/>
</folder>
<folder name="Nodes">
<file name="org.netbeans.modules.importantwebfiles.ImportantFilesNodeFactoryImpl.instance">
<attr name="position" intvalue="1200"/>
</file>
</folder>
</folder>
</folder>
----
[start=3]
1. In the Important Files node, expand the XML Layer node, then expand the 'this layer in context' node. Scroll to the Projects node and notice that the changes you made above are highlighted, to visually distinguish your extensions from those that were there already:
image::images/projectextensions_layer-visualized.png[]
NOTE: The visual view above is very useful in showing you the names of the project types, so that you can correctly register extensions to them in the layer file.
== Extending the Lookup
We start by implementing the ``LookupProviderImpl`` class, which we registered in the layer file in the previous section.
[start=1]
1. Create a Java class called ``LookupProviderImpl`` .
[start=2]
1. Change the default code to the following:
[source,java]
----
public class LookupProviderImpl implements LookupProvider {
public Lookup createAdditionalLookup(Lookup lookup) {
Project prj = lookup.lookup(Project.class);
*//If there is a web module provider in the
//project's lookup, add a new lookup item to
//the lookup, which we will look for to determine
//whether a node should be created:*
WebModuleProvider wmp = lookup.lookup(WebModuleProvider.class);
if (wmp != null) {
return Lookups.fixed(new MyCoolLookupItem(prj));
}
*//If there is no web module in the lookup,
//we do not add a new item to our lookup,
//so that later a node will not be created:*
return Lookups.fixed();
}
}
----
[start=3]
1. Create a new Java class called ``MyCoolLookupItem`` .
[start=4]
1. Change the default code to the following:
[source,java]
----
public class MyCoolLookupItem {
public MyCoolLookupItem(Project prj) {
}
}
----
== Extending the Logical View
We start by implementing the ``LookupProviderImpl`` class, which we registered in the layer file in the previous section.
[start=1]
1. Create a Java class called ``ImportantFilesNodeFactoryImpl`` .
[start=2]
1. Change the default code to the following:
[source,java]
----
public class ImportantFilesNodeFactoryImpl implements link:https://bits.netbeans.org/dev/javadoc/org-netbeans-modules-projectuiapi/org/netbeans/spi/project/ui/support/NodeFactory.html[NodeFactory] {
Project proj;
public link:https://bits.netbeans.org/dev/javadoc/org-netbeans-modules-projectuiapi/org/netbeans/spi/project/ui/support/NodeList.html[NodeList] createNodes(Project project) {
this.proj = project;
*//If there is no 'nbproject' folder,
//return an empty list of nodes:*
if (proj.getProjectDirectory().getFileObject("nbproject") == null) {
return NodeFactorySupport.fixedNodeList();
}
*//If our item is in the project's lookup,
//return a new node in the node list:*
MyCoolLookupItem item = project.getLookup().lookup(MyCoolLookupItem.class);
if (item != null) {
try {
ImportantFilesNode nd = new ImportantFilesNode(proj);
return NodeFactorySupport.fixedNodeList(nd);
} catch (DataObjectNotFoundException ex) {
Exceptions.printStackTrace(ex);
}
}
*//If our item isn't in the lookup,
//then return an empty list of nodes:*
return NodeFactorySupport.fixedNodeList();
}
}
----
[start=3]
1. Create a new Java class called ``ImportantFilesNode`` .
[start=4]
1. Change the default code to the following:
[source,java]
----
public class ImportantFilesNode extends link:https://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/FilterNode.html[FilterNode] {
private static Image smallImage =
ImageUtilities.loadImage("/org/netbeans/modules/importantwebfiles/webPagesBadge.gif"); // NOI18N
public ImportantFilesNode(Project proj) throws DataObjectNotFoundException {
super(DataObject.find(proj.getProjectDirectory().getFileObject("nbproject")).getNodeDelegate());
}
public String getDisplayName() {
return "Important Files";
}
*//Next, we add icons, for the default state, which is
//closed, and the opened state; we will make them the same.
//Icons in project logical views are
//based on combinations--you must combine the node's own icon
//with a distinguishing badge that is merged with it. Here we
//first obtain the icon from a data folder, then we add our
//badge to it by merging it via a NetBeans API utility method:*
public Image getIcon(int type) {
DataFolder root = DataFolder.findFolder(Repository.getDefault().getDefaultFileSystem().getRoot());
Image original = root.getNodeDelegate().getIcon(type);
return ImageUtilities.mergeImages(original, smallImage, 7, 7);
}
public Image getOpenedIcon(int type) {
DataFolder root = DataFolder.findFolder(Repository.getDefault().getDefaultFileSystem().getRoot());
Image original = root.getNodeDelegate().getIcon(type);
return ImageUtilities.mergeImages(original, smallImage, 7, 7);
}
}
----
[start=5]
1. Right-click this icon and save it in the main package of your module:
image::images/projectextensions_webPagesBadge.gif[]
== Installing the Module
Finally, we install the module and make use of the result.
[start=1]
1. Check that the module looks as follows in the Projects window:
image::images/projectextensions_proj-window-65.png[]
[start=2]
1. Right-click the module project and install it.
[start=3]
1. Create a new web application, or open an existing one, and notice that it has an Important Files node, containing the files from the 'nbproject' folder:
image::images/projectextensions_result-65.png[]
link:http://netbeans.apache.org/community/mailing-lists.html[Send Us Your Feedback]
== Next Steps
For more information about creating and developing NetBeans modules, see the following resources:
* link:https://netbeans.apache.org/kb/docs/platform.html[Other Related Tutorials]
* link:https://bits.netbeans.org/dev/javadoc/[NetBeans API Javadoc]