<!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>
<!-- -*- xhtml -*- -->
<title>NetBeans Visual Library Tutorial for Java Applications</title>
  <link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"/>
  <meta name="AUDIENCE" content="NBUSER"/>
  <meta name="TYPE" content="ARTICLE"/>
  <meta name="EXPIRES" content="N"/>
  <meta name="developer" content="geertjan.wielenga@sun.com"/>
  <meta name="indexed" content="y"/>
  <meta name="description"
 content="A walk-through of the basic features of the Visual Library API."/>
         <!--      Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -->
        <!--     Use is subject to license terms.-->
</head>

<body>

<h1>NetBeans Visual Library Tutorial for Java Applications</h1>

<p>In this tutorial, you will learn how to use the main
 features provided by the <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-api-visual/overview-summary.html">NetBeans Visual Library API</a>.
</p>

     <p><b>Contents</b></p>
   
   <p><img  src="../images/articles/69/netbeans-stamp7-8-9.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 6.5, 6.7, 6.8" title="Content on this page applies to NetBeans IDE 6.5, 6.7, 6.8"/></p>
      <ul class="toc">
<li><a href="#getting-started">Setting Up the Application</a></li>
<li><a href="#add">Adding the Libraries</a></li>
<li><a href="#widget">Creating the Widgets</a></li>
<li><a href="#action">Enabling the Actions</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 6.7 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<br/>version 5</td>
            </tr>
        </tbody>
    </table>

  <p>Also, you will use 3 icons in the tutorial. You can right-click
   them here and save them locally, then copy them to the application's
   location, after you create the application later in this tutorial. Here are
   the 3 icons:</p>
  
   <p><img alt=""  src="../images/tutorials/vislib/red.gif"/>
       <img alt=""  src="../images/tutorials/vislib/blue.gif"/>
       <img alt=""  src="../images/tutorials/vislib/green.gif"/></p>

<!-- ===================================================================================== -->

<h2><a name="set"></a>Setting Up the Application</h2>

<p>In this section, we use a wizard to create a Java application.</p>

<ol>
    <li>Choose File &gt; New Project (Ctrl+Shift+N).
        Under Categories, select Java.
        Under Projects, select Java Application. Click Next.</li>
    <li><p>In the Name and Location panel, type <tt>VisLibDemo</tt> in
    the Project Name field:</p>
        <p><img alt="" style="border: 1px solid" src="../images/tutorials/vislib/vislib-java-1.png"/></p>
    <p>Click Finish.</p></li>
</ol>

<p>The IDE creates the <tt>VisLibDemo</tt> project.
 Add the three images above to the main package. You
 should now see this:</p>

<p><img alt="" style="border: 1px solid" src="../images/tutorials/vislib/vislib-java-2.png"/></p>

<h2><a name="add"></a>Adding the Libraries</h2>

<p>In this section, we add the two libraries you need to work
 with the Visual Library.</p>

<ol>
    <li>Right-click the Libraries node and choose "Add JAR/Folder".</li>
    <li>Browse to the installation directory of NetBeans IDE.</li>
    <li>In <tt>platform9/lib</tt>, choose <tt>org-openide-util.jar</tt>.</li>
    <li>In <tt>platform9/modules</tt>, choose <tt>org-netbeans-api-visual.jar</tt>.</li>
</ol>

<p>You now have the only two JARs you will need. You should
 now see this:</p>

<p><img alt="" style="border: 1px solid" src="../images/tutorials/vislib/vislib-java-3.png"/></p>

<h2><a name="container"></a>Creating the Container</h2>

<p>In this section, we create the container
 that will hold the <tt>Scene</tt> from the
 Visual Library.</p>

<ol>
    <li>Define <tt>Main.java</tt> as follows:

<pre class=examplecode>
public class Main  extends JPanel {

    <b>//Create the JFrame:</b>
    public static void main(String[] args) {
        JFrame frame = new JFrame("Graph test");
        frame.setMinimumSize(new Dimension(500, 400));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(new Main());
        frame.pack();
        frame.setVisible(true);
    }

    public Main() {
        initComponents();
    }

    private void initComponents() {
        <b>//Set the layout:</b>
        setLayout(new BorderLayout());
        <b>//Create a JScrollPane:</b>
        JScrollPane scrollPane = new JScrollPane();
        <b>//Add the JScrollPane to the JPanel:</b>
        add(scrollPane, BorderLayout.CENTER);
    }

}
</pre>

    </li>

    <li>Run the application and you should see a simple
     JFrame:

     <p><img alt="" style="border: 1px solid" src="../images/tutorials/vislib/vislib-java-4.png"/></p>

     </li>
</ol>

<p>Now that you have a <tt>JScrollPane</tt>, you're
 ready to create a scene!</p>

<h2><a name="widget"></a>Creating the Widgets</h2>

<p>In this section, we create a separate
 class containing our scene. We then
 hook it into our <tt>JPanel</tt>.</p>

<ol>
    <li>Create a new class
     called <tt>GraphSceneImpl.java</tt>.</li>
    <li>Let it extend GraphScene&lt;String, String&gt;.</li>
    <li>Use the lightbulb at the side of the IDE
     to add import statements and abstract
     methods. You should now see this:

<pre class=examplecode>
package vislibdemo;

import org.netbeans.api.visual.graph.GraphScene;
import org.netbeans.api.visual.widget.Widget;

public class GraphSceneImpl extends GraphScene&lt;String, String&gt; {

    @Override
    protected Widget attachNodeWidget(String arg0) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    protected Widget attachEdgeWidget(String arg0) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    protected void attachEdgeSourceAnchor(String arg0, String arg1, String arg2) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    protected void attachEdgeTargetAnchor(String arg0, String arg1, String arg2) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}
</pre>
    </li>

    <li>We'll be using three <tt>LayerWidgets</tt>, which are
     like <tt>JGlassPanes</tt> in Swing. Declare them at the top
     of the class:
<pre class=examplecode>
private LayerWidget mainLayer;
private LayerWidget connectionLayer;
private LayerWidget interactionLayer;
</pre>
     </li>
     <li>Create a constructor, initialize your <tt>LayerWidgets</tt>
      and add them to the <tt>Scene</tt>:

<pre class=examplecode>
public GraphSceneImpl() {
    mainLayer = new LayerWidget(this);
    connectionLayer = new LayerWidget(this);
    interactionLayer = new LayerWidget(this);
    addChild(mainLayer);
    addChild(connectionLayer);
    addChild(interactionLayer);
}
</pre></li>

<li>Next, define what will happen when a new Widget
 is created:

<pre class=examplecode>@Override
protected Widget attachNodeWidget(String arg) {
    IconNodeWidget widget = new IconNodeWidget(this);
    if (arg.startsWith("1")) {
        widget.setImage(ImageUtilities.loadImage("vislibdemo/red.gif"));
    } else if (arg.startsWith("2")) {
        widget.setImage(ImageUtilities.loadImage("vislibdemo/green.gif"));
    } else {
        widget.setImage(ImageUtilities.loadImage("vislibdemo/blue.gif"));
    }
    widget.setLabel(arg);
    mainLayer.addChild(widget);
    return widget;
}</pre>

<p class="tips"> The above is triggered whenever
 <tt>addNode</tt> is called on the scene.</p></li>

<li>At the end of the constructor, trigger the
 method above 4 times:

<pre class=examplecode>
Widget w1 = addNode("1. Hammer");
w1.setPreferredLocation(new Point(10, 100));
Widget w2 = addNode("2. Saw");
w2.setPreferredLocation(new Point(100, 250));
Widget w3 = addNode("Nail");
w3.setPreferredLocation(new Point(250, 250));
Widget w4 = addNode("Bolt");
w4.setPreferredLocation(new Point(250, 350));
</pre>

<p>Above, you have created four widgets, you
 have passed in a string, and you have set
 the widget's position. Now, the <tt>attachNodeWidget</tt>
 method is triggered, which you defined in
 the previous step. The <tt>arg</tt> parameter
 in the <tt>attachNodeWidget</tt> is the string
 you passed to <tt>addNode</tt>. Therefore,
 the string will set the label of the widget. Then
 the widget is added to the <tt>mainLayer</tt>.</p></li>

<li>Back in the <tt>Main.java</tt> class, add the
 lines in bold to the <tt>initComponents</tt> method:

<pre class=examplecode>
private void initComponents() {
    //Set the layout:
    setLayout(new BorderLayout());
    //Create a JScrollPane:
    JScrollPane scrollPane = new JScrollPane();
    //Add the JScrollPane to the JPanel:
    add(scrollPane, BorderLayout.CENTER);
    <b>//Create the GraphSceneImpl:
    GraphScene scene = new GraphSceneImpl();
    //Add it to the JScrollPane:
    scrollPane.setViewportView(scene.createView());
    //Add the SatellitView to the scene:
    add(scene.createSatelliteView(), BorderLayout.WEST);</b>
}
</pre></li>

<li>Run the application and you should see this:
    <p><img alt=""  style="border: 1px solid" src="../images/tutorials/vislib/vislib-java-5.png"/></p>
</li>

</ol>

<p>Now that you have a scene with some widgets,
 we can begin integrating some actions!</p>

<h2><a name="action"></a>Enabling the Actions</h2>

<p>In this section, we enable actions
 on the widgets we created previously.</p>

<ol>
    <li>Change the <tt>attachNodeWidget</tt> by
     adding the lines in bold below:

<pre class=examplecode>
@Override
protected Widget attachNodeWidget(String arg) {
    IconNodeWidget widget = new IconNodeWidget(this);
    if (arg.startsWith("1")) {
        widget.setImage(ImageUtilities.loadImage("vislibdemo/red.gif"));
    } else if (arg.startsWith("2")) {
        widget.setImage(ImageUtilities.loadImage("vislibdemo/green.gif"));
    } else {
        widget.setImage(ImageUtilities.loadImage("vislibdemo/blue.gif"));
    }
    <b>widget.getActions().addAction(
            ActionFactory.createAlignWithMoveAction(
            mainLayer, interactionLayer,
    ActionFactory.createDefaultAlignWithMoveDecorator()));</b>
    widget.setLabel(arg);
    mainLayer.addChild(widget);
    return widget;
}
</pre>
    </li>

<li>Run the application. Drag a widget around
 and notice that alignment markers appear
 that help the user position a widget in
 relation to other widgets.</li>

    <li>Change the
     <tt>GraphSceneImpl</tt> class by
     adding the line below to the
     end of the constructor:

<pre class=examplecode>
getActions().addAction(ActionFactory.createZoomAction());
</pre>
    </li>

<li>Run the application. Scroll the middle
 mousebutton, or do whatever your operating
 system requires for "zooming", and notice
 that the whole scene increases/decreases
 in size.</li>

</ol>

<p>Now that you have a basic idea
 of the features that the Visual Library API
 provides, see the section called
 "NetBeans APIs for Visualizing Data"
 on the <a href="https://netbeans.org/kb/trails/platform.html">NetBeans Platform Learning Trail</a>.
</p>
    </body>
</html>
