| <!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 Tutorial for Geospatial Systems</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 setting up an geospatial environment | |
| 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 Tutorial for Geospatial Systems</h1> | |
| <p>The NetBeans Platform is a solid infrastructure for | |
| geospatial systems. It provides | |
| a docking framework with full screen mode, an application frame | |
| within which a map can be placed, and a loosely coupled module system for | |
| the organization of code into feature-oriented plugins.</p> | |
| <p>In this quick start, you are shown how to set up a typical | |
| geospatial application structure, leveraging the central features | |
| of the NetBeans Platform. You start by creating a new application, | |
| you add several modules, each representing a hypothetical feature in | |
| your geospatial system, you configure the application to start | |
| up in full screen mode and hide tabs, while you integrate various | |
| mapping solutions.</p> | |
| <p>By the end of this tutorial, you will have learned how to | |
| configure the NetBeans Platform to optimize it for typical | |
| geospatial scenarios, while also learning how to integrate a variety | |
| of map technologies into your NetBeans Platform application, | |
| such as OpenMap, shown below:</p> | |
| <p><img alt="openmap" src="../../images/tutorials/air/72/openmap-nb-small.png"/></p> | |
| <p><b>Contents</b></p> | |
| <p><img src="../../images/articles/71/netbeans-stamp.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 7.1" title="Content on this page applies to NetBeans IDE 7.1"/></p> | |
| <ul class="toc"> | |
| <li>Part 1: <a href="#application">Creating the Application</a></li> | |
| <li>Part 2: <a href="#modules">Adding Modules for Geospatial Features</a></li> | |
| <li>Part 3: <a href="#windows">Designing the Window Layout</a></li> | |
| <li>Part 4: <a href="#map">Integrating Map Technologies</a> | |
| <ul> | |
| <li><a href="#openmap">OpenMap</a></li> | |
| <li><a href="#geotk">Geotoolkit</a></li> | |
| </ul> | |
| </li> | |
| <li>Part 5: <a href="#publish">Publishing and Subscribing to Objects of Interest</a></li> | |
| <li>Part 6: <a href="#configure">Configuring the Geospatial System</a> | |
| <ul> | |
| <li><a href="#fullscreen">Starting Up in Full Screen Mode</a></li> | |
| <li><a href="#undocked">Starting Up in Undocked Mode</a></li> | |
| <li><a href="#tabs">Removing Tabs</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.1 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 the NetBeans Platform | |
| is a distinct product, there is no | |
| need to download it separately from NetBeans IDE. Typically, you develop the | |
| application in NetBeans IDE, on top of the NetBeans Platform | |
| used by NetBeans IDE. Then you exclude the modules that are specific to | |
| the IDE but that are superfluous to your application.</p> | |
| <p class="tips"> If you are new to the NetBeans Platform, | |
| 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="application"></a>Creating the Application</h2> | |
| <p>We start by creating a new NetBeans Platform application as a starting | |
| point for our geospatial system.</p> | |
| <ol> | |
| <li><p>Choose File | New Project and then choose NetBeans Modules. | |
| Select "NetBeans Platform Application". Click Next.</p> | |
| <p>Name your new application "MyATCSystem" and specify a folder on disk | |
| for storing it:</p> | |
| <p><img src="../../images/tutorials/air/72/new-app.png" alt="Fig 2"/></p> | |
| <p>Click Finish. The new project appears as follows in the Projects window:</p> | |
| <p><img src="../../images/tutorials/air/72/new-app-created.png" alt="Fig 2-1"/></p></li> | |
| <li><p>Right-click the application and choose Run. The application | |
| deploys and you should see this:</p> | |
| <p><img alt="create new module" src="../../images/tutorials/air/72/new-app-deployed.png"/></p> | |
| </li> | |
| </ol> | |
| <p>You have learned how to create a new NetBeans Platform application, | |
| which is the starting point for your geospatial system.</p> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="modules"></a>Adding Modules for Geospatial Features</h2> | |
| <p>In a NetBeans Platform application, each feature is provided by | |
| one or more modules. In our geospatial system, we'll pretend we have | |
| a "Flight Control" feature in one module, and a "Sky Overview" | |
| feature in another module. Each module will include a window | |
| for viewing data and information related to the feature.</p> | |
| <ol> | |
| <li><p>Expand the new application in the Projects window, | |
| right-click the Modules node, and choose "Add New":</p> | |
| <p><img alt="uppercase" src="../../images/tutorials/air/72/new-module.png"/></p> | |
| </li> | |
| <li> | |
| <p>Click Next. Type "FlightControl" as project name and set | |
| a location on disk where the the project will be stored, | |
| which is typically within the application's folder:</p> | |
| <p><img alt="uppercase" src="../../images/tutorials/air/72/flight-control.png"/></p> | |
| <p>Click Next.</p> | |
| </li> | |
| <li> | |
| <p>Use code name base "org.myatc.flight.control" and, optionally, | |
| change the display name of the module:</p> | |
| <p><img alt="uppercase" src="../../images/tutorials/air/72/flight-control-2.png"/></p> | |
| <p>Click Finish.</p> | |
| </li> | |
| <li> | |
| <p>Repeat the steps above for a feature named "SkyOverview", with | |
| code name base "org.myatc.sky.overview".</p> | |
| </li> | |
| <li> | |
| <p>You should now have two modules in your system, as | |
| shown below:</p> | |
| <p><img alt="uppercase" src="../../images/tutorials/air/72/flight-control-3.png"/></p> | |
| </li> | |
| <li> | |
| <p>Repeat the steps above for all the features in your application. Some | |
| features could be broken into multiple different modules, as | |
| discussed in <a href="http://java.dzone.com/news/how-to-split-into-modules">How to Split an Application into Modules?</a>.</p> | |
| </li> | |
| </ol> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="windows"></a>Designing the Window Layout</h2> | |
| <p>In this section, we add a new window into the modules we created | |
| in the previous section.</p> | |
| <ol> | |
| <li><p>Right-click the Initializer module's Libraries node, choose | |
| Add Module Dependency, then set a dependency on the | |
| Lookup API, Settings API, UI Utilities API, Utilities API, | |
| and Window System API.</p> | |
| </li> | |
| <li><p>Create a new Java class, with this content:</p> | |
| <pre>import org.netbeans.api.settings.ConvertAsProperties; | |
| import org.openide.awt.ActionID; | |
| import org.openide.awt.ActionReference; | |
| import org.openide.util.NbBundle; | |
| import org.openide.windows.TopComponent; | |
| @ConvertAsProperties( | |
| dtd = "-//org.myatc.flight.control//FlightControl//EN", | |
| autostore = false) | |
| @TopComponent.Description( | |
| preferredID = "FlightControlTopComponent", | |
| persistenceType = TopComponent.PERSISTENCE_ALWAYS) | |
| @TopComponent.Registration(mode = "output", openAtStartup = true) | |
| @ActionID(category = "Window", id = "org.myatc.flight.control.FlightControlTopComponent") | |
| @ActionReference(path = "Menu/Window" /*, position = 333 */) | |
| @TopComponent.OpenActionRegistration( | |
| displayName = "#CTL_FlightControlAction", | |
| preferredID = "FlightControlTopComponent") | |
| @NbBundle.Messages({ | |
| "CTL_FlightControlAction=FlightControl", | |
| "CTL_FlightControlTopComponent=FlightControl Window", | |
| "HINT_FlightControlTopComponent=This is a FlightControl window" | |
| }) | |
| public class FlightControlTopComponent extends TopComponent { | |
| public FlightControlTopComponent() { | |
| initComponents(); | |
| setName(Bundle.CTL_FlightControlTopComponent()); | |
| setToolTipText(Bundle.HINT_FlightControlTopComponent()); | |
| } | |
| private void initComponents() { | |
| // TODO add components to the component here | |
| } | |
| @Override | |
| public void componentOpened() { | |
| // TODO add custom code on component opening | |
| } | |
| @Override | |
| public void componentClosed() { | |
| // TODO add custom code on component closing | |
| } | |
| 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 | |
| } | |
| void readProperties(java.util.Properties p) { | |
| String version = p.getProperty("version"); | |
| // TODO read your settings according to their version | |
| } | |
| }</pre></li> | |
| <li>Repeat the steps above for the second module, but create the second | |
| Java class as follows: | |
| <pre>import org.netbeans.api.settings.ConvertAsProperties; | |
| import org.openide.awt.ActionID; | |
| import org.openide.awt.ActionReference; | |
| import org.openide.util.NbBundle; | |
| import org.openide.windows.TopComponent; | |
| @ConvertAsProperties( | |
| dtd = "-//org.myatc.sky.overview//SkyOverview//EN", | |
| autostore = false) | |
| @TopComponent.Description( | |
| preferredID = "SkyOverviewTopComponent", | |
| persistenceType = TopComponent.PERSISTENCE_ALWAYS) | |
| @TopComponent.Registration(mode = "explorer", openAtStartup = true) | |
| @ActionID(category = "Window", id = "org.myatc.sky.overview.SkyOverviewTopComponent") | |
| @ActionReference(path = "Menu/Window" /*, position = 333 */) | |
| @TopComponent.OpenActionRegistration( | |
| displayName = "#CTL_SkyOverviewAction", | |
| preferredID = "SkyOverviewTopComponent") | |
| @NbBundle.Messages({ | |
| "CTL_SkyOverviewAction=SkyOverview", | |
| "CTL_SkyOverviewTopComponent=SkyOverview Window", | |
| "HINT_SkyOverviewTopComponent=This is a SkyOverview window" | |
| }) | |
| public class SkyOverviewTopComponent extends TopComponent { | |
| public SkyOverviewTopComponent() { | |
| initComponents(); | |
| setName(Bundle.CTL_SkyOverviewTopComponent()); | |
| setToolTipText(Bundle.HINT_SkyOverviewTopComponent()); | |
| } | |
| private void initComponents() { | |
| // TODO add components to the component here | |
| } | |
| @Override | |
| public void componentOpened() { | |
| // TODO add custom code on component opening | |
| } | |
| @Override | |
| public void componentClosed() { | |
| // TODO add custom code on component closing | |
| } | |
| 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 | |
| } | |
| void readProperties(java.util.Properties p) { | |
| String version = p.getProperty("version"); | |
| // TODO read your settings according to their version | |
| } | |
| }</pre> | |
| </li> | |
| <li>If you run the application, you will see the application | |
| starts up with two new windows, each of them docked into | |
| the application.</li> | |
| <li>Now we will reconfigure the window system so that the | |
| two windows start up in undocked mode.</li> | |
| </ol> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="map"></a>Integrating Map Technologies</h2> | |
| <p>A variety of map technologies exist. In the subsections that follow, | |
| you will learn how to integrate a range of different map technologies | |
| into your NetBeans Platform application.</p> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="openmap"></a>OpenMap</h3> | |
| <p><a href="http://openmap.bbn.com/">OpenMap</a> is | |
| an open-source map technology.</p> | |
| <p><img alt="openmap" src="../../images/tutorials/air/72/openmap-nb-small.png"/></p> | |
| <ol> | |
| <li>Download OpenMap: <a href="http://openmap.bbn.com/cgi-bin/license.cgi">http://openmap.bbn.com/cgi-bin/license.cgi</a></li> | |
| <li><p>Right-click the application's Modules node, | |
| choose Add New Library and then create a library | |
| wrapper module that wraps the OpenMap JAR files.</p> | |
| </li> | |
| <li>From the OpenMap distribution, copy | |
| <tt>dcwpo-browse.shp</tt> and <tt>dcwpo-browse.ssx</tt> | |
| into your module. In the source code below, make sure | |
| the references to the files point to the correct location | |
| in your module.</li> | |
| <li><p>In the MapTopComponent, use OpenMap as follows, as a first | |
| example to get started with your OpenMap/NetBeans Platform | |
| integration:</p> | |
| <pre class="examplecode">public final class MapTopComponent extends TopComponent { | |
| private final InstanceContent ic = new InstanceContent(); | |
| public MapTopComponent() { | |
| initComponents(); | |
| setName(Bundle.CTL_MapTopComponent()); | |
| setToolTipText(Bundle.HINT_MapTopComponent()); | |
| setLayout(new BorderLayout()); | |
| try { | |
| //MapPanel: | |
| MapPanel mapPanel = new BasicMapPanel(); | |
| //MapHandler: | |
| MapHandler mapHandler = mapPanel.getMapHandler(); | |
| mapHandler.add(new LayerHandler()); | |
| mapHandler.add(this); | |
| //MapBean: | |
| MapBean mapBean = mapPanel.getMapBean(); | |
| mapBean.setScale(120000000f); | |
| //Selection: | |
| MouseDelegator mouseDelegator = new MouseDelegator(); | |
| mapHandler.add(mouseDelegator); | |
| SelectMouseMode selectMouseMode = new SelectMouseMode(); | |
| mapHandler.add(selectMouseMode); | |
| mouseDelegator.setActive(selectMouseMode); | |
| //MapMouseListener: | |
| final MyMapMouseListener myMapMouseListener = new MyMapMouseListener(); | |
| //ShapeLayer: | |
| ShapeLayer shapeLayer = new ShapeLayer() { | |
| @Override | |
| public synchronized MapMouseListener getMapMouseListener() { | |
| return myMapMouseListener; | |
| } | |
| }; | |
| //Properties: | |
| Properties shapeLayerProps = new Properties(); | |
| shapeLayerProps.put("lineColor", "000000"); | |
| shapeLayerProps.put("fillColor", "BDDE83"); | |
| shapeLayerProps.put("shapeFile", "org/myatc/initializer/dcwpo-browse.shp"); | |
| shapeLayerProps.put("spatialIndex", "org/myatc/initializer/dcwpo-browse.ssx"); | |
| //Assign properties to ShapeLayer: | |
| shapeLayer.setProperties(shapeLayerProps); | |
| shapeLayer.setVisible(true); | |
| //Assign ShapeLayer to MapHandler: | |
| mapHandler.add(shapeLayer); | |
| add(mapPanel.getMapBean(), BorderLayout.CENTER); | |
| } catch (MultipleSoloMapComponentException msmce) { | |
| } | |
| associateLookup(new AbstractLookup(ic)); | |
| } | |
| public class MyMapMouseListener implements MapMouseListener { | |
| @Override | |
| public String[] getMouseModeServiceList() { | |
| return new String[]{SelectMouseMode.modeID}; | |
| } | |
| @Override | |
| public boolean mouseClicked(MouseEvent e) { | |
| MapMouseEvent mme = (MapMouseEvent) e; | |
| //Optionally: | |
| //LatLonPoint latLonPoint = LatLonPoint.getFloat(mme.getLatLon()); | |
| //UTMPoint utmPoint = UTMPoint.LLtoUTM(latLonPoint); | |
| //Publish something into Lookup: | |
| ic.set(Collections.singleton(mme.getLatLon()), null); | |
| return true; | |
| } | |
| @Override | |
| public boolean mousePressed(MouseEvent e) {return true;} | |
| @Override | |
| public boolean mouseReleased(MouseEvent e) {return true;} | |
| @Override | |
| public void mouseEntered(MouseEvent e) {} | |
| @Override | |
| public void mouseExited(MouseEvent e) {} | |
| @Override | |
| public boolean mouseDragged(MouseEvent e) {return true;} | |
| @Override | |
| public boolean mouseMoved(MouseEvent e) {return true;} | |
| @Override | |
| public void mouseMoved() {} | |
| } | |
| ... | |
| ... | |
| ...</pre> | |
| </li> | |
| <li>Run the application, click on the map, and you will | |
| be publishing new <tt>Point2D</tt> objects into the Lookup | |
| of the TopComponent.</li> | |
| </ol> | |
| </div> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="geotk"></a>Geotoolkit</h3> | |
| <p><a href="http://www.geotoolkit.org/">Geotoolkit</a> is | |
| an open-source map technology.</p> | |
| <ol> | |
| <li>Download Geotoolkit: <a href="http://www.geotoolkit.org/download.html">http://www.geotoolkit.org/download.html</a></li> | |
| <li><p>Right-click the application's Modules node, | |
| choose Add New Library and then create a library | |
| wrapper module that wraps the Geotoolkit JAR files.</p> | |
| </li> | |
| <li>From the Geotoolkit distribution, copy | |
| <tt>Countries.shp</tt> file, as well as the DBF, PRJ, and SHX file | |
| into your module. In the source code below, make sure | |
| the references to the files point to the correct location | |
| in your module.</li> | |
| <li><p>In the MapTopComponent, use Geotoolkit as follows, as a first | |
| example to get started with your Geotoolkit/NetBeans Platform | |
| integration:</p> | |
| <pre class="examplecode">public final class MapTopComponent extends TopComponent { | |
| public MapTopComponent() { | |
| initComponents(); | |
| setName(Bundle.CTL_MapTopComponent()); | |
| setToolTipText(Bundle.HINT_MapTopComponent()); | |
| setLayout(new BorderLayout()); | |
| MapContext mapContext = MapBuilder.createContext(DefaultGeographicCRS.SPHERE); | |
| addShpData(mapContext); | |
| JMap2D map = new JMap2D(); | |
| map.getContainer().setContext(mapContext); | |
| map.setBackground(new Color(0, 150, 150)); | |
| JNavigationBar navBar = new JNavigationBar(map); | |
| add(navBar, BorderLayout.NORTH); | |
| add(map, BorderLayout.CENTER); | |
| } | |
| public void addShpData(MapContext context) { | |
| try { | |
| DataStore store = DataStoreFinder.get("url", | |
| MapTopComponent.class.getResource("Countries.shp")); | |
| Name name = store.getNames().iterator().next(); | |
| Session session = store.createSession(true); | |
| FeatureCollection fs = session.getFeatureCollection(QueryBuilder.all(name)); | |
| MapLayer layer = MapBuilder.createFeatureLayer(fs, | |
| RandomStyleFactory.createDefaultVectorStyle(fs)); | |
| layer.setVisible(true); | |
| context.layers().add(layer); | |
| } catch (DataStoreException e) { | |
| } | |
| } | |
| ... | |
| ... | |
| ...</pre> | |
| <p class="notes"><b>Note:</b> The import statements are as follows:</p> | |
| <pre class="examplecode">import java.awt.BorderLayout; | |
| import java.awt.Color; | |
| import org.geotoolkit.data.DataStore; | |
| import org.geotoolkit.data.DataStoreFinder; | |
| import org.geotoolkit.data.FeatureCollection; | |
| import org.geotoolkit.data.query.QueryBuilder; | |
| import org.geotoolkit.data.session.Session; | |
| import org.geotoolkit.gui.swing.go2.JMap2D; | |
| import org.geotoolkit.gui.swing.go2.control.JNavigationBar; | |
| import org.geotoolkit.map.MapBuilder; | |
| import org.geotoolkit.map.MapContext; | |
| import org.geotoolkit.map.MapLayer; | |
| import org.geotoolkit.referencing.crs.DefaultGeographicCRS; | |
| import org.geotoolkit.storage.DataStoreException; | |
| import org.geotoolkit.util.RandomStyleFactory; | |
| import org.netbeans.api.settings.ConvertAsProperties; | |
| import org.opengis.feature.type.Name; | |
| import org.openide.awt.ActionID; | |
| import org.openide.awt.ActionReference; | |
| import org.openide.util.NbBundle.Messages; | |
| import org.openide.windows.TopComponent;</pre> | |
| </li> | |
| <li>Run the application and you will see your Geotoolkit map component | |
| displayed in a window in your NetBeans Platform application.</li> | |
| </ol> | |
| </div> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="publish"></a>Publishing and Subscribing to Objects of Interest</h2> | |
| <p>When a mouse click is performed in your map, | |
| you need to publish an object into the Lookup of the TopComponent. For example, | |
| you could publish the current Point on the map.</p> | |
| <p>In the supporting windows, you need to implement a LookupListener. When the | |
| window opens, subscribe to the Lookup of the map window, while indicating that | |
| you want to be notified when a Point is published there. Whenever a new Point | |
| is made available, you can do something with it, for example, display it in | |
| the supporting window.</p> | |
| <p>Conversely, you might need the map to be updated when one or more | |
| of the supporting windows change. In that case, the map window must | |
| be subscribed to the Lookup of the currently selected window or to | |
| the specific supporting window that it is interested in. The supporting | |
| window needs to published objects of interest to the map window.</p> | |
| <p class="tips">The <a href="https://platform.netbeans.org/tutorials/nbm-quick-start.html">NetBeans Platform Quick Start</a> describes this mechanism in detail.</p> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="configure"></a>Configuring the Geospatial System</h2> | |
| <p>In this section, you learn how to change a variety of default | |
| features of the NetBeans Platform to optimize them for usage | |
| in a geospatial environment.</p> | |
| <p>All the configuration settings that follow are optional. Depending | |
| on your business needs, follow the instructions below to | |
| adapt your system to your needs.</p> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="fullscreen"></a>Starting Up in Full Screen Mode</h3> | |
| <p>In this section, we start the application in full screen mode. Full | |
| screen mode is supported by default by the NetBeans Platform. It can be | |
| invoked by the user via View | Full Screen or by pressing Alt-Shift-Enter. | |
| However, in geospatial systems, you typically need to start the application in full screen | |
| mode automatically, so that the user will not need to take this step | |
| over and over again manually.</p> | |
| <ol> | |
| <li><p>Create a new module in the application and name it "Initializer", | |
| with code name base "org.myatc.initializer". In this module, you will | |
| provide code for initializing the application as a whole.</p> | |
| </li> | |
| <li><p>Right-click the Initializer module and choose New | Other | Module Development | Installer. Click | |
| Next and Finish.</p> | |
| </li> | |
| <li><p>Right-click the Initializer module's Libraries node, choose | |
| Add Module Dependency, then set a dependency on the | |
| File System API, the UI Utilities API, and the Window System API.</p> | |
| </li> | |
| <li><p>Define the Installer class as follows:</p> | |
| <pre class="examplecode">import javax.swing.Action; | |
| import org.openide.filesystems.FileUtil; | |
| import org.openide.modules.ModuleInstall; | |
| import org.openide.windows.WindowManager; | |
| public class Installer extends ModuleInstall { | |
| @Override | |
| public void restored() { | |
| WindowManager.getDefault().invokeWhenUIReady(new Runnable() { | |
| @Override | |
| public void run() { | |
| FileUtil.getConfigObject("Actions/Window/org-netbeans-core-windows-actions-ToggleFullScreenAction.instance", Action.class).actionPerformed(null); | |
| } | |
| }); | |
| } | |
| }</pre> | |
| </li> | |
| </ol> | |
| <p>Run the application and notice that it starts in full screen mode.</p> | |
| </div> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="undocked"></a>Starting Up in Undocked Mode</h3> | |
| <p>In this section, we reconfigure the modes in the NetBeans Platform | |
| so that the windows, except the map window, open in undocked mode.</p> | |
| <ol> | |
| <li><p>Create a layer file.</p></li> | |
| <li><p>Expand the layer file and look for the mode file.</p></li> | |
| <li><p>Change "joined" to "separated".</p></li> | |
| <li><p>Look in the layer file and see that your overrides are registered.</p></li> | |
| </ol> | |
| <p>Run the application and notice that the windows open undocked.</p> | |
| </div> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="tabs"></a>Removing Tabs</h3> | |
| <p>In this section, we remove the tabs from all the | |
| windows in the application.</p> | |
| <ol> | |
| <li><p>Set dependencies on the "Look & Feel Customization Library" | |
| and "Tab Control".</p></li> | |
| <li><p>Create a class named <code>NoTabsTabDisplayerUI</code>, with this content</p> | |
| <pre class="�xamplecode">import java.awt.Dimension; | |
| import java.awt.Point; | |
| import java.awt.Polygon; | |
| import java.awt.Rectangle; | |
| import javax.swing.DefaultSingleSelectionModel; | |
| import javax.swing.JComponent; | |
| import javax.swing.SingleSelectionModel; | |
| import javax.swing.plaf.ComponentUI; | |
| import org.netbeans.swing.tabcontrol.TabDisplayer; | |
| import org.netbeans.swing.tabcontrol.TabDisplayerUI; | |
| public class NoTabsTabDisplayerUI extends TabDisplayerUI { | |
| public NoTabsTabDisplayerUI(TabDisplayer displayer) { | |
| super(displayer); | |
| } | |
| public static ComponentUI createUI(JComponent jc) { | |
| assert jc instanceof TabDisplayer; | |
| return new NoTabsTabDisplayerUI((TabDisplayer) jc); | |
| } | |
| private static final int[] PTS = new int[] { 0, 0, 0 }; | |
| @Override | |
| public Polygon getExactTabIndication(int i) { | |
| //Should never be called | |
| return new Polygon(PTS, PTS, PTS.length); | |
| } | |
| @Override | |
| public Polygon getInsertTabIndication(int i) { | |
| return new Polygon(PTS, PTS, PTS.length); | |
| } | |
| @Override | |
| public int tabForCoordinate(Point point) { | |
| return -1; | |
| } | |
| @Override | |
| public Rectangle getTabRect(int i, Rectangle rectangle) { | |
| return new Rectangle(0,0,0,0); | |
| } | |
| @Override | |
| protected SingleSelectionModel createSelectionModel() { | |
| return new DefaultSingleSelectionModel(); | |
| } | |
| public java.lang.String getCommandAtPoint(Point point) { | |
| return null; | |
| } | |
| @Override | |
| public int dropIndexOfPoint(Point point) { | |
| return -1; | |
| } | |
| @Override | |
| public void registerShortcuts(javax.swing.JComponent jComponent) { | |
| //do nothing | |
| } | |
| @Override | |
| public void unregisterShortcuts(javax.swing.JComponent jComponent) { | |
| //do nothing | |
| } | |
| @Override | |
| protected void requestAttention(int i) { | |
| //do nothing | |
| } | |
| @Override | |
| protected void cancelRequestAttention(int i) { | |
| //do nothing | |
| } | |
| @Override | |
| public Dimension getPreferredSize(javax.swing.JComponent c) { | |
| return new Dimension(0, 0); | |
| } | |
| @Override | |
| public Dimension getMinimumSize(javax.swing.JComponent c) { | |
| return new Dimension(0, 0); | |
| } | |
| @Override | |
| public Dimension getMaximumSize(javax.swing.JComponent c) { | |
| return new Dimension(0, 0); | |
| } | |
| }</pre> | |
| </li> | |
| <li><p>Add to the restored method in the installer:</p> | |
| <pre class="examplecode">UIManager.put("ViewTabDisplayerUI", "org.myatc.initializer.NoTabsTabDisplayerUI"); | |
| UIManager.put("EditorTabDisplayerUI", "org.myatc.initializer.NoTabsTabDisplayerUI");</pre> | |
| </li> | |
| </ol> | |
| <p>Run the application and notice that the tabs are removed.</p> | |
| </div> | |
| <p>Congratulations! At this stage, with very little coding, | |
| you have created the starting point of an air-traffic control system.</p> | |
| <p class="tips"> To continue learning about 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> |