<!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.">
</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><b>Contents</b></p>
   
   <img  src="../images/articles/68/netbeans-stamp-65-67-68.gif" 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><a href="#add">Adding the Libraries</a>
<li><a href="#widget">Creating the Widgets</a>
<li><a href="#action">Enabling the Actions</a>
       </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.5 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><img src="../images/tutorials/vislib/red.gif"/>
    <img src="../images/tutorials/vislib/blue.gif"/>
    <img 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.


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

<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><img border="1" 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.

<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 border="1" src="../images/tutorials/vislib/vislib-java-4.png"/>

     </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>.

<ol>
    <li>Create a new class
     called <tt>GraphSceneImpl.java</tt>.
    <li>Let it extend GraphScene&lt;String, String&gt;.
    <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>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>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>.

<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>Run the application and you should see this:

<p><img border="1" src="../images/tutorials/vislib/vislib-java-5.png"/>

</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.

<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:

 <p><p><img border="1" src="../images/tutorials/vislib/vislib-java-7.png"/>

    <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>Add a custom <tt>ConnectProvider</tt>
  to the end of the <tt>GraphSceneImpl</tt>:

<pre class=examplecode>
private class MyConnectProvider implements ConnectProvider {

    public boolean isSourceWidget(Widget source) {
        return source instanceof IconNodeWidget && source != null? true : false;
    }

    public ConnectorState isTargetWidget(Widget src, Widget trg) {
        return src != trg && trg instanceof IconNodeWidget ? ConnectorState.ACCEPT : ConnectorState.REJECT;
    }

    public boolean hasCustomTargetWidgetResolver(Scene arg0) {
        return false;
    }

    public Widget resolveTargetWidget(Scene arg0, Point arg1) {
        return null;
    }

    public void createConnection(Widget source, Widget target) {
        ConnectionWidget conn = new ConnectionWidget(GraphSceneImpl.this);
        conn.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
        conn.setTargetAnchor(AnchorFactory.createRectangularAnchor(target));
        conn.setSourceAnchor(AnchorFactory.createRectangularAnchor(source));
        connectionLayer.addChild(conn);
    }

}
</pre>

<p>Hook the custom <tt>ConnectProvider</tt>
 into the widget as follows:

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

<li>Run the application, select a widget,
 hold down the Ctrl key, and then drag
 the mouse to another widget. You should
 then be able to connect widgets to
 each other, like this:

<p><p><img border="1" src="../images/tutorials/vislib/vislib-java-6.png"/>

</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>.

    </body>
</html>
