<!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>Tutorial da biblioteca visual do NetBeans para aplicativos Java</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 http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <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>Tutorial da biblioteca visual do NetBeans para aplicativos Java</h1>

<p>Neste tutorial, voc&ecirc; aprender&aacute; como utilizar os recursos principais fornecidos pela <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-api-visual/overview-summary.html">API Visual Library do NetBeans</a>.
   
     <p><b>Conte&uacute;do</b></p>
   
   <p><img  src="../images/articles/69/netbeans-stamp7-8-9.png" class="stamp" width="114" height="114" alt="O conte&uacute;do desta p&aacute;gina se aplica ao NetBeans IDE 6.5, 6.7, 6.8" title="O conte&uacute;do desta p&aacute;gina se aplica ao NetBeans IDE 6.5, 6.7, 6.8" /></p>
      <ul class="toc">
<li><a href="#getting-started">Configurando o aplicativo</a>
<li><a href="#add">Adicionando bibliotecas </a>
<li><a href="#widget">Criando widgets</a>
<li><a href="#action">Ativando a&ccedil;&otilde;es</a>
       </ul>
         
<p><b>Para seguir este tutorial, os softwares e recursos listados na tabela seguinte s&atilde;o necess&aacute;rios.</b></p>

    <table>
        <tbody>
            <tr>
                <th class="tblheader" scope="col">Software ou recurso</th>
                <th class="tblheader" scope="col">Vers&atilde;o necess&aacute;ria</th>
            </tr> 
            <tr>
                <td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td>
                <td class="tbltd1">vers&atilde;o 6.7 ou superior</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">Vers&atilde;o 6 ou<br/>vers&atilde;o 5</td>
            </tr>
        </tbody>
    </table>

  <p>Al&eacute;m disso, 3 &iacute;cones ser&atilde;o utilizados no tutorial. &Eacute; poss&iacute;vel clicar com o bot&atilde;o direito do mouse neles e salv&aacute;-los localmente, em seguida, copie-os para a localiza&ccedil;&atilde;o do aplicativo depois de criar o aplicativo mais tarde neste tutorial. Aqui est&atilde;o os 3 &iacute;cones:
  
   <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>Configurando o aplicativo</h2>

<p>Nesta se&ccedil;&atilde;o, utilizamos o assistente para criar um aplicativo Java.


<ol>
    <li>Escolha Arquivo &gt; Novo projeto (Ctrl-Shift-N). Em Categorias, selecione Java. Em Projetos, selecione Aplicativo Java. Clique em Pr&oacute;ximo.</li>
    <li>No painel Nome e localiza&ccedil;&atilde;o, digite <tt>VisLibDemo</tt> no campo Nome do projeto:
    <p><p><img border="1" src="../images/tutorials/vislib/vislib-java-1.png"/>
    <p>Clique em Terminar.</li>
</ol>

<p>O IDE cria o projeto <tt>VisLibDemo</tt>. Adicione as tr&ecirc;s imagens acima ao pacote principal. O seguinte dever&aacute; ser exibido:
<p><img border="1" src="../images/tutorials/vislib/vislib-java-2.png"/>



<p><h2><a name="add"></a>Adicionando bibliotecas</h2>

<p>Nesta se&ccedil;&atilde;o, adicionamos duas bibliotecas necess&aacute;rias para trabalhar com a Biblioteca visual.

<ol>
    <li>Clique com o bot&atilde;o direito do mouse no n&oacute; Bibliotecas e escolha &quot;Adicionar JAR/pasta&quot;.</li>
    <li>V&aacute; at&eacute; o diret&oacute;rio de instala&ccedil;&atilde;o do NetBeans IDE.</li>
    <li>Em <tt>platform9/lib</tt>, escolha <tt>org-openide-util.jar</tt>.</li>
    <li>Em <tt>platform9/modules</tt>, escolha <tt>org-netbeans-api-visual.jar</tt>.</li>
</ol>

<p>Agora voc&ecirc; tem os dois &uacute;nicos JARs necess&aacute;rios. O seguinte dever&aacute; ser exibido:
<p><img border="1" src="../images/tutorials/vislib/vislib-java-3.png"/>

<p><h2><a name="container"></a>Criando o cont&ecirc;iner</h2>

<p>Nesta se&ccedil;&atilde;o, criamos o cont&ecirc;iner que manter&aacute; o <tt>Scene</tt> da Biblioteca visual.

<ol>
    <li>Defina <tt>Main.java</tt> da seguinte forma:

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

    <b>//Create the JFrame:</b>
    public static void main(String[] args) {
        JFrame frame = new JFrame(&quot;Graph test&quot;);
        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>Execute o aplicativo. Voc&ecirc; deveria ver um JFrame simples:

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

     </li>
</ol>

<p>Agora que tem um <tt>JScrollPane</tt>, voc&ecirc; est&aacute; pronto para criar um cen&aacute;rio!

<p><h2><a name="widget"></a>Criando widgets</h2>

<p>Nesta se&ccedil;&atilde;o, criamos uma classe separada contendo nosso cen&aacute;rio. Em seguida, vinculamos ao nosso <tt>JPanel</tt>.

<ol>
    <li>Crie uma nova classe chamada <tt>GraphSceneImpl.java</tt>.
    <li>Deixe-a estender GraphScene&lt;String, String&gt;.
    <li>Utilize a l&acirc;mpada ao lado do IDE para adicionar instru&ccedil;&otilde;es de importa&ccedil;&atilde;o e m&eacute;todos abstratos. O seguinte dever&aacute; ser exibido:

<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(&quot;Ainda n&atilde;o suportado.&quot;);
    }

    @Override
    protected Widget attachEdgeWidget(String arg0) {
        throw new UnsupportedOperationException(&quot;Ainda n&atilde;o suportado.&quot;);
    }

    @Override
    protected void attachEdgeSourceAnchor(String arg0, String arg1, String arg2) {
        throw new UnsupportedOperationException(&quot;Ainda n&atilde;o suportado.&quot;);
    }

    @Override
    protected void attachEdgeTargetAnchor(String arg0, String arg1, String arg2) {
        throw new UnsupportedOperationException(&quot;Ainda n&atilde;o suportado.&quot;);
    }

}
</pre>
    </li>

    <li>Utilizaremos tr&ecirc;s <tt>LayerWidgets</tt>, que s&atilde;o como <tt>JGlassPanes</tt> no Swing. Declare-os na parte superior da classe:
<pre class=examplecode>
private LayerWidget mainLayer;
private LayerWidget connectionLayer;
private LayerWidget interactionLayer;
</pre>
     </li>
     <li>Crie um construtor, inicialize os <tt>LayerWidgets</tt> e os adicione ao <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>Depois, defina o que acontecer&aacute; quando um novo widget for criado:

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

<p class="tips"> O m&eacute;todo acima &eacute; disparado sempre que <tt>addNode</tt> for chamado no cen&aacute;rio.

<p><li>No final do construtor, dispare o m&eacute;todo acima quatro vezes:

<pre class=examplecode>
Widget w1 = addNode(&quot;1. Martelo&quot;);
w1.setPreferredLocation(new Point(10, 100));
Widget w2 = addNode(&quot;2. Serra&quot;);
w2.setPreferredLocation(new Point(100, 250));
Widget w3 = addNode(&quot;Prego&quot;);
w3.setPreferredLocation(new Point(250, 250));
Widget w4 = addNode(&quot;Parafuso&quot;);
w4.setPreferredLocation(new Point(250, 350));
</pre>

<p>Acima, voc&ecirc; criou quatro widgets, aprovou uma string e definiu a posi&ccedil;&atilde;o do widget. Agora, o m&eacute;todo <tt>attachNodeWidget</tt> definido na etapa anterior &eacute; disparado. O par&acirc;metro <tt>arg</tt> no <tt>attachNodeWidget</tt> &eacute; a string aprovada para <tt>addNode</tt>. Portanto, a string definir&aacute; o r&oacute;tulo do widget. Em seguida, o widget &eacute; adicionado a <tt>mainLayer</tt>.

<li>De volta na classe <tt>Main.java</tt>, adicione as linhas em negrito ao m&eacute;todo <tt>initComponents</tt>:

<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>Execute o aplicativo. Voc&ecirc; deveria ver o seguinte:

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

</ol>

<p>Agora que h&aacute; um cen&aacute;rio com alguns widgets, podemos come&ccedil;ar a integrar algumas a&ccedil;&otilde;es!

<p><h2><a name="action"></a>Ativando a&ccedil;&otilde;es</h2>

<p>Nesta se&ccedil;&atilde;o, ativamos a&ccedil;&otilde;es nos widgets criados anteriormente.

<ol>
    <li>Altere <tt>attachNodeWidget</tt> adicionando as linhas em negrito abaixo:

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

<li>Execute o aplicativo. Arraste um widget e observe que os marcadores de alinhamento aparecem para ajudar o usu&aacute;rio a posicion&aacute;-lo em rela&ccedil;&atilde;o aos outros widgets:

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

    <li>Altere a classe <tt>GraphSceneImpl</tt> adicionando a linha abaixo ao final do construtor:

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

<li>Execute o aplicativo. Role o bot&atilde;o central do mouse ou fa&ccedil;a o que o seu sistema operacional requer para efetuar zoom e observe que todo o cen&aacute;rio diminui/aumenta de tamanho.

 <li>Adicione um <tt>ConnectProvider</tt> personalizado ao final de <tt>GraphSceneImpl</tt>:

<pre class=examplecode>
private class MyConnectProvider implements ConnectProvider {

    public boolean isSourceWidget(Widget source) {
        return source instanceof IconNodeWidget &amp;&amp; source != null? true : false;
    }

    public ConnectorState isTargetWidget(Widget src, Widget trg) {
        return src != trg &amp;&amp; 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>Vincule o <tt>ConnectProvider</tt> personalizado ao widget da seguinte forma:

<pre class=examplecode>
@Override
protected Widget attachNodeWidget(String arg0) {
    IconNodeWidget widget = new IconNodeWidget(this);
    if (arg0.startsWith(&quot;1&quot;)) {
        widget.setImage(ImageUtilities.loadImage(&quot;vislibdemo/red.gif&quot;));
    } else if (arg0.startsWith(&quot;2&quot;)) {
        widget.setImage(ImageUtilities.loadImage(&quot;vislibdemo/green.gif&quot;));
    } else {
        widget.setImage(ImageUtilities.loadImage(&quot;vislibdemo/blue.gif&quot;));
    }
    <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>Execute o aplicativo, selecione um widget, mantenha pressionada a tecla Ctrl e arraste o mouse at&eacute; outro widget. Assim, &eacute; poss&iacute;vel conectar os widgets uns aos outros da seguinte forma:

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

</ol>

<p>Agora que j&aacute; tem uma ideia dos recursos que a API Visual Library oferece, consulte a se&ccedil;&atilde;o &quot;APIs NetBeans para visualiza&ccedil;&atilde;o de dados&quot; na <a href="https://netbeans.org/kb/trails/platform_pt_BR.html">Trilha do aprendizado da plataforma NetBeans</a>.

    </body>
</html>
