blob: a1dddb8ab8073cf5247821386dabc59a7fabb958 [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>NetBeans Platform Ant Tutorial</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 guide to getting started with EMF on the NetBeans Platform."/>
<!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -->
<!-- Use is subject to license terms.-->
</head>
<body>
<h1>NetBeans Platform Ant Tutorial</h1>
<p>This document shows you how to use Ant and the command line to
set up and deploy NetBeans Platform applications.
</p>
<p>
You will start by setting up a folder and file structure for
deploying a NetBeans Platform application. The structure will
consist of folders, together with Ant scripts and property files.
For example, one of the Ant targets will download the NetBeans Platform, while
another will run it. Next, you will create a new folder and file structure
for adding a new module to the application. Finally, you will add
code that will enable your module to provide new components, such as
a new menu item, to the application.
</p>
<p>Once you have gone through this simple scenario, you should not <i>need</i> to
use NetBeans IDE at all when creating NetBeans Platform applications.
On the other hand, you might still <i>want</i> to use NetBeans IDE, since
it provides many wizards, templates, and other tools for generating
code and visualizing module structures, which are features
that no other IDE currently provides. Simultaneously, the instructions
below provide all the NetBeans-specific information needed for someone to create a plugin
for a different IDE enabling developers to use other IDEs to provide
the folder structures and file contents outlined below.
</p>
<p><b>Contents</b></p>
<ul class="toc">
<li><a href="#rcp">Downloading the NetBeans Platform</a></li>
<li><a href="#application">Setting Up a NetBeans Platform Application</a></li>
<li><a href="#module">Setting Up a NetBeans Module</a></li>
<li><a href="#menu">Adding a Menu Item</a></li>
<li><a href="#window">Adding a Window</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://ant.apache.org/">Ant</a></td>
<td class="tbltd1"></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>
</tbody>
</table>
<p>The tutorial assumes you have set up Ant and that you know how to use it.</p>
<!-- ===================================================================================== -->
<p></p>
<h2><a name="rcp"></a>Downloading the NetBeans Platform</h2>
<p>In this section, you begin to set up a folder structure
for your NetBeans Platform work, focusing on an Ant script
to download the NetBeans Platform.</p>
<ol>
<li><p>Create a new folder with a name of your choosing (here referred to as <code>ABC</code>) and, within it, create a folder
named <code>myapp</code> (or any other name), containing a file named <code>build.xml</code>. At this
point the structure of your application should be as follows:</p>
<p><img style="border: 1px solid" src="../images/tutorials/ant/ant-structure-0.png" alt="structure 1"/></p>
</li>
<li>Read <a href="http://wiki.netbeans.org/AutoUpdateTask">http://wiki.netbeans.org/AutoUpdateTask</a>.</li>
<li><p>Define the content of the <code>build.xml</code> file as follows:</p>
<pre class="examplecode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project name="myapp" basedir="."&gt;
&lt;description&gt;Builds, tests, and runs the project "myapp".&lt;/description&gt;
&lt;!-- change this: --&gt;
&lt;property name="netbeans"
value="/home/geertjan/ABC/nbrcp"/&gt;
&lt;property name="bootstrap.url"
value="http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastStableBuild/artifact/nbbuild/netbeans/harness/tasks.jar"/&gt;
&lt;property name="netbeans.updatecenter.url"
value="http://bits.netbeans.org/netbeans/6.9/community/fcs/uc/catalog.xml.gz"/&gt;
&lt;target name="download-netbeans-rcp"&gt;
&lt;mkdir dir="${netbeans}/harness"/&gt;
&lt;get src="${bootstrap.url}" dest="${netbeans}/harness/tasks.jar" usetimestamp="true" verbose="true"/&gt;
&lt;taskdef name="autoupdate" classname="org.netbeans.nbbuild.AutoUpdate" classpath="${netbeans}/harness/tasks.jar"/&gt;
&lt;autoupdate installdir="${netbeans}" updatecenter="${netbeans.updatecenter.url}"&gt;
&lt;modules includes=".*" clusters="harness[0-9]*"/&gt;
&lt;modules includes=".*" clusters="platform[0-9]*"/&gt;
&lt;/autoupdate&gt;
&lt;/target&gt;
&lt;/project&gt;
</pre>
</li>
<li><p>On the command line, go to the "ABC/myapp" folder and run this:</p>
<pre class="examplecode">ant download-netbeans-rcp</pre>
<p>You now see the NetBeans Platform downloading:</p>
<p><img style="border: 1px solid" src="../images/tutorials/ant/ant-download.png" alt="structure 1"/></p>
<p>In your ABC folder, you now have a folder named "nbrcp", as shown below:</p>
<p><img style="border: 1px solid" src="../images/tutorials/ant/ant-structure-1.png" alt="structure 1"/></p>
<p>Read <code>harness/README</code> for a lot of tips, configuration data, and advice.</p>
<p>The folder "myapp" is where you will create your application,
on top of the NetBeans Platform, which is in the folder "nbrcp".</p>
</li>
</ol>
<p><b>Note:</b> Instead of using the Ant target above, you can simply download the ZIP
files for <code>harness</code> and <code>platform</code>:</p>
<ul>
<li><p>platform: <a href="https://netbeans.org/downloads/start.html?filename=zip/moduleclusters/netbeans-6.9-201006101454-ml-platform.zip&amp;pagelang=" rel="nofollow">http://netbeans.org/downloads/start.html?filename=zip/moduleclusters/netbeans-6.9-201006101454-ml-platform.zip&amp;pagelang=</a></p></li>
<li><p>harness: <a href="https://netbeans.org/downloads/start.html?filename=zip/moduleclusters/netbeans-6.9-201006101454-ml-harness.zip&amp;pagelang=" rel="nofollow">http://netbeans.org/downloads/start.html?filename=zip/moduleclusters/netbeans-6.9-201006101454-ml-harness.zip&amp;pagelang=</a></p></li>
</ul>
<p>Now that you have the NetBeans Platform, you can start creating
an application on top of it.</p>
<!-- ===================================================================================== -->
<p></p>
<h2><a name="application"></a>Setting Up a NetBeans Platform Application</h2>
<p>In this section, you set up a minimal folder and file structure for a new
NetBeans Platform application.</p>
<p>At the end of this section, you will have a source structure
on disk, as follows:</p>
<p><img style="border: 1px solid" src="../images/tutorials/ant/ant-structure.png" alt="structure 1"/></p>
<ol>
<li><p>Within the "myapp" folder, create a folder named "nbproject".
This folder will, from now onwards, be referred to as
the "application project folder", while "myapp" will be referred to
as the "application root folder".</p></li>
<li><p>Within the application project folder, create a file named
<code>build-impl.xml</code>, with the following content.</p>
<pre class="examplecode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project name="myapp-impl" basedir=".." xmlns:sproject="https://netbeans.org/ns/nb-module-suite-project/1"&gt;
&lt;property file="nbproject/platform.properties"/&gt;
&lt;macrodef name="property" uri="https://netbeans.org/ns/nb-module-suite-project/1"&gt;
&lt;attribute name="name"/&gt;
&lt;attribute name="value"/&gt;
&lt;sequential&gt;
&lt;property name="@{name}" value="${@{value}}"/&gt;
&lt;/sequential&gt;
&lt;/macrodef&gt;
&lt;macrodef name="evalprops" uri="https://netbeans.org/ns/nb-module-suite-project/1"&gt;
&lt;attribute name="property"/&gt;
&lt;attribute name="value"/&gt;
&lt;sequential&gt;
&lt;property name="@{property}" value="@{value}"/&gt;
&lt;/sequential&gt;
&lt;/macrodef&gt;
&lt;sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/&gt;
&lt;sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/&gt;
&lt;sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/&gt;
&lt;import file="${harness.dir}/suite.xml"/&gt;
&lt;/project&gt;</pre>
</li>
<li>Import the <code>build-impl.xml</code> file into the <code>build.xml</code> file,
as follows:
<pre class="examplecode">&lt;import file="nbproject/build-impl.xml"/&gt;</pre>
<p>The <code>build-impl.xml</code> file gives you access to the NetBeans Platform
infrastructure, such as its "run" target. You will never need to change
the <code>build-impl.xml</code> file. On the other hand, the <code>build.xml</code> file
is the Ant script where you will customize, where necessary, your application's
build process.</p></li>
<li><p>Within the application project folder, create a file named
<code>platform.properties</code>, with the following content.</p>
<pre class="examplecode">nbplatform.active=default
nbplatform.active.dir=/home/geertjan/ABC/nbrcp
harness.dir=${nbplatform.active.dir}/harness
cluster.path=${nbplatform.active.dir}/platform
disabled.modules=</pre>
<p>As you can see, the <code>platform.properties</code> file
configures your NetBeans Platform application, pointing to
its <code>harness</code> and the <code>platform</code> folders,
as well as a placeholder for the modules you will disable, later
in your development work. Make sure to
change <code>nbplatform.active.dir</code> above to point to
your "nbrcp" folder.</p>
</li>
<li><p>Within the application project folder, create a file named
<code>project.properties</code>, with the following content.</p>
<pre class="examplecode">app.name=myapp
branding.token=${app.name}
modules=</pre>
<p>As you can see, the <code>project.properties</code> file
is focused on the application. In this case, you have added
keys in the file for the name
of the application and the custom modules that the
application will provide.</p>
</li>
<li><p>On the command line, go to the "ABC/myapp" folder and run this:</p>
<pre class="examplecode">ant run</pre>
</li>
</ol>
<p>The NetBeans Platform starts up and you see a main window, with
a menu bar and a tool bar, as shown below:</p>
<p><img src="../images/tutorials/ant/ant-result-0.png" alt="structure 1"/></p>
<p>Try out some of the toolbar buttons
and menu items, to see what the NetBeans Platform provided by default.</p>
<!-- ===================================================================================== -->
<p></p>
<h2><a name="module"></a>Setting Up a NetBeans Module</h2>
<p>In this section, you set up a minimal folder and file structure for a new
NetBeans module in your NetBeans Platform application. In the process,
you also register the module with the application so that, when the application
starts up, it will load the module together with the default NetBeans
Platform modules making
up the application.</p>
<ol>
<li><p>Start by creating some folders:</p>
<ul><li><p>Within the "myapp" folder, create a folder named "mymodule".
This folder will, from now onwards, be referred to as
the "module root folder". </p></li>
<li><p>Within the module root folder,
create a new folder named "nbproject", which will,
from now onwards, be referred to
as the "module project folder".</p></li>
<li><p>Within the module root folder,
create a new folder structure "src/org/demo/mymodule", which will
be the main package.</p></li></ul>
<p>Check that the structure you have created
is now as follows:</p>
<p><img style="border: 1px solid" src="../images/tutorials/ant/ant-structure-2.png" alt="structure 1"/></p>
</li>
<li><p>In the module project folder, create the following:</p>
<ul><li><p>A file named <code>suite.properties</code>, with this content:</p>
<pre class="examplecode">suite.dir=${basedir}/..</pre>
<p>The above points to the "myapp" folder, specifying that
it is the application that owns this module.</p>
</li>
<li><p>A file named <code>project.properties</code>, with this content:</p>
<pre class="examplecode">javac.source=1.6
javac.compilerargs=-Xlint -Xlint:-serial</pre>
</li>
<li><p>A file named <code>project.xml</code>, with this content:</p>
<pre class="examplecode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project xmlns="https://netbeans.org/ns/project/1"&gt;
&lt;type&gt;org.netbeans.modules.apisupport.project&lt;/type&gt;
&lt;configuration&gt;
&lt;data xmlns="https://netbeans.org/ns/nb-module-project/3"&gt;
&lt;code-name-base&gt;org.demo.mymodule&lt;/code-name-base&gt;
&lt;suite-component/&gt;
&lt;module-dependencies&gt;
&lt;/module-dependencies&gt;
&lt;public-packages/&gt;
&lt;/data&gt;
&lt;/configuration&gt;
&lt;/project&gt;</pre>
</li>
<li><p>A file named
<code>build-impl.xml</code>, with this content:</p>
<pre class="examplecode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project name="org.demo.mymodule-impl" basedir=".."&gt;
&lt;property file="nbproject/suite.properties"/&gt;
&lt;property file="${suite.dir}/nbproject/platform.properties"/&gt;
&lt;macrodef name="property" uri="https://netbeans.org/ns/nb-module-project/2"&gt;
&lt;attribute name="name"/&gt;
&lt;attribute name="value"/&gt;
&lt;sequential&gt;
&lt;property name="@{name}" value="${@{value}}"/&gt;
&lt;/sequential&gt;
&lt;/macrodef&gt;
&lt;macrodef name="evalprops" uri="https://netbeans.org/ns/nb-module-project/2"&gt;
&lt;attribute name="property"/&gt;
&lt;attribute name="value"/&gt;
&lt;sequential&gt;
&lt;property name="@{property}" value="@{value}"/&gt;
&lt;/sequential&gt;
&lt;/macrodef&gt;
&lt;nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="https://netbeans.org/ns/nb-module-project/2"/&gt;
&lt;nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="https://netbeans.org/ns/nb-module-project/2"/&gt;
&lt;nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="https://netbeans.org/ns/nb-module-project/2"/&gt;
&lt;import file="${harness.dir}/build.xml"/&gt;
&lt;/project&gt;</pre>
</li>
</ul></li>
<li><p>In the module root folder, that is, within the "mymodule" folder,
create the following:</p>
<ul><li><p>A file named <code>build.xml</code>, with the
following content:</p>
<pre class="examplecode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project name="org.demo.mymodule" default="netbeans" basedir="."&gt;
&lt;description&gt;Builds, tests, and runs the project org.demo.mymodule.&lt;/description&gt;
&lt;import file="nbproject/build-impl.xml"/&gt;
&lt;/project&gt;</pre>
</li>
<li><p>A file named <code>manifest.mf</code>, with the
following content:</p>
<pre class="examplecode">Manifest-Version: 1.0
OpenIDE-Module: org.demo.mymodule
OpenIDE-Module-Specification-Version: 1.0</pre>
</li></ul></li>
<li><p>Check that the "mymodule" structure you have created
is now as follows:</p>
<p><img style="border: 1px solid" src="../images/tutorials/ant/ant-structure-3.png" alt="structure 1"/></p></li>
<li><p>In the application project folder, that is, "myapp/nbproject",
change the "modules" key to the following, to register the
module with the application:</p>
<pre class="examplecode">modules=${project.org.demo.mymodule}
project.org.demo.mymodule=MyModule</pre></li>
<li><p>On the command line, go to the "ABC/myapp" folder and run this:</p>
<pre class="examplecode">ant run</pre>
</li>
<li><p>The application starts up and, since you didn't add any code
to the module, you see no changes in the application.
Nevertheless, looking at the output, you can see that the module loaded successfully:</p>
<p><img style="border: 1px solid" src="../images/tutorials/ant/ant-result-1.png" alt="structure 1"/></p></li>
</ol>
<p>In the next section, you add a new feature to the application.</p>
<!-- ===================================================================================== -->
<p></p>
<h2><a name="menu"></a>Adding a Menu Item</h2>
<p>In this section, you add a menu item to the module you created in the
previous section. All the files
described below are assumed to be created in the main package, which is
<code>org.demo.mymodule</code>.</p>
<ol>
<li><p>Add a new Action class to the module:</p>
<pre class="examplecode">package org.demo.mymodule;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
public final class HelloWorldAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "hello...");
}
}</pre>
</li>
<li><p>Register the new Action class in a new <code>layer.xml</code> file:</p>
<pre class="examplecode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "https://netbeans.org/dtds/filesystem-1_2.dtd"&gt;
&lt;filesystem&gt;
&lt;folder name="Actions"&gt;
&lt;folder name="Window"&gt;
&lt;file name="org-demo-mymodule-HelloWorldAction.instance"&gt;
&lt;attr name="delegate" newvalue="org.demo.mymodule.HelloWorldAction"/&gt;
&lt;attr name="displayName" bundlevalue="org.demo.mymodule.Bundle#CTL_HelloWorldAction"/&gt;
&lt;attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;folder name="Menu"&gt;
&lt;folder name="Window"&gt;
&lt;file name="HelloWorldAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Window/org-demo-mymodule-HelloWorldAction.instance"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/filesystem&gt;</pre>
<p>Above, you're registering the <code><a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/Actions.html#alwaysEnabled%28java.awt.event.ActionListener,%20java.lang.String,%20java.lang.String,%20boolean%29">Actions.alwaysEnabled</a></code>
factory method defined in the UI Utilities API.</p>
</li>
<li><p>Add a <code>Bundle.properties</code> file:</p>
<pre class="examplecode">CTL_HelloWorldAction=Hello World</pre>
</li>
<li><p>Register the <code>layer.xml</code> file and the <code>Bundle.properties</code> file
in the <code>manifest.mf</code> file:</p>
<pre class="examplecode">OpenIDE-Module-Layer: org/demo/mymodule/layer.xml
OpenIDE-Module-Localizing-Bundle: org/demo/mymodule/Bundle.properties</pre>
</li>
<li><p>On the command line, go to the "ABC/myapp" folder and run this:</p>
<pre class="examplecode">ant run</pre>
</li>
<li><p>The application starts up and shows a new menu item under the Window menu:</p>
<p><img src="../images/tutorials/ant/ant-result.png" alt="structure 1"/></p>
</li>
</ol>
<!-- ===================================================================================== -->
<p></p>
<h2><a name="window"></a>Adding a Window</h2>
<p>In this section, you use the NetBeans TopComponent class
to add a window to the module you created previously. All the files
described below are assumed to be created in the main package, which is
<code>org.demo.mymodule</code>.</p>
<ol>
<li><p>Add a new TopComponent class to the module, including
some code for initializing and
persisting the TopComponent:</p>
<pre class="examplecode">package org.demo.mymodule;
import java.awt.BorderLayout;
import java.util.logging.Logger;
import javax.swing.JLabel;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
@ConvertAsProperties(dtd = "-//org.demo.mymodule//HelloTopComponent//EN", autostore = false)
public class HelloTopComponent extends TopComponent {
private static HelloTopComponent instance;
private static final String PREFERRED_ID = "HelloTopComponent";
public HelloTopComponent() {
setName(NbBundle.getMessage(HelloTopComponent.class, "CTL_HelloTopComponent"));
setToolTipText(NbBundle.getMessage(HelloTopComponent.class, "HINT_HelloTopComponent"));
// setIcon(ImageUtilities.loadImage(ICON_PATH, true));
setLayout(new BorderLayout());
add(new JLabel("hello"), BorderLayout.CENTER);
}
public static synchronized HelloTopComponent getDefault() {
if (instance == null) {
instance = new HelloTopComponent();
}
return instance;
}
/**
* Obtain the HelloTopComponent instance. Never call {@link #getDefault} directly!
*/
public static synchronized HelloTopComponent findInstance() {
TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
if (win == null) {
Logger.getLogger(HelloTopComponent.class.getName()).warning(
"Cannot find " + PREFERRED_ID + " component. It will not be "
+ "located properly in the window system.");
return getDefault();
}
if (win instanceof HelloTopComponent) {
return (HelloTopComponent) win;
}
Logger.getLogger(HelloTopComponent.class.getName()).warning(
"There seem to be multiple components with the '" + PREFERRED_ID
+ "' ID. That is a potential source of errors and unexpected behavior.");
return getDefault();
}
@Override
public int getPersistenceType() {
return TopComponent.PERSISTENCE_ALWAYS;
}
void writeProperties(java.util.Properties p) {
// better to version settings since initial version as advocated at
// http://wiki.apidesign.org/wiki/PropertyFiles
p.setProperty("version", "1.0");
// TODO store your settings
}
Object readProperties(java.util.Properties p) {
if (instance == null) {
instance = this;
}
instance.readPropertiesImpl(p);
return instance;
}
private void readPropertiesImpl(java.util.Properties p) {
String version = p.getProperty("version");
// TODO read your settings according to their version
}
@Override
protected String preferredID() {
return PREFERRED_ID;
}
}</pre>
</li>
<li><p>Create a file named <code>HelloTopComponentSettings.xml</code>,
with this content:</p>
<pre class="examplecode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "https://netbeans.org/dtds/sessionsettings-1_0.dtd"&gt;
&lt;settings version="1.0"&gt;
&lt;module name="org.demo.mymodule" spec="1.0"/&gt;
&lt;instanceof class="org.openide.windows.TopComponent"/&gt;
&lt;instanceof class="org.demo.mymodule.HelloTopComponent"/&gt;
&lt;instance class="org.demo.mymodule.HelloTopComponent" method="getDefault"/&gt;
&lt;/settings&gt;</pre>
<p>Read <a href="http://wiki.netbeans.org/DevFaqDotSettingsFiles">http://wiki.netbeans.org/DevFaqDotSettingsFiles</a>
for background on the above file.</p>
</li>
<li><p>Create a file named <code>HelloTopComponentWstcref.xml</code>,
with this content:</p>
<pre class="examplecode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "https://netbeans.org/dtds/tc-ref2_0.dtd"&gt;
&lt;tc-ref version="2.0" &gt;
&lt;module name="org.demo.mymodule" spec="1.0"/&gt;
&lt;tc-id id="HelloTopComponent"/&gt;
&lt;state opened="true"/&gt;
&lt;/tc-ref&gt;</pre>
</li>
<li><p>Register the new TopComponent class in the <code>layer.xml</code> file
created previously, within the <code>filesystem/Windows2</code> folder:</p>
<pre class="examplecode">&lt;folder name="Windows2"&gt;
&lt;folder name="Components"&gt;
&lt;file name="HelloTopComponent.settings" url="HelloTopComponentSettings.xml"/&gt;
&lt;/folder&gt;
&lt;folder name="Modes"&gt;
&lt;folder name="editor"&gt;
&lt;file name="HelloTopComponent.wstcref" url="HelloTopComponentWstcref.xml"/&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/folder&gt;</pre>
</li>
<li><p>Register a menu item for opening your new TopComponent class.
The Action for the menu item will not exist in your own code,
since it already exists in the API of the TopComponent class.
You simply need to refer to that API in your Action definition
in the <code>layer.xml</code> file, while referring to that
Action from the Menu folder:</p>
<pre class="examplecode">&lt;folder name="Actions"&gt;
&lt;folder name="Window"&gt;
&lt;file name="org-demo-mymodule-HelloAction.instance"&gt;
&lt;attr name="component" methodvalue="org.demo.mymodule.HelloTopComponent.findInstance"/&gt;
&lt;attr name="displayName" bundlevalue="org.demo.mymodule.Bundle#CTL_HelloAction"/&gt;
&lt;attr name="instanceCreate" methodvalue="org.openide.windows.TopComponent.openAction"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;folder name="Menu"&gt;
&lt;folder name="Window"&gt;
&lt;file name="HelloAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Window/org-demo-mymodule-HelloAction.instance"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;</pre>
<p>Above, you're registering the <code><a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html#openAction%28org.openide.windows.TopComponent,%20java.lang.String,%20java.lang.String,%20boolean%29">TopComponent.openAction</a></code>
factory method defined in the Window System API.</p>
</li>
<li><p>Add the following to the <code>Bundle.properties</code> file:</p>
<pre class="examplecode">CTL_HelloAction=Hello
CTL_HelloTopComponent=Hello Window</pre>
</li>
<li><p>In the module project folder, create a file named <code>project.xml</code>,
which the NetBeans Platform
uses to specify module dependencies in the <code>manifest.mf</code>
file:</p>
<pre class="examplecode">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;project xmlns="https://netbeans.org/ns/project/1"&gt;
&lt;type&gt;org.netbeans.modules.apisupport.project&lt;/type&gt;
&lt;configuration&gt;
&lt;data xmlns="https://netbeans.org/ns/nb-module-project/3"&gt;
&lt;code-name-base&gt;org.demo.mymodule&lt;/code-name-base&gt;
&lt;suite-component/&gt;
&lt;module-dependencies&gt;
&lt;dependency&gt;
&lt;code-name-base&gt;org.netbeans.modules.settings&lt;/code-name-base&gt;
&lt;build-prerequisite/&gt;
&lt;compile-dependency/&gt;
&lt;run-dependency&gt;
&lt;release-version&gt;1&lt;/release-version&gt;
&lt;specification-version&gt;1.26.1&lt;/specification-version&gt;
&lt;/run-dependency&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;code-name-base&gt;org.openide.awt&lt;/code-name-base&gt;
&lt;build-prerequisite/&gt;
&lt;compile-dependency/&gt;
&lt;run-dependency&gt;
&lt;specification-version&gt;7.23.1&lt;/specification-version&gt;
&lt;/run-dependency&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;code-name-base&gt;org.openide.util&lt;/code-name-base&gt;
&lt;build-prerequisite/&gt;
&lt;compile-dependency/&gt;
&lt;run-dependency&gt;
&lt;specification-version&gt;8.6.1&lt;/specification-version&gt;
&lt;/run-dependency&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;code-name-base&gt;org.openide.util.lookup&lt;/code-name-base&gt;
&lt;build-prerequisite/&gt;
&lt;compile-dependency/&gt;
&lt;run-dependency&gt;
&lt;specification-version&gt;8.3.1&lt;/specification-version&gt;
&lt;/run-dependency&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;code-name-base&gt;org.openide.windows&lt;/code-name-base&gt;
&lt;build-prerequisite/&gt;
&lt;compile-dependency/&gt;
&lt;run-dependency&gt;
&lt;specification-version&gt;6.33.1&lt;/specification-version&gt;
&lt;/run-dependency&gt;
&lt;/dependency&gt;
&lt;/module-dependencies&gt;
&lt;public-packages/&gt;
&lt;/data&gt;
&lt;/configuration&gt;
&lt;/project&gt;</pre>
</li>
<li><p>On the command line, go to the "ABC/myapp" folder and run this:</p>
<pre class="examplecode">ant run</pre>
</li>
<li><p>The application starts up and shows a new window, which can also be
opened from the Window menu.</p>
<p><img src="../images/tutorials/ant/ant-result-2.png" alt="structure 1"/></p>
</li>
</ol>
<p>Congratulations, you've successfully set up a pure Ant-based application structure
for working with the NetBeans Platform.</p>
<div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback:%20EMF%20Integration%20Tutorial">Send Us Your Feedback</a></div>
</body>
</html>