<!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 Standard Java SE Applications in NetBeans IDE 7.1</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@oracle.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 Standard Java SE 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/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><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 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>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 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.</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 style="border:1px black solid" src="../../images/tutorials/vislib/71/vislib-java-1.png"/></p>
    <p>Click Finish. The IDE creates the <tt>VisLibDemo</tt> project.</li>
    <li>Add the three images above to the main package. You
 should now see this:</p>
<p><img src="../../images/tutorials/vislib/71/vislib-java-2.png"/></p>
</li>
</ol>

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

<p>In this section, we add the NetBeans Platform JARs you need, to be able 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>platform/lib</tt>, choose <tt>org-openide-util.jar</tt>.</li>
    <li>In <tt>platform/lib</tt>, choose <tt>org-openide-util-lookup.jar</tt>.</li>
    <li>In <tt>platform/modules</tt>, choose <tt>org-netbeans-api-visual.jar</tt>.</li>
</ol>

<p>You now have the only NetBeans Platform JARs you will need:</p>
<p><img src="../../images/tutorials/vislib/71/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>VisLibDemo.java</tt> to contain a <tt>JFrame</tt> with a <tt>JScrollPane</tt> as follows:

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

    public VisLibDemo() {
        initComponents();
    }

    private void initComponents() {
        setLayout(new BorderLayout());
        JScrollPane scrollPane = new JScrollPane();
        add(scrollPane, BorderLayout.CENTER);
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setMinimumSize(new Dimension(500, 400));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setContentPane(new VisLibDemo());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
    
}</pre>

    </li>

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

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

     </li>
</ol>

<p>Now that you have a <tt>JFrame</tt>, a <tt>JPanel</tt>, and 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 style="border:1px black solid" 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 style="border:1px black solid" 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 style="border:1px black solid" 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>.</p>

    
        <div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback:%20Visual%20Library%207.1%20Tutorial">Send Us Your Feedback</a></div>
        <!-- ======================================================================================== -->

        <h2><a name="nextsteps"></a>Next Steps</h2>

        <p>For more information about using NetBeans APIs, see the following resources: </p>
        <ul>
            <li><a href="https://netbeans.org/kb/trails/platform.html">Other Related Tutorials</a></li>
            <li><a href="https://netbeans.org/download/dev/javadoc/">NetBeans API Javadoc</a></li>
        </ul>
    </body>
</html>
