<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | |
"http://www.w3.org/TR/html4/loose.dtd"> | |
<html> | |
<head> | |
<!-- -*- xhtml -*- --> | |
<title>NetBeans Platform Workflow Tutorial</title> | |
<meta name="AUDIENCE" content="NBUSER"> | |
<meta name="TYPE" content="ARTICLE"> | |
<meta name="EXPIRES" content="N"> | |
<meta name="developer" content="gwielenga@netbeans.org"> | |
<meta name="indexed" content="y"> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
<meta name="description" | |
content="A guide describing how to create a workflow application on the NetBeans Platform."> | |
<link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"> | |
</head> | |
<!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. --> | |
<!-- Use is subject to license terms.--> | |
<body> | |
<h1><a name="top"></a>NetBeans Platform Workflow Tutorial</h1> | |
<p>In this tutorial, you are shown how to create a pluggable infrastructure | |
as the basis for a workflow application. In workflow | |
applications, the user is guided through a sequence of steps provided by multiple GUI | |
components, ending with a final product of some kind.</p> | |
<p>Here are two examples of workflow applications.</p> | |
<ul> | |
<li><p><b>EasyDoe Toolsuite.</b> A workflow created by IAV in Berlin, Germany, | |
for control units of calibration engines, using a | |
method called Design of Experiments. The workflow guides the | |
user through the whole process, starting at defining the task, | |
making a test plan, importing data, making a mathematical model | |
from the data, using the model in optimizations and calibrate | |
maps that are directly exported to the engine control units.</p> | |
<br> | |
<p><a href="https://netbeans.org/images_www/screenshots/platform/easyDoe.png"><img src="../images/tutorials/workflow/72/easyDoe_thumb.png" alt="Easy DOE"></a></p> | |
<br> | |
</li> | |
<li><p><b>Limits.</b> A reservoir engineering tool created by Object Reservoir, in Austin, Texas, | |
for shale gas and unconventional reservoirs. Limits uses readily available and | |
routinely collected pressure and rate data to determine feasible ranges of physical | |
reservoir and completion parameters in order to estimate the uncertainty in the | |
future performance of the well.</p> | |
<br> | |
<p><a href="https://netbeans.org/images_www/screenshots/platform/objectreservoir.jpg"><img src="../images/tutorials/workflow/72/objectreservoir_thumb.jpg" alt="Object Reservoir"></a></p> | |
<br> | |
</li> | |
</ul> | |
<p>In this tutorial, we imagine we're creating a prediction system consisting of three | |
steps, "specify", "diagnose", and "forecast". Each | |
step in the sequence is supported by a "canvas", which consists of multiple "windows". | |
The user switches from canvas to canvas via a control panel. Changes made by the | |
user to the size and position of windows in a canvas are automatically stored on disk and are automatically | |
available upon restarts of the application. | |
</p> | |
<p><b>Contents</b></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"> | |
<ul class="toc"> | |
<li><a href="#create-application">Creating the Application</a></li> | |
<li><a href="#create-canvas">Creating the Canvases</a></li> | |
<li><a href="#create-control">Creating the Controler Mechanism</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="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> | |
<!-- ===================================================================================== --> | |
<br> | |
<h2 class="tutorial"><a name="create-application"></a>Creating the Application</h2> | |
<p>In this section, you create a skeleton prediction system, consisting of the NetBeans Platform.</p> | |
<div class="indent"> | |
<ol> | |
<li>Choose File > New Project (Ctrl+Shift+N). Under Categories, select NetBeans Modules. | |
Under Projects, select NetBeans Platform Application: | |
<br><br> | |
<img src="../images/tutorials/javafx/72/new-app-1.png" alt="new project wizard"> | |
<br><br> | |
Click Next. | |
</li> | |
<li>In the Name and Location panel:<br><br> | |
<ul><li>In the Project Name field, type <tt>PredictionSystem</tt>.</li> | |
<li>In the Project Location field, change the value to any directory on your computer where | |
the application will be stored.</li></ul> | |
<img src="../images/tutorials/workflow/72/new-project.png" alt="new project wizard"> | |
<br><br> | |
<p>Click Finish. The IDE creates the <tt>PredictionSystem</tt> project:</p> | |
<br> | |
<img src="../images/tutorials/workflow/72/new-app.png" alt="created app"> | |
</li> | |
<li>Right-click the application and choose Run. The application starts up, showing | |
a default splash screen. Once the application has started, open some windows, | |
browse through the menu bar and toolbar, and generally investigate the | |
features that your application already has. | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-app-2.png" alt="running nb platform"> | |
<br> | |
</li> | |
</ol> | |
</div> | |
<p>You now have a basic application containing a lot of functionality. In the next section, we create the canvases.</p> | |
<!-- ===================================================================================== --> | |
<br> | |
<h2 class="tutorial"><a name="create-canvas"></a>Creating the Canvases</h2> | |
<p>In this section, you create support for the steps in the workflow, each of which consist of a canvas containing one or more windows.</p> | |
<div class="indent"> | |
<h3 class="tutorial"><a name="creating-modules"></a>Creating the Modular Structure</h3> | |
<p>In this section, you create a new module for each step in the sequence.</p> | |
<div class="indent"> | |
<ol> | |
<li>Right-click the application's Modules node and choose Add New: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-canvas-1.png" alt="canvas 1"> | |
<br><br> | |
Click Next. | |
</li> | |
<li>Set <tt>Specify</tt> as the project name and leave the other values | |
unchanged: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-canvas-2.png" alt="canvas 2"> | |
<br><br> | |
Click Next. | |
</li> | |
<li>Set <tt>org.prediction.specify</tt> as the module's code name base | |
and set <tt>Specify</tt> as the display name: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-canvas-3.png" alt="canvas 3"> | |
<br><br> | |
Click Finish. You now have your first custom module, named "Specify", for | |
the code relating to the specify step: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-canvas-4.png" alt="canvas 4"> | |
</li> | |
<li>Repeat the three steps above twice, to create modules for the steps "diagnose" and "forecast": | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-canvas-5.png" alt="canvas 5"> | |
</li> | |
</ol> | |
<p>You now have a modular structure on top of the NetBeans Platform. Each | |
module will provide the code for one step in the workflow.</p> | |
</div> | |
</div> | |
<div class="indent"> | |
<h3 class="tutorial"><a name="creating-windows"></a>Creating the Windows</h3> | |
<p>In this section, you create the windows that define the canvases.</p> | |
<div class="indent"> | |
<ol> | |
<li>Right-click the <tt>org.prediction.specify</tt> package and choose | |
New | Other | Module Development and then choose Window: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-window-1.png" alt="canvas 1"> | |
<br><br> | |
Click Next. | |
</li> | |
<li>Choose a window position, that is, the place in the application frame | |
where the window will be displayed, and set Open on Application Start | |
so that the window will open as soon as the application has started up: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-window-2.png" alt="canvas 2"> | |
<br><br> | |
Click Next. | |
</li> | |
<li>Set <tt>SpecifyOne</tt> (or another suitable name) as the class name prefix: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-window-3.png" alt="canvas 3"> | |
<br><br> | |
Click Finish. You now have your first window, named "SpecifyOneTopComponent", for | |
the code relating to one of the windows in the specify step: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-window-4.png" alt="canvas 4"> | |
</li> | |
<li><p>In the source code of the window, assign | |
the window to its role, as follows, by adding <tt>roles={"specify"}</tt> in | |
the <tt>@TopComponent.Registration</tt> annotation:</p> | |
<pre class="examplecode">@TopComponent.Registration(<b>roles={"specify"},</b> mode = "editor", openAtStartup = true)</pre> | |
</li> | |
<li>Repeat the four steps above several times, to create several windows | |
in each module, each window registered to the role for which you created the module. | |
Each canvas is defined by multiple windows, some | |
canvases will have more windows, while others have less. Dependending | |
on the needs of each canvas, create the required windows accordingly, | |
with appropriate names: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-window-5.png" alt="canvas 5"> | |
</li> | |
</ol> | |
</div> | |
</div> | |
<p>You now have three modules, each containing a | |
canvas defined by one or more windows. In the next section, we create a controler mechanism so that the | |
user can switch from canvas to canvas.</p> | |
<!-- ===================================================================================== --> | |
<br> | |
<h2 class="tutorial"><a name="create-control"></a>Creating the Controler Mechanism</h2> | |
<p>In this section, you create a controler mechanism for switching between roles.</p> | |
<div class="indent"> | |
<ol> | |
<li>As before, create a module in the application. Name it <tt>Control</tt>: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-control-1.png" alt="control 1"> | |
<br><br> | |
<p>Click Next.</p> | |
</li> | |
<li>Set <tt>org.prediction.control</tt> as the code name base: | |
<br><br> | |
<img src="../images/tutorials/workflow/72/new-control-2.png" alt="control 2"> | |
<br><br> | |
<p>Click Finish. You now have a Control module, together with the three canvas | |
modules you already had:</p> | |
<br> | |
<img src="../images/tutorials/workflow/72/new-control-3.png" alt="control 3"> | |
</li> | |
<li>In the Control module, right-click the Libraries node, and choose Add Module | |
Dependency. Set a new module dependency on the Module System API and the Window System API.</li> | |
<li>Create a new Java class named <tt>Installer</tt> in the package <tt>org.prediction.control</tt>. Define | |
it as follows and click the links for further information: | |
<pre class="examplecode">package org.prediction.control; | |
import <a href="http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/OnStart.html">org.openide.modules.OnStart</a>; | |
import org.openide.windows.WindowManager; | |
import org.openide.windows.WindowSystemEvent; | |
import <a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/WindowSystemListener.html">org.openide.windows.WindowSystemListener</a>; | |
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/OnStart.html">@OnStart</a> | |
public class Installer implements Runnable, <a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/WindowSystemListener.html">WindowSystemListener</a> { | |
@Override | |
public void run() { | |
WindowManager.getDefault().addWindowSystemListener(this); | |
} | |
@Override | |
public void beforeLoad(WindowSystemEvent wse) { | |
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/WindowManager.html#setRole(java.lang.String)">WindowManager.getDefault().setRole("specify")</a>; | |
WindowManager.getDefault().removeWindowSystemListener(this); | |
} | |
@Override | |
public void afterLoad(WindowSystemEvent wse) { | |
} | |
@Override | |
public void beforeSave(WindowSystemEvent wse) { | |
} | |
@Override | |
public void afterSave(WindowSystemEvent wse) { | |
} | |
}</pre></li> | |
<li>In each window, delete the <tt>@ActionID</tt>, <tt>@ActionReference</tt>, | |
and <tt>@TopComponent.OpenActionRegistration</tt> | |
annotations because, instead of menu items for opening individual windows, | |
you´re going to create a controler to open canvases, using one or more of the mechanisms described below.</li> | |
</ol> | |
</div> | |
<div class="indent"> | |
<div class="indent"> | |
<div class="indent"> | |
<div class="indent"> | |
<h3 class="tutorial"><a name="creating-a-menu-based-controler"></a>Creating a Menu Based Controler Mechanism</h3> | |
<p>In this section, you create new menu items to control switching between canvases.</p> | |
<p>In each canvas module, create an ActionListener such as the below | |
for switching between roles. The example below is for the | |
specify role, create the same class in the other two | |
modules, changing "specify" to "diagnose" and "forecast" for | |
the other modules. | |
</p> | |
<pre class="examplecode">package org.prediction.specify; | |
import java.awt.event.ActionEvent; | |
import java.awt.event.ActionListener; | |
import <a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionID.html">org.openide.awt.ActionID</a>; | |
import <a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionReference.html">org.openide.awt.ActionReference</a>; | |
import <a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionRegistration.html">org.openide.awt.ActionRegistration</a>; | |
import <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbBundle.Messages.html">org.openide.util.NbBundle.Messages</a>; | |
import org.openide.windows.WindowManager; | |
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionID.html">@ActionID</a>( | |
category = "Window", | |
id = "org.prediction.specify.SwitchToSpecifyRole") | |
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionRegistration.html">@ActionRegistration</a>( | |
displayName = "#CTL_SwitchToSpecifyRole") | |
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionReference.html">@ActionReference</a>( | |
path = "Menu/Window", | |
position = 250) | |
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbBundle.Messages.html">@Messages</a>("CTL_SwitchToSpecifyRole=Switch to Specify Role") | |
public final class SwitchToSpecifyRole implements ActionListener { | |
@Override | |
public void actionPerformed(ActionEvent e) { | |
<a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/WindowManager.html#setRole(java.lang.String)">WindowManager.getDefault().setRole("specify")</a>; | |
} | |
}</pre> | |
<p>You now have a controler mechanism, defined | |
by a set of actions, invoked from menu items in the Window menu, for switching between roles.</p> | |
<img src="../images/tutorials/workflow/72/new-canvas-6.png" alt="canvas"> | |
<br><br><p>You also | |
have an installer class which sets the initial role in the application.</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="indent"> | |
<div class="indent"> | |
<div class="indent"> | |
<div class="indent"> | |
<h3 class="tutorial"><a name="creating-a-window-based-controler"></a>Creating a Window Based Controler Mechanism</h3> | |
<p>In this section, you create a new window to control switching between canvases.</p> | |
<p>In the Control module, create a new <tt>TopComponent</tt>, with <tt>WorkflowControl</tt> as | |
the class name prefix. Add a dependency | |
on the File System API and define the constructor of the <tt>TopComponent</tt> | |
as follows. Also make sure that the "category" of each <tt>ActionListener</tt> | |
defined in the previous section is set to "Predict". | |
</p> | |
<pre class="examplecode">public WorkflowControlTopComponent() { | |
initComponents(); | |
setName(Bundle.CTL_WorkflowControlTopComponent()); | |
setToolTipText(Bundle.HINT_WorkflowControlTopComponent()); | |
setLayout(new FlowLayout(FlowLayout.LEFT, 14, 10)); | |
for (FileObject fo : FileUtil.getConfigFile("Actions/Predict").getChildren()) { | |
Action action = FileUtil.getConfigObject(fo.getPath(), Action.class); | |
JButton button = new JButton(action); | |
button.setPreferredSize(new Dimension(150,100)); | |
add(button); | |
} | |
}</pre> | |
<p>You now have a controler mechanism, defined | |
by a set of buttons in a TopComponent for switching between roles.</p> | |
<img src="../images/tutorials/workflow/72/new-control-4.png" alt="canvas"> | |
<br><br><p>You also | |
have an installer class which sets the initial role in the application.</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- ===================================================================================== --> | |
<p>The tutorial is complete. You have created a modular application on the | |
NetBeans Platform, providing the infrastructure for a workflow application.</p> | |
<br> | |
<div class="feedback-box"><a name="feedback"></a> | |
<a href="https://netbeans.org/about/contact_form.html?to=3&subject=Feedback:%20NetBeans%20Platform%20Workflow%20Tutorial%207.2"> | |
Send Us Your Feedback</a></div> | |
<br style="clear:both;" > | |
<!-- ======================================================================================== --> | |
<!-- <h2><a name="nextsteps"></a>See Also</h2> | |
<p>This concludes the NetBeans Plugin Quick Start. This document has described | |
how to create a plugin that adds a Google Search toolbar to the IDE. | |
For more information about creating and developing plugins, see the following resources: | |
<ul> | |
<li><a href="https://netbeans.org/kb/trails/platform.html">NetBeans Platform Learning Trail</a></li> | |
<li><a href="http://bits.netbeans.org/dev/javadoc/">NetBeans API Javadoc</a></li> | |
<li>NetBeans API classes used in this tutorial: | |
<ul> | |
<li><tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/HtmlBrowser.URLDisplayer.html">HtmlBrowser.URLDisplayer</a></tt> | |
<li><tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/actions/Presenter.Toolbar.html">Presenter.Toolbar</a></tt> | |
</ul> | |
</li> | |
</ul>--> | |
<!-- ======================================================================================== --> | |
</body> | |
</html> |