| <!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 Quick Start for NetBeans Platform 7.2</title> | |
| <meta name="AUDIENCE" content="NBUSER"/> | |
| <meta name="TYPE" content="ARTICLE"/> | |
| <link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"/> | |
| <meta name="EXPIRES" content="N"/> | |
| <meta name="developer" content="gwielenga@netbeans.org"/> | |
| <meta name="indexed" content="y"/> | |
| <meta name="description" | |
| content="A short guide to getting started with 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 7.2 Quick Start</h1> | |
| <p>Welcome to the <a href="https://platform.netbeans.org/"><b>NetBeans Platform</b></a>!</p> | |
| <p>The NetBeans Platform is a generic application framework primarily for Java desktop applications. | |
| The main benefit of the NetBeans Platform is its predefined modular architecture. Secondary | |
| benefits are the NetBeans Platform's reusable solutions such as its | |
| docking framework and its out-of-the-box pluggable components, in combination with the tools | |
| provided by its SDK, NetBeans IDE, in particular | |
| its award winning "Matisse" GUI Builder for designing GUI components.</p> | |
| <p>In this quick start, you are introduced to the benefits and usages of modularity | |
| on the Java desktop via | |
| a very simple example, contributed by Thomas Würthinger, a | |
| PhD student at the Johannes Kepler University in Linz, Austria. Once you have | |
| grasped the concepts introduced in this quick start, you will be ready to | |
| step onto the <a href="https://netbeans.org/kb/trails/platform.html">NetBeans Platform Learning Trail</a>, | |
| providing a very rich variety of tutorials for many different scenarios | |
| relating to the NetBeans Platform.</p> | |
| <p class="tips"> If you are new to the NetBeans Platform, it is highly | |
| recommended to watch the screencast series <a href="https://platform.netbeans.org/tutorials/nbm-10-top-apis.html">Top 10 NetBeans APIs</a>.</p> | |
| <p><strong class="notes">Note: </strong>This document uses NetBeans Platform 7.2 and | |
| NetBeans IDE 7.2. If you | |
| are using an earlier version, see <a href="71/nbm-quick-start.html">the previous version | |
| of this document</a>.</p> | |
| <p><b>Contents</b></p> | |
| <p><img src="../../images/articles/72/netbeans-stamp.gif" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 7.2" title="Content on this page applies to NetBeans IDE 7.2"/></p> | |
| <ul class="toc"> | |
| <li>Part 1: <a href="#single">A Single Module NetBeans Platform Application</a> | |
| <ul> | |
| <li><a href="#application">Create the Application</a></li> | |
| <li><a href="#module">Create the Module</a></li> | |
| <li><a href="#window">Create the Window</a></li> | |
| <li><a href="#run">Run the Application</a></li> | |
| </ul> | |
| </li> | |
| <li>Part 2: <a href="#lookup">A Modular Application Using Lookup</a> | |
| <ul> | |
| <li><a href="#api">Create the API</a></li> | |
| <li><a href="#impl">Implement the API</a></li> | |
| <li><a href="#run2">Run the Application</a></li> | |
| </ul> | |
| </li> | |
| <li>Part 3: <a href="#listener">Publishing and Subscribing to the Lookup</a> | |
| <ul> | |
| <li><a href="#publish">Publish to the Lookup</a></li> | |
| <li><a href="#subscribe">Subscribe to the Lookup</a></li> | |
| </ul> | |
| </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="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td> | |
| <td class="tbltd1">version 7.2 or above</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 or above</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p></p> | |
| <p><b class="notes">Note:</b> Even though it is a separate product, there is no | |
| need to download the NetBeans Platform separately. Typically, you develop the | |
| application in NetBeans IDE and then exclude the modules that are specific to | |
| the IDE but that are superfluous to your application.</p> | |
| <p class="tips"> Do some background reading before diving into | |
| this tutorial. In particular, read the <a href="http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html">Modules API Reference</a> document, | |
| which explains what modules are and provides some | |
| context for this tutorial, while noting that there is an extensive Reference Material section | |
| on the <a href="https://netbeans.org/kb/trails/platform.html">NetBeans Platform Learning Trail</a>.</p> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="single"></a>A Single Module NetBeans Platform Application</h2> | |
| <p>We start by creating a new NetBeans Platform application, | |
| containing a single module.</p> | |
| <ul> | |
| <li><a href="#application">Create the Application</a></li> | |
| <li><a href="#module">Create the Module</a></li> | |
| <li><a href="#window">Create the Window</a></li> | |
| <li><a href="#run">Running the Application</a></li> | |
| </ul> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="application"></a>Create the Application</h3> | |
| <p>In this section, you create your first NetBeans Platform application.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li><p>Choose File | New Project and then choose NetBeans Modules. | |
| Select "NetBeans Platform Application". You should see this:</p><br/> | |
| <p><img src="../../images/tutorials/quickstart-platform/72/new-project-1.png" alt="Fig 1"/></p> | |
| <br/><p>Click Next.</p></li> | |
| <li><p>Name your new application "WordProcessor" and specify a folder on disk | |
| for storing it:</p><br/> | |
| <p><img src="../../images/tutorials/quickstart-platform/72/new-project-2.png" alt="Fig 2"/></p> | |
| <br/><p>Click Finish. The new project appears as follows in the Projects window:</p> | |
| <br/><p><img src="../../images/tutorials/quickstart-platform/72/new-project-3.png" alt="Fig 2-1"/></p></li> | |
| </ol> | |
| </div> | |
| </div> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="module"></a>Create the Module</h3> | |
| <p>In this section, you create your first NetBeans Platform module.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li><p>Right-click the "Modules" node, shown in the screenshot above, | |
| and choose "Add New":</p> | |
| <br/><p><img src="../../images/tutorials/quickstart-platform/72/new-project-4.png" alt="Fig 2-1"/></p> | |
| <p>Name the new | |
| module "WordEditorCore":</p> | |
| <br/><p><img alt="create new module" src="../../images/tutorials/quickstart-platform/72/new-project-5.png"/></p> | |
| <br/><p>Click Next.</p></li> | |
| <li><p>Specify "org.word.editor.core" as the unique string identifying the module, which is its code name | |
| base, together with a project display name that will be shown in the Projects window.</p><br/> | |
| <p><img alt="create new module" src="../../images/tutorials/quickstart-platform/72/new-project-6.png"/></p> | |
| <br/><p>Click Finish. The new module is created and its structure is | |
| shown in the Projects window:</p> | |
| <br/><p><img alt="specify a name" src="../../images/tutorials/quickstart-platform/72/new-project-7.png"/></p></li> | |
| </ol> | |
| </div> | |
| </div> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="window"></a>Create the Window</h3> | |
| <p>In this section, you create your first NetBeans window.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li><p>Right-click the "WordEditorCore" module and choose New | Other. | |
| In the Module Development category, select "Window":</p> | |
| <p><br/><img alt="create new window" src="../../images/tutorials/quickstart-platform/72/new-window-1.png"/></p> | |
| <br/><p>Click Next.</p></li> | |
| <li><p>You should now see a dialog for specifying the position where the new window | |
| will appear in the application frame, as well as whether it will open automatically when the application | |
| starts, among other settings:</p> | |
| <p><br/><img alt="create new window" src="../../images/tutorials/quickstart-platform/72/new-window-2.png"/></p> | |
| <p><br/>In the wizard step above, select "editor", which is the default central | |
| position within the application frame, and "Open on Application Start". Then click Next.</p></li> | |
| <li><p>Set the class name prefix to "Word" and the package to "org.word.editor.core":</p> | |
| <p><br/><img alt="set definitions" src="../../images/tutorials/quickstart-platform/72/new-window-3.png"/></p> | |
| <p><br/>Click Finish. The new window is added to the source structure | |
| of your module:</p> | |
| <p><br/><img alt="set definitions" src="../../images/tutorials/quickstart-platform/72/new-window-4.png"/></p></li> | |
| <li><p>Now double click on the file "WordTopComponent.java" to open | |
| it in the Design view of the "Matisse" GUI Builder. Use the Palette (Ctrl-Shift-8) to | |
| drag and drop a button and a text area onto the window:</p> | |
| <p><br/><img alt="palette" style="border: 1px solid black;" src="../../images/tutorials/quickstart-platform/72/new-window-5.png"/></p> | |
| <br/><p>Do the following to make the new GUI components meaningful:</p> | |
| <br/><ul> | |
| <li>Right-click the text area, choose "Change Variable Name", and then | |
| name it "text". That is the name that will enable you to access the | |
| component from your code.</li> | |
| <li>Right-click the button, choose "Edit Text", and then set the text of the button to "Filter!"</li> | |
| </ul></li> | |
| <li>Double click on the button, causing an event handling method | |
| to automatically be created in the Source editor. The method is called whenever the button is clicked. Change the body | |
| of the method to the following code. | |
| <pre class="examplecode">private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { | |
| <b>String s = text.getText(); | |
| s = s.toUpperCase(); | |
| text.setText(s);</b> | |
| }</pre></li> | |
| </ol> | |
| </div> | |
| </div> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="run"></a>Run the Application</h3> | |
| <p>In this section, you deploy the application.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li><p>Right-click the application and choose Run. Doing so will start up your | |
| new NetBeans Platform application and install your module. You will have a new | |
| window, as well as a new menu item for opening it, | |
| as shown below:</p> | |
| <br/><p><img alt="show new app" src="../../images/tutorials/quickstart-platform/72/new-app-1.png"/></p></li> | |
| <li><p>Enter a text in lowercase in the text area, and click "Filter!". | |
| You should see that the text is now shown | |
| in uppercase:</p> | |
| <br/><p><img alt="uppercase" src="../../images/tutorials/quickstart-platform/72/new-app-3.png"/></p></li> | |
| </ol> | |
| </div> | |
| </div> | |
| <p>You have learned how to create a new NetBeans Platform application and how | |
| to add new modules to it. In the next section, you will be introduced | |
| to the NetBeans Platform's pluggable service infrastructure.</p> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="lookup"></a>A Modular Application Using Lookup</h2> | |
| <p>In this section, you create two additional modules. The first | |
| new module, "WordEditorAPI", | |
| contains a service provider interface. The second module, | |
| "UppercaseFilter", is a service provider for the interface.</p> | |
| <p> The GUI module, which you created in the previous section, will be loosely coupled from | |
| the "UppercaseFilter" service provider because the GUI module | |
| will not refer to any code from the "UppercaseFilter" service provider. | |
| That will be possible because the "UppercaseFilter" | |
| service provider will be registered in the META-INF/services folder | |
| and loaded via the NetBeans Lookup class, which is comparable to | |
| the JDK 6 ServiceLoader class.</p><p> You will then | |
| create another loosely coupled service provider, | |
| named "LowercaseFilter".</p> | |
| <ul> | |
| <li><a href="#api">Create the API</a></li> | |
| <li><a href="#impl">Implement the API</a></li> | |
| <li><a href="#run2">Run the Application</a></li> | |
| </ul> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="api"></a>Create the API</h3> | |
| <p>In this section, you create an API.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li><p>Expand the new application in the Projects window, | |
| right-click the Modules node, and choose "Add New":</p> | |
| <br/><p><img alt="uppercase" src="../../images/tutorials/quickstart-platform/72/new-api-1.png"/></p> | |
| <br/><p>Name the new | |
| module "WordEditorAPI":</p> | |
| <br/><p><img alt="uppercase" src="../../images/tutorials/quickstart-platform/72/new-api-2.png"/></p> | |
| <br/><p>Click Next. Use code name base "org.word.editor.api" and | |
| complete the wizard, which adds the module to your previously created | |
| application, as you did in the previous section:</p> | |
| <br/><p><img alt="uppercase" src="../../images/tutorials/quickstart-platform/72/new-api-3.png"/></p></li> | |
| <li><p>Right-click the "WordEditorAPI" module and choose | |
| New | Java Interface. Name the Java interface "WordFilter", | |
| in the package "org.word.editor.api", and use the editor | |
| to define it as follows:</p> | |
| <pre class="examplecode">package org.word.editor.api; | |
| public interface WordFilter { | |
| String process(String s); | |
| }</pre></li> | |
| <li><p>Right-click the "WordEditorAPI" module, | |
| choose Properties, and use the "API Versioning" | |
| tab to specify that the package containing the | |
| interface should be available throughout the | |
| application:</p> | |
| <br/><p><img alt="" src="../../images/tutorials/quickstart-platform/72/new-api-4.png"/></p> | |
| <br/><p>Click OK.</p> | |
| <p class="tips">In the Projects window, expand "Important Files" in the | |
| "WordEditorAPI" project and then | |
| double-click "Project Metadata". The "project.xml" file | |
| opens and you should see that the package has now been declared | |
| public:</p> | |
| <pre class="examplecode"><?xml version="1.0" encoding="UTF-8"?> | |
| <project xmlns="https://netbeans.org/ns/project/1"> | |
| <type>org.netbeans.modules.apisupport.project</type> | |
| <configuration> | |
| <data xmlns="https://netbeans.org/ns/nb-module-project/3"> | |
| <code-name-base>org.word.editor.api</code-name-base> | |
| <suite-component/> | |
| <module-dependencies/> | |
| <b><public-packages> | |
| <package>org.word.editor.api</package> | |
| </public-packages></b> | |
| </data> | |
| </configuration> | |
| </project></pre> | |
| </li> | |
| </ol> | |
| </div> | |
| </div> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="impl"></a>Implement the API</h3> | |
| <p>In this section, you implement the API, in a separate module.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li><p>Expand the new application in the Projects window, | |
| right-click the Modules node, and choose "Add New" again:</p> | |
| <br/><p><img alt="uppercase" src="../../images/tutorials/quickstart-platform/72/new-impl-1.png"/></p> | |
| <br/><p>Name the new | |
| module "UppercaseFilter":</p> | |
| <br/><p><img alt="uppercase" src="../../images/tutorials/quickstart-platform/72/new-impl-2.png"/></p> | |
| <br/><p>Click Next. Use code name base "org.word.editor.uppercase" and | |
| complete the wizard, which adds the module to your previously created | |
| application, as you did in the previous section:</p> | |
| <br/><p><img alt="uppercase" src="../../images/tutorials/quickstart-platform/72/new-impl-3.png"/></p></li> | |
| <li><p>Right-click the Libraries node "UppercaseFilter" module, | |
| and Add Module Dependency, as shown below:</p> | |
| <br/><p><img alt="" src="../../images/tutorials/quickstart-platform/72/new-impl-4.png"/></p> | |
| <br/><p>Start typing the name of the API class and notice that the list narrows | |
| until the module containing the class is found:</p> | |
| <br/><p><img alt="" src="../../images/tutorials/quickstart-platform/72/new-impl-5.png"/></p> | |
| <br/><p>Click OK.</p> | |
| <br/><p class="tips">In the Projects window, expand "Important Files" in the "UppercaseFilter" project, | |
| and then | |
| double-click "Project Metadata". The "project.xml" file | |
| opens and you should see that a new dependency has been declared:</p> | |
| <pre class="examplecode"><?xml version="1.0" encoding="UTF-8"?> | |
| <project xmlns="https://netbeans.org/ns/project/1"> | |
| <type>org.netbeans.modules.apisupport.project</type> | |
| <configuration> | |
| <data xmlns="https://netbeans.org/ns/nb-module-project/3"> | |
| <code-name-base>org.word.editor.uppercase</code-name-base> | |
| <suite-component/> | |
| <b><module-dependencies> | |
| <dependency> | |
| <code-name-base>org.word.editor.api</code-name-base> | |
| <build-prerequisite/> | |
| <compile-dependency/> | |
| <run-dependency> | |
| <specification-version>1.0</specification-version> | |
| </run-dependency> | |
| </dependency> | |
| </module-dependencies></b> | |
| <public-packages/> | |
| </data> | |
| </configuration> | |
| </project></pre> | |
| <p class="notes"><b>Note:</b> In the same way as shown above, | |
| set a dependency on the Lookup API module, which provides the | |
| @ServiceProvider annotation that you will use in the next step.</p></li> | |
| <li>Because of the Lookup API dependency you defined above, | |
| you can now implement the | |
| interface defined in the WordEditorAPI module. Do so in the "UppercaseFilter" module, by creating | |
| a new class named "UppercaseFilter", in the "org.word.editor.uppercase" package, | |
| as shown below. Start by creating a new Java class, named "UppercaseFilter", and | |
| then define it as follows: | |
| <pre class="examplecode">package org.word.editor.uppercase; | |
| import org.openide.util.lookup.ServiceProvider; | |
| import org.word.editor.api.WordFilter; | |
| @ServiceProvider(service=WordFilter.class) | |
| public class UppercaseFilter implements WordFilter { | |
| @Override | |
| public String process(String s) { | |
| return s.toUpperCase(); | |
| } | |
| }</pre> | |
| <p class="tips"> At compile time, the @ServiceProvider annotation will create a META-INF/services | |
| folder with a file that registers your implementation of the | |
| WordFilter interface, following the JDK 6 ServiceLoader mechanism.</p></li> | |
| <li><p>In the WordEditorCore module, the code that handles a click on the | |
| filter button now needs to be changed, so that all | |
| implementations of the interface "WordFilter" are located | |
| and loaded. | |
| When such implementations are found, you need to invoke its method to | |
| filter the text. Before we can do this, we need to | |
| add a dependency in the | |
| the "WordEditorCore" module on the "WordEditorAPI" module:</p> | |
| <br/><p><img alt="" src="../../images/tutorials/quickstart-platform/72/new-impl-6.png"/></p> | |
| <p>Now, you can load implementations of the | |
| "WordFilter" class, as shown below:</p> | |
| <pre class="examplecode">private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { | |
| <b>String enteredText = text.getText(); | |
| Collection<? extends WordFilter> allFilters = Lookup.getDefault().lookupAll(WordFilter.class); | |
| StringBuilder sb = new StringBuilder(); | |
| for (WordFilter textFilter : allFilters) { | |
| String processedText = textFilter.process(enteredText); | |
| sb.append(processedText).append("\n"); | |
| } | |
| text.setText(sb.toString());</b> | |
| }</pre> | |
| <p class="tips"> The above could be achieved via the | |
| JDK 6 "ServiceLoader" class, except that the | |
| "Lookup" class can be used in JDK's prior | |
| to JDK 6. Aside from that, the "Lookup" class | |
| has a number of additional features, as the | |
| next section will illustrate.</p> | |
| </li> | |
| </ol> | |
| </div> | |
| </div> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="run2"></a>Run the Application</h3> | |
| <p>In this section, you run the application again.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li><p>Now you can run the application again and check | |
| that everything works just as before. While the functionality | |
| is the same, the new modular design offers a clear separation | |
| between the GUI and the implementation | |
| of the filter. The structure of the application should be as shown below.</p> | |
| <br/><p><img alt="" src="../../images/tutorials/quickstart-platform/72/new-impl-7.png"/></p> | |
| </li> | |
| <li><p>The new application can also be extended | |
| quite easily, by adding new service providers to | |
| the application's classpath. As an exercise, add a new module that provides a "LowercaseFilter" | |
| implementation of the API to the application.</p></li> | |
| </ol> | |
| </div> | |
| </div> | |
| <p>You have now used the default Lookup, that is, "Lookup.getDefault()", to load | |
| implementations of an interface from the META-INF/services folder.</p> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="listener"></a>Publishing and Subscribing to the Lookup</h2> | |
| <p>In this section, we create a fourth module, which receives texts | |
| dynamically whenever we click the "Filter!" button | |
| in our first module.</p> | |
| <ul> | |
| <li><a href="#publish">Publish to the Lookup</a></li> | |
| <li><a href="#subscribe">Subscribe to the Lookup</a></li> | |
| </ul> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="publish"></a>Publish to the Lookup</h3> | |
| <p>In this section, you publish a String into the Lookup of the TopComponent. Whenever | |
| the TopComponent is selected, the String is published into the application's context.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li>In the "WordEditorCore" module, we publish a String whenever | |
| the user clicks the "Filter!" button. To do so, change the | |
| constructor of the "WordTopComponent" as follows: | |
| <pre class="examplecode"><b>private <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/InstanceContent.html">InstanceContent</a> content;</b> | |
| private WordTopComponent() { | |
| initComponents(); | |
| setName(Bundle.CTL_WordTopComponent()); | |
| setToolTipText(Bundle.HINT_WordTopComponent()); | |
| <b>content = new InstanceContent(); | |
| <a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html#associateLookup(org.openide.util.Lookup)">associateLookup</a>(new <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/AbstractLookup.html">AbstractLookup</a>(content));</b> | |
| }</pre></li><li><p>Change the code of the filter | |
| button so that the entered text is added to | |
| the <tt>InstanceContent</tt> object when the button is clicked.</p> | |
| <pre class="examplecode">private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { | |
| String enteredText = text.getText(); | |
| Collection<? extends WordFilter> allFilters = Lookup.getDefault().lookupAll(WordFilter.class); | |
| StringBuilder sb = new StringBuilder(); | |
| for (WordFilter textFilter : allFilters) { | |
| String processedText = textFilter.process(enteredText); | |
| sb.append(processedText).append("\n"); | |
| <b>content.add(enteredText);</b> | |
| } | |
| text.setText(sb.toString()); | |
| }</pre> | |
| </li> | |
| </ol> | |
| </div> | |
| </div> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="subscribe"></a>Subscribe to the Lookup</h3> | |
| <p>In this section, you create a new module, with a new window. In | |
| the new window, you listen to the application's context for Strings. When there | |
| is a new String in the Lookup, you display it in the window.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li><p>In the same way as done in the previous sections, | |
| create another module in your application and name it "WordHistory". | |
| Use code name base "org.word.editor.history".</p> | |
| </li> | |
| <li><p>In the WordHistory module, right-click the "org.word.editor.history" package | |
| and choose New | Window. Use the New Window wizard to create a | |
| new window component that will automatically be opened on the left side of the | |
| application frame, which is the "explorer" position:</p> | |
| <br/><p><img alt="" src="../../images/tutorials/quickstart-platform/72/new-window2-1.png"/></p> | |
| <br/><p>Click Next. Use prefix "WordHistory" and specify that the new window will be stored | |
| in the "org.word.editor.history" package. Click Finish.</p> | |
| </li> | |
| <li><p>Once | |
| you have created the window, add a | |
| <tt>JTextArea</tt> to it:</p> | |
| <br/><p><img alt="" style="border:1px solid black" src="../../images/tutorials/quickstart-platform/72/new-window2-2.png"/></p> | |
| <p>Change the variable | |
| name of the text area to "historyText".</p> | |
| </li> | |
| <li>In the Source view, add code to the constructor of the HistoryTopComponent class so | |
| that it listens to the lookup of the <tt>String</tt> class | |
| of the current active window. It displays all retrieved | |
| <tt>String</tt> objects in the text area: | |
| <pre class="examplecode">... | |
| ... | |
| ... | |
| public final class HistoryTopComponent extends TopComponent <b>implements LookupListener</b> { | |
| <b>private org.openide.util.Lookup.Result<String> result;</b> | |
| ... | |
| ... | |
| ... | |
| <b>@Override | |
| public void componentOpened() { | |
| result = org.openide.util.Utilities.actionsGlobalContext().lookupResult(String.class); | |
| result.addLookupListener(this); | |
| } | |
| @Override | |
| public void componentClosed() { | |
| result.removeLookupListener(this); | |
| } | |
| @Override | |
| public void resultChanged(LookupEvent le) { | |
| Collection<? extends String> allStrings = result.allInstances(); | |
| StringBuilder sb = new StringBuilder(); | |
| for (String string : allStrings) { | |
| sb.append(string).append("\n"); | |
| } | |
| historyText.setText(sb.toString()); | |
| }</b> | |
| ... | |
| ... | |
| ... | |
| </pre></li> | |
| <li><p>Then you can start the application and | |
| experiment with it. The result should look similar | |
| to that shown in the screenshot below:</p> | |
| <br/><p><img alt="" src="../../images/tutorials/quickstart-platform/72/new-result-1.png"/></p> | |
| <p class="tips">As an exercise, redesign the user interface of the "WordTopComponent" | |
| in such a way that a <tt>JList</tt> displays the filters.</p> | |
| </li> | |
| </ol> | |
| </div> | |
| </div> | |
| <p>Congratulations! At this stage, with very little coding, | |
| you have created a small example of a loosely-coupled modular | |
| application:</p> | |
| <p><img alt="" src="../../images/tutorials/quickstart-platform/72/new-result-2.png"/></p> | |
| <p>Two important concepts have been covered in this tutorial.</p> | |
| <ol> | |
| <li>The application consists of four modules. Code from one module can only | |
| be used by another module if (1) the first module explicitly exposes | |
| packages and (2) the second module sets a dependency on the first module. | |
| In this way, the NetBeans Platform helps to organize your code in a | |
| strict modular architecture, ensuring that code isn't reused randomly | |
| but only when there are contracts set between the modules that provide | |
| the code.</li> | |
| <li>Secondly, the <tt>Lookup</tt> class has been introduced as | |
| a mechanism for communicating between modules, as an extension of the | |
| JDK 6 ServiceLoader approach. Implementations are loaded via their | |
| interfaces. Without using any code from an implementation, the "WordEditorCore" | |
| module is able to display the service provided by the implementor. Loose | |
| coupling is provided to NetBeans Platform applications in this way.</li> | |
| </ol> | |
| <p class="tips"> To continue learning about modularity | |
| and the NetBeans Platform, head on to | |
| the four-part "NetBeans Platform Selection | |
| Management" series, <a href="https://platform.netbeans.org/tutorials/nbm-selection-1.html">which starts here</a>. | |
| After that, get started with the <a href="https://netbeans.org/kb/trails/platform.html">NetBeans Platform Learning Trail</a>, choosing | |
| the tutorials that are most relevant to your particular business scenario. Also, | |
| whenever you have questions about the NetBeans Platform, of any kind, feel free | |
| to write to the mailing list, dev@platform.netbeans.org; its related | |
| archive <a href="https://netbeans.org/projects/platform/lists/dev/archive">is here</a>.</p> | |
| <p>Have fun with the NetBeans Platform and see you on the mailing list!</p> | |
| </body> | |
| </html> |