blob: 6427a3e1e0824a9888c0f2a673a56ceb970d9970 [file] [log] [blame]
<!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, 2011, 2012, 2013, 2014 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 class="notes">Note:</b> This document uses NetBeans IDE 8.0 and NetBeans Platform 8.0. If you
are using an earlier version, see <a href="74/nbm-workflow.html">the previous version
of this document</a>.</p>
<p><b>Contents</b></p>
<img src="../images/articles/81/netbeans-stamp.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 8.0" title="Content on this page applies to NetBeans IDE 8.0">
<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 8.0 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 7 or above</td>
</tr>
</tbody>
</table>
<p class="tips">For troubleshooting purposes, you are welcome to download the <a href="http://java.net/projects/nb-api-samples/sources/api-samples/show/versions/8.0/tutorials/PredictionSystem">completed tutorial source code</a>.</p>
<!-- ===================================================================================== -->
<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 &gt; 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&amp;subject=Feedback:%20NetBeans%20Platform%20Workflow%20Tutorial%208.0">
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>