blob: a9d413b73275840e51272431015bafca9be5d67d [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Working with NetBeans Module Suites Using Maven</title>
<link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"/>
<meta name="AUDIENCE" content="NBUSER"/>
<meta name="TYPE" content="ARTICLE"/>
<meta name="EXPIRES" content="N"/>
<meta name="indexed" content="y"/>
<meta name="description" content="A short demonstration of how to use Maven to create and run a NetBeans Platform Module Suite."/>
<!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -->
<!-- Use is subject to license terms.-->
</head>
<body>
<h1>Working with NetBeans Module Suites Using Maven</h1>
<p>This document demonstrates how to create a NetBeans Platform Module Suite from Maven archetypes
and build and install the suite in your installation of the IDE.
In this tutorial you will create a Maven module suite project that contains three NetBeans modules as sub-projects.
The Maven project that contains the sub-projects is a simple POM project that declares how the suite is compiled
and the installation target.
</p>
<p>This document is based on the Ant-based <a href="https://platform.netbeans.org/tutorials/nbm-selection-1.html">NetBeans Selection Management Tutorial</a>
and illustrates some of the differences between using Ant and Maven to develop NetBeans Platform module suites.
After you understand some of the differences, you can easily proceed through other
tutorials on the the <a href="https://netbeans.org/kb/trails/platform.html">NetBeans Platform Learning Trail</a>.</p>
<p class="tips">If you are new to the NetBeans Platform, you might want to watch the
the screencast series <a href="https://platform.netbeans.org/tutorials/nbm-10-top-apis.html">Top 10 NetBeans APIs</a>.</p>
<p><b>Contents</b></p>
<p><img src="../images/articles/69/netbeans-stamp69.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 6.5, 6.7, 6.8" title="Content on this page applies to NetBeans IDE 6.5, 6.7, 6.8"/></p>
<ul class="toc">
<li><a href="#config">Using Maven with the IDE</a>
<ul>
<li><a href="#config1">Configuring Maven Options</a></li>
<li><a href="#config2">Viewing the Maven Repositories</a></li>
</ul></li>
<li><a href="#01">Creating the NetBeans Platform Module Suite</a></li>
<li><a href="#02">Modifying the MyAPI Module</a>
<ul>
<li><a href="#02a">Creating a Class</a></li>
<li><a href="#02b">Specifying the Public Packages</a></li>
</ul>
</li>
<li><a href="#03">Creating the MyViewer Module</a>
<ul>
<li><a href="#03b">Creating the Window Component</a></li>
</ul>
</li>
<li><a href="#04">Creating the MyEditor Module</a>
<ul>
<li><a href="#04b">Adding an Action</a></li>
<li><a href="#04c">Adding the Editor Component</a></li>
</ul>
</li>
<li><a href="#05">Building and Running the Module Suite</a>
<ul>
<li><a href="#05a">Declaring Direct Dependencies</a></li>
<li><a href="#05b">Specifying the Location of the NetBeans Installation</a></li>
<li><a href="#05c">Running the Application</a></li>
</ul>
</li>
<li><a href="#06">Modifying the Lookup Dynamically</a></li>
</ul>
<p><b>To follow this tutorial, you need the software and resources listed in the following table.</b></p>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="http://download.netbeans.org/netbeans/6.9/beta/">NetBeans IDE</a></td>
<td class="tbltd1">version 6.9</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">Java Developer Kit (JDK)</a></td>
<td class="tbltd1">Version 6</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://maven.apache.org/">Maven</a></td>
<td class="tbltd1">Version 2.0.9 or higher</td>
</tr>
</tbody>
</table>
<p><strong class="notes">Note:</strong> You do not need to download a separate version
of the NetBeans Platform to develop applications for the NetBeans Platform.
Typically, you develop the applications and modules in the NetBeans IDE and
then only include the modules that are necessary to run the NetBeans Platform and your application.</p>
<p>Before starting this tutorial you may want to familiarize yourself with
the following documentation.</p>
<ul>
<li><a href="http://wiki.netbeans.org/NetBeansDeveloperFAQ">NetBeans Developer FAQ</a></li>
<li><a href="http://wiki.netbeans.org/MavenBestPractices">Best Practices for Apache Maven in NetBeans 6.x</a></li>
<li><a href="http://www.sonatype.com/books/maven-book/reference/introduction.html">Chapter 1. Introducing Apache Maven</a>
(from <a href="http://www.sonatype.com/books/maven-book/reference/public-book.html">Maven: The Definitive Guide</a>)</li>
<li><a href="https://netbeans.org/kb/docs/java/gui-functionality.html">Introduction to GUI Building</a></li>
</ul>
<!-- =================================================================== -->
<!-- +++++++++++++++ Configuring Maven +++++++++++++++++++++++++++++++++ -->
<h2><a name="config"></a>Using Maven with the IDE</h2>
<p>If this is your first Maven project you will want to familiarize yourself with the Maven configuration settings
and the Maven Repository Browser.</p>
<div class="indent">
<a name="config1"></a>
<h3>Configuring Maven Options</h3>
<p>You can use the Maven tab in the Options window to configure the behavior of Maven in the IDE and to check
that your configuration is correct.</p>
<ol>
<li>Select the Miscellaneous category in the Options window and click the Maven tab.</li>
<li>Specify the location of your local Maven installation (requires 2.0.9 or newer).</li>
<li>Confirm that the location of the local Maven repository is correct.</li>
<li>Click OK.</li>
</ol>
<p>In most cases, if your Maven configuration is typical the information in the Options window should already be correct.</p>
<p class="notes"><strong>Note.</strong> Maven support is activated as part of the Java SE feature set.
If the Maven tab is not available in the Options window, confirm that Java SE is activated by creating a Java application.</p>
<h3><a name="config2"></a>Viewing the Maven Repositories</h3>
<p>The artifacts that are used by Maven to build all your projects are stored in your local Maven repository.
When an artifact is declared as a project dependency, the artifact is downloaded to your local repository
from one of the registered remote repositories if it is not already installed.</p>
<p>The NetBeans repository and several well-known indexed Maven repositories are registered and listed in the Repository Browser window by default.
The NetBeans repository contains most of the public artifacts necessary for you to build your project.
You can use the Maven Repository Browser to view the contents of your local and remote repositories.
You can expand the Local Repository node to see the artifacts that are present locally.
The artifacts listed under the NetBeans repository nodes can be added as project dependencies, but not all of
them are present locally. They are only added to the Local Repository when they are declared as project
dependencies.</p>
<p>To open the Maven Repository Browser:</p>
<ul>
<li>Choose Window &gt; Other &gt; Maven Repository Browser from the main menu.<br/>
<img src="../images/tutorials/maven-quickstart68/maven-nbm-netbeans-repo.png" alt="Screenshot of Maven Repository Browser" title="Screenshot of Maven Repository Browser" class="margin-around b-all" />
</li>
</ul>
</div>
<!-- =================================================================== -->
<!-- +++++++++++++++++++ Creating the Module Suite +++++++++++++++++++++ -->
<h2><a name="01"></a>Creating the NetBeans Platform Module Suite</h2>
<p>In this section you use the New Project wizard to create a
NetBeans Platform Module Suite from a Maven archetype.
The wizard will create a POM project that will contain the module projects.
In the wizard you will also create a module as a sub-project of the suite.
</p>
<ol>
<li>Open the New Project wizard and select Maven NetBeans Module Suite in the Maven category. Click Next.</li>
<li>Type <strong>MavenSelectionSuite</strong> for the Project Name. Click Next.</li>
<li>Select Create Module Project and type <strong>MyAPI</strong> for the module name. Click Finish.</li>
</ol>
<p>When you click Finish, the IDE creates the MavenSelectionSuite project and the sub-project MyAPI NetBeans Module.<br/>
<img src="../images/tutorials/maven-suite/maven-suite-projectswindow.png" alt="Screenshot of Projects window" title="Screenshot of Projects window" class="margin-around b-all" />
</p>
<p>MavenSelectionSuite is a POM project which is a container for sub-projects, in this case NetBeans Module projects.
The POM project does not contain any source files.
The project's POM contains instructions for compiling the suite, and
if you look at the POM for the project you can see that <tt>pom</tt> is specified for the packaging.</p>
<pre class="examplecode"> &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;groupId&gt;com.mycompany&lt;/groupId&gt;
&lt;artifactId&gt;MavenSelectionSuite&lt;/artifactId&gt;
<strong>&lt;packaging&gt;pom&lt;/packaging&gt;</strong>
&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
&lt;name&gt;MavenSelectionSuite Netbeans Module Suite&lt;/name&gt;
...
&lt;properties&gt;
&lt;netbeans.version&gt;RELEASE69&lt;/netbeans.version&gt;
&lt;/properties&gt;
<strong>&lt;modules&gt;
&lt;module&gt;MyAPI&lt;/module&gt;
&lt;/modules&gt;</strong>
&lt;/project&gt;</pre>
<p>The POM also contains a list of the modules that will be included when you build the POM project.
You can see that the MyAPI project is listed as a module.</p>
<p>If you expand the Modules node in the Projects window you will see that the MyAPI project is listed as a module.
In the Files window you can see that the MyAPI project directory is located in the <tt>MavenSelectionSuite</tt> directory.
When you create a new project in the directory of a POM project,
the IDE automatically adds the project to the list of modules in the POM that are included when you build and run the POM project.</p>
<!--<p>The project also contains other XML files containing metadata about the project such as <tt>profiles.xml</tt>.
The <tt>profiles.xml</tt> file specifies the path to the NetBeans installation and is used by the IDE when running the project.
-->
<p class="tips">When you create a NetBeans Platform module suite from the Maven archetype,
you do not specify the target NetBeans Platform installation in the New Project wizard as you do when using Ant.
To set the NetBeans Platform installation you need to modify the <tt>&lt;netbeans.installation&gt;</tt> element
in the POM project's <tt>profiles.xml</tt> file and explicitly specify the path to the NetBeans Platform installation.
For more, see the section <a href="#05b">Specifying the Location of the NetBeans Installation</a> in this tutorial.</p>
<!--see https://netbeans.org/bugzilla/show_bug.cgi?id=185941.-->
<!-- =================================================================== -->
<!-- ++++++++++++++++++ Adding Class to MyAPI Module +++++++++++++++++++ -->
<h2><a name="02"></a>Modifying the MyAPI Module</h2>
<p>You created the MyAPI module when you created the module suite, but now you need to
create a class in the module and expose the class to other modules.</p>
<div class="indent">
<a name="02a"></a>
<h3>Creating a Class in the MyAPI Module</h3>
<p>In this exercise you will create a simple class named <tt>APIObject</tt>.
Each instance of <tt>APIObject</tt> will be unique because the field <tt>index</tt>
is incremented by 1 each time a new instance of <tt>APIObject</tt> is created.</p>
<ol>
<li>Expand the MyAPI project in the Projects window.</li>
<li>Right-click the Source Packages node and choose New &gt; Java Class.</li>
<li>Type <strong>APIObject</strong> as the Class Name and select <tt>com.mycompany.mavenselectionsuite</tt>
from the Package dropdown list. Click Finish.</li>
<li>Modify the class to declare some fields and add the following simple methods.
<pre class="examplecode">
public final class APIObject {
private final Date date = new Date();
private static int count = 0;
private final int index;
public APIObject() {
index = count++;
}
public Date getDate() {
return date;
}
public int getIndex() {
return index;
}
public String toString() {
return index + " - " + date;
}
}</pre>
</li>
<li>Fix your imports and save your changes.</li>
</ol>
<a name="02b"></a>
<h3>Specifying the Public Packages</h3>
<p>In this tutorial you will create additional modules that will need to access the methods in <tt>APIObject</tt>.
In this exercise you will make the contents of the MyAPI module public so that other modules can access the methods.
To declare the <tt>com.mycompany.mavenselectionsuite</tt> package as public you will
modify the <tt>configuration</tt> element of <tt>nbm-maven-plugin</tt> in the POM to specify the packages that are exported as public.
You can make the changes to the POM in the editor or by selecting the packages to make public in the project's Properties window.</p>
<ol>
<li>Right-click the project node and choose Properties to open the Properties window.</li>
<li>Select the <strong>com.mycompany.mavenselectionsuite</strong> package in the <strong>Public Packages</strong> category. Click OK.
<img src="../images/tutorials/maven-suite/maven-suite-publicpackages.png" alt="Screenshot of Public Packages in Properties window" title="Public Packages in Properties window" class="margin-around b-all" />
<p>When you select a package to export, the IDE modifies the <tt>nbm-maven-plugin</tt> element in the POM to specify the package.</p>
<pre class="examplecode">&lt;plugin&gt;
&lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
&lt;artifactId&gt;nbm-maven-plugin&lt;/artifactId&gt;
&lt;extensions&gt;true&lt;/extensions&gt;
&lt;configuration&gt;
&lt;publicPackages&gt;
<strong>&lt;publicPackage&gt;com.mycompany.mavenselectionsuite&lt;/publicPackage&gt;</strong>
&lt;/publicPackages&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;</pre></li>
<li>Right-click the project and choose Build.</li>
</ol>
<p>When you build the project, the <tt>nbm-maven-plugin</tt> will generate a manifest header in the <tt>MANIFEST.MF</tt>
of the JAR that specifies the public packages.</p>
<p class="tips">For more information, see the <a href="http://mojo.codehaus.org/nbm-maven-plugin/manifest-mojo.html#publicPackages">nbm-maven-plugin manifest documentation</a>.</p>
</div>
<!-- =================================================================== -->
<!-- ++++++++++++++++++ Creating the MyViewer Module +++++++++++++++++++ -->
<h2><a name="03"></a>Creating the MyViewer Module</h2>
<p>In this section you will create a new module named MyViewer and add a window component and two text fields.
The component will implement <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/LookupListener.html">LookupListener</a></tt>
to listen for changes to the <a href="http://wiki.netbeans.org/DevFaqLookup">Lookup</a>.</p>
<div class="indent">
<h3><a name="03a"></a>Creating the Module</h3>
<p>In this exercise you will create the MyViewer NetBeans module in the <tt>MavenSelectionSuite</tt> directory.</p>
<ol>
<li>Choose File &gt; New Project from the main menu (Ctrl-Shift-N).</li>
<li>Select Maven NetBeans Module from the Maven category. Click Next.</li>
<li>Type <strong>MyViewer</strong> as the Project Name.</li>
<li>Confirm that the Project Location is the <tt>MavenSelectionSuite</tt> directory. Click Finish.</li>
<li>Right-click the Libraries node in the Projects window and choose Add Dependency.</li>
<li>Select the MyAPI NetBeans Module in the Open Projects tab. Click OK.<br/>
<img src="../images/tutorials/maven-suite/maven-suite-addapi.png" alt="Screenshot of Public Packages in Properties window" title="Public Packages in Properties window" class="margin-around b-all" />
</li>
</ol>
<p>When you click OK, the IDE adds the artifact to the list of dependencies in the POM and displays the
artifact under the Libraries node.</p>
<p>If you look at the POM for the MyViewer module, you see that the
parent project for the module is MavenSelectionSuite, that <tt>nbm</tt> is specified for the <tt>packaging</tt>
and that the <strong>nbm-maven-plugin</strong> will be used to build the project as a NetBeans module.</p>
<pre class="examplecode">
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
<strong>&lt;parent&gt;
&lt;groupId&gt;com.mycompany&lt;/groupId&gt;
&lt;artifactId&gt;MavenSelectionSuite&lt;/artifactId&gt;
&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
&lt;/parent&gt;</strong>
&lt;groupId&gt;com.mycompany&lt;/groupId&gt;
&lt;artifactId&gt;MyViewer&lt;/artifactId&gt;
<strong>&lt;packaging&gt;nbm&lt;/packaging&gt;</strong>
&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
&lt;name&gt;MyViewer NetBeans Module&lt;/name&gt;
</pre>
<a name="03b"></a>
<h3>Creating the Window Component</h3>
<p>In this exercise you will create a Window component and add two text fields.</p>
<ol>
<li>Right-click the MyViewer project and choose New &gt; Window.</li>
<li>Select <strong>navigator</strong> from the dropdown list and select Open on Application Start. Click Next.</li>
<li>Type <strong>MyViewer</strong> as the Class Name Prefix. Click Finish.</li>
<li>Drag two labels from the Palette into the component and change the text of the top label to <tt>"[nothing selected]"</tt>.<br/>
<img src="../images/tutorials/maven-suite/maven-suite-myviewertopcomponent.png" alt="Screenshot of Window component" title="Text Fields in Window component" class="margin-around b-all" />
</li>
<li>Click the Source tab and modify the class signature to implement <tt>LookupListener</tt>.
<pre class="examplecode">public class MyViewerTopComponent extends TopComponent <strong>implements LookupListener</strong> {</pre></li>
<li>Implement the abstract methods by placing the insert cursor in the line and pressing the Alt-Enter keys.</li>
<li>Add the following <tt>private</tt> field <tt>result</tt> and set the initial value to null.
<pre class="examplecode">private Lookup.Result result = null;</pre></li>
<li>Make the following changes to the <tt>componentOpened()</tt>, <tt>componentClosed()</tt> and <tt>resultChanged()</tt> methods.
<pre class="examplecode">
public void componentOpened() {
<strong>result = Utilities.actionsGlobalContext().lookupResult(APIObject.class);
result.addLookupListener(this);</strong>
}
public void componentClosed() {
<strong>result.removeLookupListener (this);
result = null;</strong>
}
public void resultChanged(LookupEvent le) {
<strong>Lookup.Result r = (Lookup.Result) le.getSource();
Collection c = r.allInstances();
if (!c.isEmpty()) {
APIObject o = (APIObject) c.iterator().next();
jLabel1.setText (Integer.toString(o.getIndex()));
jLabel2.setText (o.getDate().toString());
} else {
jLabel1.setText("[no selection]");
jLabel2.setText ("");
}</strong>
}</pre>
<p>By using <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/Utilities.html#actionsGlobalContext%28%29">Utilities.actionsGlobalContext()</a></tt>,
each time that a component is opened the class is able to listen globally for the Lookup object of the component that has the focus.
The Lookup is removed when the component is closed.
The <tt>resultChanged()</tt> method implements the <tt>LookupListener</tt> so that
the JLabels in the form are updated according to the <tt>APIObject</tt> that has the focus.</p>
</li>
<li>Fix the imports and be sure to add <strong><tt>org.openide.util.Utilities</tt></strong>. Save your changes.</li>
</ol>
</div>
<!-- =================================================================== -->
<!-- ++++++++++++++++++ Creating the MyEditor Module +++++++++++++++++++ -->
<h2><a name="04"></a>Creating the MyEditor Module</h2>
<p>In this section you will create a new module called MyEditor.
The module will contain a
<tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a></tt>
that will offer instances of <tt>APIObject</tt> via Lookup.
You will also create an action that will open new instances of the MyEditor component.</p>
<div class="indent">
<a name="04a"></a>
<h3>Creating the Module</h3>
<p>In this exercise you will create a NetBeans module in the <tt>MavenSelectionSuite</tt> directory and add a dependency
on the MyAPI module.</p>
<ol>
<li>Choose File &gt; New Project from the main menu.</li>
<li>Select Maven NetBeans Module from the Maven category. Click Next.</li>
<li>Type <strong>MyEditor</strong> as the Project Name.</li>
<li>Confirm that the Project Location is the <tt>MavenSelectionSuite</tt> directory. Click Finish.</li>
<li>Right-click the project's Libraries node in the Projects window and choose Add Dependency.</li>
<li>Select the MyAPI NetBeans Module in the Open Projects tab. Click OK.</li>
</ol>
<a name="04b"></a>
<h3>Adding an Action</h3>
<p>In this exercise you will create a class to add a menu item to the File menu to open a component named MyEditor.
You will create the component in the next exercise.</p>
<!-- issue: https://netbeans.org/bugzilla/show_bug.cgi?id=186876
In this section you need to create the action first, then the component.
If the component is created first, the New Action wizard will choke on what looks like
a lockedFile exception on the bundle.properties and the entries for the action are not generated in layer.xml.-->
<ol>
<li>Right-click the MyEditor project and choose New &gt; Action to open the New Action dialog.</li>
<li>Select Always Enabled. Click Next.</li>
<li>Keep the defaults in the GUI Registration page. Click Next.</li>
<li>Type <strong>OpenEditorAction</strong> for the Class Name.</li>
<li>Type <strong>Open Editor</strong> for the Display Name. Click Finish.
<p>The IDE opens the <tt>OpenEditorAction</tt> class in the editor and adds the following to the <tt>layer.xml</tt> file.</p>
<pre class="examplecode">
&lt;filesystem&gt;
&lt;folder name="Actions"&gt;
&lt;folder name="Build"&gt;
&lt;file name="com-mycompany-myeditor-OpenEditorAction.instance"&gt;
&lt;attr name="delegate" newvalue="com.mycompany.myeditor.OpenEditorAction"/&gt;
&lt;attr name="displayName" bundlevalue="com.mycompany.myeditor.Bundle#CTL_OpenEditorAction"/&gt;
&lt;attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/&gt;
&lt;attr name="noIconInMenu" boolvalue="false"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;folder name="Menu"&gt;
&lt;folder name="File"&gt;
&lt;file name="com-mycompany-myeditor-OpenEditorAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Build/com-mycompany-myeditor-OpenEditorAction.instance"/&gt;
&lt;attr name="position" intvalue="0"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/filesystem&gt;</pre></li>
<li>Modify the <tt>OpenEditorAction</tt> class to modify the <tt>actionPerformed</tt> method.
<pre class="examplecode">public void actionPerformed(ActionEvent e) {
MyEditor editor = new MyEditor();
editor.open();
editor.requestActive();
}</pre></li>
</ol>
<a name="04c"></a>
<h3>Adding the Editor Component</h3>
<p>In this exercise you will create the component MyEditor that opens in the editor area when invoked by <tt>OpenEditorAction</tt>.
You will not use a Window component template because you will want multiple instances of the
component and the Window component is used for creating singleton components.
Instead, you will use a JPanel Form template and then modify the class to extend <tt>TopComponent</tt>.</p>
<ol>
<li>Right-click the Source Packages and choose New &gt; Other and select JPanel Form in the Swing GUI Forms category. Click Next.</li>
<li>Type <strong>MyEditor</strong> for the Class Name and select the <tt>com.mycompany.myeditor</tt> package. Click Finish.</li>
<li>Drag two Text Fields into the component.</li>
<li>Make the text fields read-only by deselecting the <tt>editable</tt> property for each Text Field.<br/>
<img src="../images/tutorials/maven-suite/maven-suite-editableprop.png" alt="Screenshot of Editable property for labels" title="Editable property for labels" class="margin-around b-all" />
</li>
<li>Click the Source tab and modify the class signature to extend <tt>TopComponent</tt> instead of <tt>javax.swing.JPanel</tt>.
<pre class="examplecode">public class MyEditor extends <strong>TopComponent</strong></pre></li>
<li>Place your insert cursor in the signature and type Alt-Enter to fix the error in the code by
searching the Maven repository and adding a dependency on the <tt>org.openide.windows</tt> artifact. Fix your imports.<br/>
<img src="../images/tutorials/maven-suite/maven-suite-add-topcomponent.png" alt="Screenshot of Editable property for labels" title="Editable property for labels" class="margin-around b-all" />
</li>
<li>Modify the constructor to create a new instance of <tt>APIObject</tt> each time the class is invoked.
<pre class="examplecode">
public MyEditor() {
initComponents();
<strong>APIObject obj = new APIObject();
associateLookup(Lookups.singleton(obj));
jTextField1.setText("APIObject #" + obj.getIndex());
jTextField2.setText("Created: " + obj.getDate());
setDisplayName("MyEditor " + obj.getIndex());</strong>
}</pre>
<p>The <tt>associateLookup(Lookups.singleton(obj));</tt> line in the constructor will create a
Lookup that contains the new instance of <tt>APIObject</tt>.</p></li>
<li>Fix your imports and save the changes.</li>
</ol>
<p>The text fields in the component only display the index value and date from <tt>APIObject</tt>.
This will enable you to see that each MyEditor component is unique and that MyViewer is displaying the
details of the MyEditor component that has the focus.</p>
<p class="notes"><strong>Note.</strong> The errors in <tt>OpenEditorAction</tt> will be resolved after you save your changes to <tt>MyEditor</tt>. </p>
</div>
<!-- =================================================================== -->
<!-- ++++++++++++++++ Building and Running the Module +++++++++++++++++ -->
<h2><a name="05"></a>Building and Running the Module Suite</h2>
<p>At this point you are almost ready to run the suite to see if it builds, installs and behaves correctly.</p>
<div class="indent">
<a name="05a"></a>
<h3>Declaring Direct Dependencies</h3>
<p>Before you can build and run the suite you need to modify one of the dependencies of the MyEditor project.
If you try to build the module suite now, the build output in the Output window will inform you
that the suite cannot compile because the MyEditor module requires that the <tt>org.openide.util-lookup</tt>
artifact be available at runtime.</p>
<p>If you right-click on the project node and choose Show Dependency Graph,
the dependency graph viewer can help you to visualize the module dependencies.</p>
<img src="../images/tutorials/maven-suite/maven-suite-dependency-graph.png" alt="Screenshot of artifact dependency graph" title="artifact dependency graph" class="margin-around b-all" />
<p>You can see that MyEditor does not have a direct dependency on <tt>org.openide.util-lookup</tt>.
The dependency is transitive and the artifact is available to the project at compile time,
but the dependency needs to be direct if the artifact is to be available at runtime.
You need to modify the POM to declare the artifact as a direct dependency.</p>
<p>You can make the artifact a direct dependency by manually editing the POM or by using the popup menu item in the Projects window.</p>
<ol>
<li>Expand the Libraries node of the MyEditor module.</li>
<li>Right-click the <tt>org.openide.util-lookup</tt> artifact and choose Declare as Direct Dependency.
<p>When you choose Declare as Direct Dependency, the IDE modifies the POM to add the artifact as a dependency.</p>
</li>
</ol>
<p class="notes"><strong>Note.</strong> The <tt>org.openide.util-lookup</tt> artifact is already a direct dependency of the MyViewer module.</p>
<a name="05b"></a>
<h3>Specifying the Location of the NetBeans Installation</h3>
<p>By default, no target NetBeans installation is specified when you use the Maven archetype to create a NetBeans Platform module suite.
To install and run the module suite on an installation of the IDE, you need to specify the path
to the installation directory by editing the <tt>profiles.xml</tt> file in the POM project.</p>
<ol>
<li>Expand the Project Files node under the MavenSelectionSuite application and double-click <tt>profiles.xml</tt> to open the file in the editor.</li>
<li>Modify the <tt>&lt;netbeans.installation&gt;</tt> element to specify the path to the target NetBeans platform and save the changes.
<pre class="examplecode">
&lt;profile&gt;
&lt;id&gt;netbeans-ide&lt;/id&gt;
&lt;properties&gt;
&lt;netbeans.installation&gt;/home/me/netbeans-6.9&lt;/netbeans.installation&gt;
&lt;/properties&gt;
&lt;/profile&gt;</pre>
<p class="notes"><strong>Note.</strong> The path needs to specify the directory that contains the <tt>bin</tt> directory containing the runnable file.</p>
<p>For example, on OS X your path might resemble the following.</p>
<pre class="examplecode">&lt;netbeans.installation&gt;/Applications/NetBeans/NetBeans6.9.app/Contents/Resources/NetBeans&lt;/netbeans.installation&gt;</pre>
</li>
</ol>
<a name="05c"></a>
<h3>Running the Application</h3>
<p>Now that the target installation of the IDE is specified, you can use the Run command on the suite project.</p>
<ol>
<li>Right-click MavenSelectionSuite and choose Run.</li>
</ol>
<p>When you choose Run, an instance of the IDE will launch with the module suite installed.</p>
<img src="../images/tutorials/maven-suite/maven-suite-run1.png" alt="Screenshot of the My Viewer and MyEditor windows" title="My Viewer and MyEditor windows" class="margin-around b-all" />
<p>The MyViewer window will open when the application starts and will display the two text labels.
You can now choose Open Editor from the File menu to open a MyEditor component in the editor area.
The MyViewer window will display the details of the MyEditor component that has the focus.</p>
<p>The Run action for the module suite project is by default configured to use the Reactor plugin to
recursively build and package the modules that are specified as part of the suite.
You can open the project's Properties window to view the Maven goals that are mapped to actions in the IDE.
</p>
<img src="../images/tutorials/maven-suite/maven-suite-run-action.png" alt="Screenshot of the My Viewer and MyEditor windows" title="My Viewer and MyEditor windows" class="margin-around b-all" />
<p>In the Actions category in the Properties window you can see the goals that are mapped to the Run action.</p>
</div>
<!-- =================================================================== -->
<!-- ++++++++++++++++ Modifying the Lookup with Button +++++++++++++++++ -->
<h2><a name="06"></a>Modifying the Lookup Dynamically</h2>
<p>Currently, a new <tt>APIObject</tt> is created each time that you open a new MyEditor component.
In this section you will add a button to the MyEditor component that will replace the component's current <tt>APIObject</tt>
with a new one. You will modify the code to use
<tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/InstanceContent.html">InstanceContent</a></tt>
to dynamically handle changes to the content of Lookup.</p>
<ol>
<li>Expand the MyEditor project and open the <tt>MyEditor</tt> form in the Design view of the editor.</li>
<li>Drag a Button onto the form and set the text of the Button to "Replace".</li>
<li>Right-click the Button and choose Events &gt; Action &gt; actionPerformed to create an event
handler method for the button and open the form in the source editor.</li>
<li>Add the following <tt>final</tt> field to the class.
<pre class="examplecode">public class MyEditor extends TopComponent {
<strong>private final InstanceContent content = new InstanceContent();</strong></pre>
<p>To take advantage of <tt>InstanceContent</tt> you will need to use
<tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/AbstractLookup.html#AbstractLookup%28org.openide.util.lookup.AbstractLookup.Content%29">AbstractLookup</a></tt>
instead of <tt>Lookup</tt> in the constructor.</p>
</li>
<li>Modify the body of the <tt>jButton1ActionPerformed</tt> event handler method to look like the following by
copying the lines from the class constructor and adding the call to <tt>content.set</tt>.
<pre class="examplecode">private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
<strong>APIObject obj = new APIObject();
jTextField1.setText ("APIObject #" + obj.getIndex());
jTextField2.setText ("Created: " + obj.getDate());
setDisplayName ("MyEditor " + obj.getIndex());
content.set(Collections.singleton (obj), null);</strong>
}</pre>
</li>
<li>Modify the constructor to remove the lines that you copied to the event handler and change
<tt>associateLookup</tt> to use <tt>AbstractLookup</tt> and add <tt>jButton1ActionPerformed(null);</tt>.
The constructor should now look like the following.
<pre class="examplecode">public MyEditor() {
initComponents();
<strong>associateLookup(new AbstractLookup(content));
jButton1ActionPerformed(null);</strong>
}</pre>
<p>You added <tt>jButton1ActionPerformed(null);</tt> to the constructor to ensure that the component
is initialized when created.</p></li>
<li>Fix your imports and save your changes.</li>
</ol>
<p>When you run the module suite project again, you will see the new button in each MyEditor component.
When you click the button, the index number in the text fields will increase.
The label in the MyViewer window will also update to correspond to the new value.</p>
<p>This tutorial demonstrated how to create and run a NetBeans Platform Module Suite that you create from a Maven Archetype.
You saw how module suites are structured and how you configure a modules POM to specify the public packages.
You also learned how to modify the parent POM project to specify the target NetBeans installation so that
the Run command in the IDE will install the suite and launch a new instance of the Platform.
For more examples on how to build NetBeans Platform applications and modules,
see the tutorials listed in the <a href="https://netbeans.org/kb/trails/platform.html">NetBeans Platform Learning Trail</a>.</p>
<!-- ======================================================================================== -->
<div class="feedback-box"><a name="feedback"></a>
<a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback:%20NetBeans%20NetBeans%20Module%20Suites%20Using%20Maven">
Send Us Your Feedback</a></div>
<p>&nbsp;</p>
<!-- ======================================================================================== -->
<h2><a name="nextsteps"></a>See Also</h2>
<p>For more information about creating and developing on the NetBeans Platform, see the following resources.</p>
<ul>
<li><a href="https://netbeans.org/kb/trails/platform.html">NetBeans Platform Learning Trail</a></li>
<li><a href="http://wiki.netbeans.org/NetBeansDeveloperFAQ">NetBeans Developer FAQ</a></li>
<li><a href="http://bits.netbeans.org/dev/javadoc/">NetBeans API Javadoc</a></li>
</ul>
<p>If you have any questions about the NetBeans Platform, feel free
to write to the mailing list, dev@platform.netbeans.org, or view the
<a href="https://netbeans.org/projects/platform/lists/dev/archive">NetBeans Platform mailing list archive</a>.</p>
<!-- ======================================================================================== -->
</body>
</html>