blob: a0ec39a97654061124a374e4de444fc2f8310257 [file] [log] [blame]
<!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>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- -*- xhtml -*- -->
<title>Tutorial Visual Library do NetBeans para NetBeans Platform 6.0</title>
<link rel="stylesheet" type="text/css" href="../../../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) 2006 Sun Microsystems, Inc. All rights reserved. -->
<!-- Use is subject to license terms.-->
</head>
<body>
<h1>Tutorial Visual Library do NetBeans</h1>
<p>Neste tutorial, voc&ecirc; aprender&aacute; como usar os recursos principais fornecidos pela API Visual Library do NetBeans. A API Visual Library &eacute; uma API de visualiza&ccedil;&atilde;o, &uacute;til no contexto de, por exemplo, modelagem e gr&aacute;ficos.
</p><p><b>Conte&uacute;do</b></p>
<img src="../../images/articles/60/netbeans-stamp60-61.gif" class="stamp" width="114" height="114" alt="O conte&uacute;do desta p&aacute;gina se aplica ao IDE NetBeans 6.1 " title="O conte&uacute;do desta p&aacute;gina se aplica ao IDE NetBeans 6.1"> </p>
<ul class="toc">
<li><a href="#getting-started">Configurando o m&oacute;dulo</a>
</li><li><a href="#creating-the-scene">Criando a cena</a>
</li><li><a href="#creating-a-palette">Criando uma paleta de componentes da cena</a>
</li><li><a href="#adding-a-layer-widget">Adicionando um LayerWidget</a>
</li><li><a href="#adding-an-icon-widget">Adicionando um IconNodeWidget por meio da funcionalidade arrastar e soltar</a>
</li><li><a href="#adding-to-scene">Adicionando funcionalidade &agrave; cena</a>
</li><li><a href="#adding-to-widget">Adicionando funcionalidade ao IconNodeWidget</a>
</li></ul>
<p><b>Para seguir este tutorial, voc&ecirc; preciso dos softwares e recursos listados na tabela seguinte.</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">NetBeans IDE</td>
<td class="tbltd1">vers&atilde;o <a href="http://download.netbeans.org/netbeans/6.1/final/">vers&atilde;o 6.1</a> ou<br>
vers&atilde;o 6.0</td>
</tr>
<tr>
<td class="tbltd1">Java Developer Kit (JDK)</td>
<td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">vers&atilde;o 6</a> ou<br>
vers&atilde;o 5</td>
</tr>
</tbody>
</table>
<p class="tips">Opcionalmente, para fins de solu&ccedil;&atilde;o de problemas, voc&ecirc; pode <a href="http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=2701">baixar a amostra completa</a> e inspecionar os c&oacute;digos-fonte.
</p><p>Al&eacute;m disso, voc&ecirc; usar&aacute; 3 &iacute;cones no tutorial. Voc&ecirc; pode 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 projeto do m&oacute;dulo, depois de criar o projeto do m&oacute;dulo mias tarde neste tutorial. Aqui est&atilde;o os 3 &iacute;cones:
</p><p><img border="1" src="../../images/tutorials/vislib/image1.png"/>
<img border="1" src="../../images/tutorials/vislib/image2.png"/>
<img border="1" src="../../images/tutorials/vislib/image3.png"/>
</p><p>Todas as informa&ccedil;&otilde;es que voc&ecirc; precisa saber para trabalhar com a API do Visual Library s&atilde;o coletadas nestes dois locais:
</p><ul>
<li><a href="http://graph.netbeans.org/">P&aacute;gina do projeto do Visual Library</a>
</li><li><a href="http://graph.netbeans.org/documentation.html">Visual Library 2.0 - Documenta&ccedil;&atilde;o</a>
</li></ul>
<p>Al&eacute;m disso, consulte o <a href="http://www.javalobby.org/eps/netbeans_visual_library/">Screencast sobre o Visual Library de Roman Strobl</a> em Javalobby.
<!-- ===================================================================================== -->
</p><p></p><h2><a name="getting-started"></a>Configurando o m&oacute;dulo</h2>
<p>Nesta se&ccedil;&atilde;o, usamos assistentes para criar um projeto do m&oacute;dulo e um componente de janela personalizado.
</p><ol>
<li>Escolha Arquivo &gt; Novo projeto. No assistente para Novo projeto. escolha M&oacute;dulos do NetBeans em Categorias e M&oacute;dulos em Projetos. Clique em Pr&oacute;ximo. Digite <tt>ShapeSample</tt> em Nome do projeto e defina Localiza&ccedil;&atilde;o do projeto como uma pasta apropriada no disco. Se n&atilde;o estiverem selecionadas, selecione M&oacute;dulo independente e Definir como projeto principal. Clique em Pr&oacute;ximo.
<p></p></li><li>Digite <tt>org.netbeans.shapesample</tt> em Nome de base de c&oacute;digo e <tt>Amostra de forma</tt> em Nome de exibi&ccedil;&atilde;o do m&oacute;dulo. Clique em Terminar.
<p></p></li><li>Clique com o bot&atilde;o direito do mouse no projeto, escolha Propriedades, clique em Bibliotecas na caixa de di&aacute;logo Propriedades do projeto e declare uma depend&ecirc;ncia nas seguintes APIs:
<p></p><ul>
<li>API do Visual Library
</li><li>API de utilit&aacute;rios
</li></ul>
<p>Clique em OK.
</p><p></p></li><li>Clique com o bot&atilde;o direito do mouse no projeto do m&oacute;dulo, escolha Novo &gt; Arquivo/pasta e escolha Componente da janela na categoria Desenvolvimento de m&oacute;dulo do NetBeans. Clique em Pr&oacute;ximo. Escolha <tt>editor</tt> na lista suspensa e selecione Abrir ao iniciar aplicativo. Clique em Pr&oacute;ximo.
<p></p></li><li>Digite <tt>Shape</tt> no Prefixo do nome da classe. Opcionalmente, adicione um &iacute;cone com uma dimens&atilde;o de 16x16 pixels. Clique em Terminar.</p>
<p>V&aacute;rios arquivos s&atilde;o gerados, um deles &eacute; <tt>ShapeTopComponent</tt>. Abra este arquivo no modo Design. O seguinte dever&aacute; ser exibido:
</p><p><img border="1" src="../../images/tutorials/vislib/shapetopcomponent.png"/>
</p><p></p></li><li>Clique com o bot&atilde;o direito do mouse em TopComponent no modo Design, escolha Definir layout e selecione BorderLayout.
</li></ol>
<p></p><h2><a name="creating-the-scene"></a>Criando a cena</h2>
<p>A programa&ccedil;&atilde;o com a API do Visual Library &eacute; semelhante &agrave; programa&ccedil;&atilde;o em Swing. Voc&ecirc; constr&oacute;i e modifica uma &aacute;rvore de elementos visuais que s&atilde;o chamados de &quot;widgets&quot;. A raiz da &aacute;rvore &eacute; representada por uma classe Cena que mant&eacute;m todos os dados visuais da cena. A cena &eacute; um widget. Voc&ecirc; tem que criar uma visualiza&ccedil;&atilde;o de cena, que &eacute; um JComponent. Em seguida, voc&ecirc; deve adicionar o JComponent a um JScrollPane.
</p><p>Nesta se&ccedil;&atilde;o, adicionamos um JScrollPane ao nosso TopComponent. Em seguida, crie uma nova cena. Em seguida, passamos a visualiza&ccedil;&atilde;o Cena para o TopComponent, de forma que ele possa ser exibido no JScrollPane do TopComponent. Em seguida, instalamos o projeto do m&oacute;dulo e exibimos nossa primeira cena.</p>
<ol>
<li>Use a paleta (Ctrl-Shift-8) para soltar um <tt>JScrollPane</tt> no TopComponent. No Inspetor, clique com o bot&atilde;o direito do mouse em <tt>JScrollPane</tt>, escolha Alterar nome da vari&aacute;vel e digite <tt>shapePane</tt>.
<p></p></li><li>No pacote <tt>org.netbeans.shapesample</tt>, crie uma classe Java chamada <tt>GraphSceneImpl</tt>. Deixe a classe estender <tt>GraphScene</tt>.</p>
<p>Um sublinhado de erro vermelho e uma l&acirc;mpada aparecem. Deixe o IDE gerar a instru&ccedil;&atilde;o de importa&ccedil;&atilde;o.
</p><p>Um sublinhado de erro vermelho e uma l&acirc;mpada aparecem novamente. Deixe o IDE gerar os m&eacute;todos abstratos da classe.
</p><p></p></li><li>Crie uma implementa&ccedil;&atilde;o fict&iacute;cia da classe, adicionando identificadores significativos e configurando <tt>leftnull</tt> para ser retornado quando necess&aacute;rio, de forma que todos os requisitos da classe sejam atendidos:
<pre class="examplecode">public class GraphSceneImpl extends GraphScene {
public GraphSceneImpl() {
}
protected Widget attachNodeWidget(Object node) {
return null;
}
protected Widget attachEdgeWidget(Object edge) {
return null;
}
protected void attachEdgeSourceAnchor(Object edge, Object oldSourceNode, Object newSourceNode) {
}
protected void attachEdgeTargetAnchor(Object edge, Object oldTargetNode, Object newTargetNode) {
}
}</pre>
<p></p></li><li>Agora use o construtor do TopComponent para manter uma inst&acirc;ncia da classe <tt>GraphSceneImpl</tt>. Para fazer isso, adicione o seguinte no fim do construtor da classe <tt>ShapeTopComponent</tt>:
<pre class="examplecode">GraphSceneImpl scene = new GraphSceneImpl();
myView = scene.createView();
shapePane.setViewportView(myView);
add(scene.createSatelliteView(), BorderLayout.WEST);</pre>
<p>Observe que estamos criando duas visualiza&ccedil;&otilde;es. A primeira ser&aacute; uma visualiza&ccedil;&atilde;o grande para ver seus gr&aacute;ficos ou modelos, etc. A segunda &eacute; uma visualiza&ccedil;&atilde;o sat&eacute;lite, que colocamos no WEST (ou seja, o lado esquerdo) do TopComponent. Isso permitir&aacute; que o usu&aacute;rio navegue rapidamente pela visualiza&ccedil;&atilde;o e oferece uma vis&atilde;o geral da cena inteira.</p>
<p>Declare a visualiza&ccedil;&atilde;o JComponent:
</p><pre class="examplecode">private JComponent myView;</pre>
<p></p></li><li>Quando o IDE &eacute; reinicializado, n&atilde;o &eacute; necess&aacute;rio persistir o TopComponent. Na verdade, fazer isso causar&aacute; um erro nesse caso. Portanto, altere PERSISTENCE_ALWAYS para PERSISTENCE_NEVER, como mostrado abaixo:
<pre class="examplecode">public int getPersistenceType() {
return TopComponent.PERSISTENCE_NEVER;
}</pre>
<p></p></li><li>Clique com o bot&atilde;o direito do mouse no n&oacute; do projeto e escolha &quot;Instalar/recarregar no IDE de desenvolvimento&quot;. Se uma mensagem de aviso aparecer, clique em OK.</p>
<p>Quando o m&oacute;dulo &eacute; instalado, observe o menu Janela e voc&ecirc; encontrar&aacute; um nome item de menu chamado &quot;Forma&quot;, no in&iacute;cio da lista de itens de menu. Escolha-o e voc&ecirc; ver&aacute; o in&iacute;cio da sua implementa&ccedil;&atilde;o da API do Visual Library:
</p><p><img border="1" src="../../images/tutorials/vislib/firstscene.png"/>
</p></li>
<!-- ===================================================================================== -->
<p></p><h2><a name="creating-a-palette"></a>Criando uma paleta de componentes da cena</h2>
<p>Para fazer algo &uacute;til com a API do Visual Library, implementaremos a <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-spi-palette/overview-summary.html">API da paleta</a> de forma que terminemos com uma paleta de componentes contendo as formas mostradas no in&iacute;cio deste tutorial. Mais tarde, adicionaremos a funcionalidade arrastar e soltar da API do Visual Library de forma que possamos arrastar e soltar as formas na cena. Depois disso, podermos enriquecer a cena com recursos adicionais, tais como a habilidade de colocar zoom e panor&acirc;mica na cena.
</p><ol>
<li>J&aacute; que o foco deste tutorial &eacute; a API do Visual Library, e n&atilde;o a API da paleta, n&atilde;o perderemos tempo explicando como a API da paleta funciona. Existem muitos tutoriais sobre esse assunto (<a href="https://netbeans.org/kb/trails/platform.html">aqui</a>). Portanto, voc&ecirc; pode simplesmente copiar e colar os arquivos seguintes em um novo pacote chamado <tt>org.netbeans.shapesample.palette</tt>:
<ul>
<li><a href="../../images/tutorials/vislib/Category.java">Category.java</a>
</li><li><a href="../../images/tutorials/vislib/CategoryChildren.java">CategoryChildren.java</a>
</li><li><a href="../../images/tutorials/vislib/CategoryNode.java">CategoryNode.java</a>
</li><li><a href="../../images/tutorials/vislib/PaletteSupport.java">PaletteSupport.java</a>
</li><li><a href="../../images/tutorials/vislib/Shape.java">Shape.java</a>
</li><li><a href="../../images/tutorials/vislib/ShapeChildren.java">ShapeChildren.java</a>
</li><li><a href="../../images/tutorials/vislib/ShapeNode.java">ShapeNode.java</a>
</li></ul>
<p></p></li><li>Da mesma forma explicada na etapa 3 da se&ccedil;&atilde;o chamada &quot;Introdu&ccedil;&atilde;o&quot;, anteriormente neste tutorial, adicionamos depend&ecirc;ncias sobre a API de a&ccedil;&otilde;es, a API de n&oacute;s e a API de paleta comum.</p>
<p></p></li><li>Em seguida, adicionamos a paleta &agrave; pesquisa do TopComponent, adicionando esta linha no fim do construtor do TopComponent:
<pre class="examplecode">associateLookup( Lookups.fixed( new Object[] { PaletteSupport.createPalette() } ) );</pre>
<p></p></li><li>O IDE solicitar&aacute; que voc&ecirc; insira instru&ccedil;&otilde;es de importa&ccedil;&atilde;o para <tt>org.openide.util.lookup.Lookups</tt> e <tt>org.netbeans.shapesample.palette.PaletteSupport</tt>. Aceite os avisos e permita que o IDE gere as instru&ccedil;&otilde;es de importa&ccedil;&atilde;o.
<p></p></li><li>Coloque as imagens encontradas no in&iacute;cio deste tutorial no pacote <tt>org.netbeans.shapesample.palette</tt>.</p>
<p>A janela Projetos agora deve ter esta apar&ecirc;ncia:</p>
<p><img border="1" src="../../images/tutorials/vislib/proj-window.png"/>
</p><p></p></li><li>Instale o m&oacute;dulo novamente. Quando voc&ecirc; abre o TopComponent no item de menu, a nova paleta de componentes e mostrada &agrave; direita da cena:</p>
<p><img border="1" src="../../images/tutorials/vislib/firstpalette.png"/>
</p></li>
<!-- ===================================================================================== -->
<p></p><h2><a name="adding-a-layer-widget"></a>Adicionando um LayerWidget</h2>
<p>Um <a href="http://graph.netbeans.org/documentation.html#LayerWidget">LayerWidget</a> representa um painel de vidro, semelhante a JGlassPane em Swing. Ele &eacute; transparente por padr&atilde;o. Portanto, antes de prosseguir, adicionaremos um LayerWidget &agrave; cena, portanto, temos algum lugar para colocar os widgets vis&iacute;veis que arrastar e soltar na cena.
</p><ol><li>Na classe <tt>GraphSceneImpl</tt>, declare a LayerWidget:
<pre class="examplecode">private LayerWidget mainLayer;</pre>
<p></p></li><li>No construtor da classe <tt>GraphSceneImpl</tt>, adicione a LayerWidget como uma filha da cena:
<pre class="examplecode">mainLayer = new LayerWidget (this);
addChild (mainLayer);</pre></li></ol>
<p>Agora, quando arrastamos e soltamos itens da paleta como widgets na cena, os adicionaremos como filhos de LayerWidget. Como LayerWidgets s&atilde;o transparentes por padr&atilde;o, voc&ecirc; poderia ter v&aacute;rios LayerWidgets transparentemente um em cima do outro, de forma que, por exemplo, possa adicionar uma imagem de segundo plano &agrave; cena.
</p><p>Para obter detalhes, consulte <a href="http://graph.netbeans.org/documentation.html#LayerWidget">LayerWidget</a> no Javadoc.
<!-- ===================================================================================== -->
</p><p></p><h2><a name="adding-an-icon-widget"></a>Adicionando um IconNodeWidget por meio da funcionalidade arrastar e soltar</h2>
<p>Anteriormente, usamos o construtor da classe <tt>GraphSceneImpl</tt> para passar uma cena para o JScrollPane do TopComponent. At&eacute; aqui, a cena existe mas n&atilde;o tem comportamento. O comportamento &eacute; adicionado atrav&eacute;s de a&ccedil;&otilde;es. A a&ccedil;&atilde;o que examinaremos nesta se&ccedil;&atilde;o se chama <tt><a href="http://graph.netbeans.org/documentation.html#AcceptAction">AcceptAction</a></tt>. Essa a&ccedil;&atilde;o ativa a funcionalidade arrastar e soltar. A funcionalidade arrastar e soltar poderia ser aplicada a um widget, mas aqui a aplicamos &agrave; cena em si.
</p><p>Usamos <tt>createAcceptAction</tt> para especificar o que deve acontecer quando um item da paleta &eacute; arrastado sobre a cena. Dois m&eacute;todos s&atilde;o envolvidos aqui. A primeira, <tt>isAcceptable()</tt>, &eacute; usada para determinar se o item pode ser aceito na cena. Aqui voc&ecirc; pode testar o item, usando a transfer&ecirc;ncia. Voc&ecirc; tamb&eacute;m pode definir a imagem arrastada, que &eacute; tudo o que fazemos na implementa&ccedil;&atilde;o abaixo. Se <tt>true</tt> for retornado, o m&eacute;todo <tt>accept</tt> &eacute; chamado. Aqui obtemos a imagem da transfer&ecirc;ncia, usando o mesmo m&eacute;todo de ajuda anterior. Em seguida, chamamos o m&eacute;todo <tt>addNode</tt>, instanciando um novo <a href="http://graph.netbeans.org/documentation.html#IconNodeWidget">IconNodeWidget</a> e passando a imagem recuperada da transfer&ecirc;ncia.
</p><p>Todo c&oacute;digo desta se&ccedil;&atilde;o &eacute; inter-relacionado, e voc&ecirc; receber&aacute; sublinhados de erro vermelhos em seu c&oacute;digo at&eacute; que todos os m&eacute;todos abaixo tenham sido adicionados, mas tentaremos adicionar tudo de uma forma l&oacute;gica!
</p><ol>
<li>Primeiro, adicione <tt>createAcceptAction</tt>, com seus dois m&eacute;todos, ao construtor da classe <tt>GraphSceneImpl</tt>:
<pre class="examplecode">getActions().addAction(ActionFactory.createAcceptAction(new AcceptProvider() {
public ConnectorState isAcceptable(Widget widget, Point point, Transferable transferable) {
Image dragImage = getImageFromTransferable(transferable);
JComponent view = getView();
Graphics2D g2 = (Graphics2D) view.getGraphics();
Rectangle visRect = view.getVisibleRect();
view.paintImmediately(visRect.x, visRect.y, visRect.width, visRect.height);
g2.drawImage(dragImage,
AffineTransform.getTranslateInstance(point.getLocation().getX(),
point.getLocation().getY()),
null);
return ConnectorState.ACCEPT;
}
public void accept(Widget widget, Point point, Transferable transferable) {
Image image = getImageFromTransferable(transferable);
Widget w = GraphSceneImpl.this.addNode(new MyNode(image));
w.setPreferredLocation(widget.convertLocalToScene(point));
}
}));</pre>
<p><b>Observa&ccedil;&atilde;o:</b> depois de adicionar o c&oacute;digo acima, alguns sublinhados vermelhos permanecer&atilde;o, indique que h&aacute; erros. Esses erros acontecem porque o c&oacute;digo acima se refere a um m&eacute;todo e a uma classe que ainda n&atilde;o foram criados. Voc&ecirc; ir&aacute; cri&aacute;-los nas pr&oacute;ximas etapas.
</p><p></p></li><li>Em seguida, na classe <tt>GraphSceneImpl</tt>, adicione um m&eacute;todo de ajuda para recuperar a imagem da transfer&ecirc;ncia:
<pre class="examplecode">private Image getImageFromTransferable(Transferable transferable) {
Object o = null;
try {
o = transferable.getTransferData(DataFlavor.imageFlavor);
} catch (IOException ex) {
ex.printStackTrace();
} catch (UnsupportedFlavorException ex) {
ex.printStackTrace();
}
return o instanceof Image ? (Imagem) o : Utilities.loadImage(&quot;org/netbeans/shapesample/palette/shape1.png&quot;);
}</pre>
<p>Observe que voc&ecirc; pode definir qualquer tipo de imagem quando uma imagem n&atilde;o &eacute; retornada com &ecirc;xito desse m&eacute;todo de ajuda. Por enquanto, usaremos a imagem &quot;<tt>shape1.png</tt>&quot; em vez disso.</p>
<p></p></li><li>Crie uma nova classe chamada <tt>MyNode</tt>. Essa classe representa um n&oacute; em um modelo orientado a gr&aacute;fico. Ela n&atilde;o pode ser uma imagem diretamente, j&aacute; que cada n&oacute; deve ser &uacute;nico (verificado pelo m&eacute;todo &quot;equals&quot;) no modelo. Se voc&ecirc; quisesse usar as imagens diretamente, ent&atilde;o, poderia ter somente 3 n&oacute;s (um para cada imagem) na cena. Usando a classe MyNode, voc&ecirc; pode ter v&aacute;rios n&oacute;s e cada n&oacute; pode ter sua pr&oacute;pria inst&acirc;ncia de imagem ou uma compartilhada.
<pre class="examplecode">public class MyNode {
private Image image;
public MyNode(Image image) {
this.image = image;
}
public Image getImage() {
return image;
}
}</pre>
<p></p></li><li>Altere a assinatura da classe <tt>GraphSceneImpl</tt> para o seguinte, de forma que o n&oacute; seja recebido pela classe de implementa&ccedil;&atilde;o do Visual Library:</li>
<pre class="examplecode">extends GraphScene&lt;MyNode, String&gt;</pre>
<p>Voc&ecirc; deve deixar o IDE gerar novos stubs para os m&eacute;todos abstratos.
</p><p>Al&eacute;m disso, j&aacute; que agora estamos usando gen&eacute;ricos, certifique-se de que o IDE esteja usando o JDK 1.5. Se voc&ecirc; n&atilde;o tem certeza se o 1.6 est&aacute; sendo usado, clique com o bot&atilde;o direito do mouse no projeto, escolha Propriedades e v&aacute; para a p&aacute;gina C&oacute;digos-fonte. Altere a lista suspensa N&iacute;vel do c&oacute;digo-fonte para 1.5.
</p><p></p><li>Finalmente, defina o novo widget na classe <tt>GraphSceneImpl</tt>. Esse m&eacute;todo &eacute; chamado automaticamente pelo m&eacute;todo <tt>accept</tt>. Use-o para definir o widget do Visual Library quando o item da paleta for solto.
<pre class="examplecode">protected Widget attachNodeWidget(MyNode node) {
IconNodeWidget widget = new IconNodeWidget(this);
widget.setImage(node.getImage());
widget.setLabel(Long.toString(node.hashCode()));
widget.getActions().addAction(ActionFactory.createMoveAction());
mainLayer.addChild(widget);
return widget;
}</pre>
<p>Observe que definimos a imagem recuperada do no. Tamb&eacute;m geramos um n&uacute;mero aleat&oacute;rio para que tenhamos um r&oacute;tulo. Por padr&atilde;o, o widget existe mas n&atilde;o tem comportamento. Aqui, criamos uma a&ccedil;&atilde;o de movimento, de forma que o widget possa ser movido na cena. Finalmente, antes de retornar o widget para a cena, o adicionamos como um filho ao LayerWidget que criamos na se&ccedil;&atilde;o anterior.</p>
<p></p></li><li>Recarregue o m&oacute;dulo e abra-o na janela Forma novamente.</p>
<p>Agora voc&ecirc; pode arrastar e saltar itens da paleta. Conforme voc&ecirc; arrastar um item sobre a cena, voc&ecirc; ver&aacute; a imagem arrastada. Quando voc&ecirc; solta um item, ele se torna um widget e fica vis&iacute;vel na cena, assim como na visualiza&ccedil;&atilde;o sat&eacute;lite, como voc&ecirc; pode ver aqui:
</p><p><img border="1" src="../../images/tutorials/vislib/finishedscene.png"/></p>
</li></ol>
<!-- ===================================================================================== -->
<p></p><h2><a name="adding-to-scene"></a>Adicionando funcionalidade &agrave; cena</h2>
<p>Na cena anterior, adicionamos <tt><a href="http://graph.netbeans.org/documentation.html#AcceptAction">AcceptAction</a></tt> &agrave; cena. T&iacute;nhamos que definir dois m&eacute;todos para especificar se o item deve ser solto e para resolver o item. Nesta se&ccedil;&atilde;o, usamos <tt><a href="http://graph.netbeans.org/documentation.html#ZoomAction">ZoomAction</a></tt>, para adicionar a funcionalidade mais zoom/menos zoom &agrave; cena.
</p><ol>
<li>No fim do construtor da classe <tt>GraphSceneImpl</tt>, adicione esta linha:
<pre class="examplecode">getActions().addAction(ActionFactory.createZoomAction());</pre>
<p></p></li><li>Instale o m&oacute;dulo novamente.
<p></p></li><li>Enquanto mant&eacute;m a tecla CTRL pressionada, use a roda do mouse para colocar mais zoom e menos zoom na cena:</p>
<p><img border="1" src="../../images/tutorials/vislib/zoom.png"/></p>
<p><img border="1" src="../../images/tutorials/vislib/unzoom.png"/></p>
</li></ol>
<p><b>Observa&ccedil;&atilde;o:</b> As formas s&atilde;o renderizadas como imagens. SVG n&atilde;o tem suporte no momento.
</p><p>Da mesma forma descrita acima, voc&ecirc; pode adicionar a funcionalidade Panor&acirc;mica &agrave; cena, por meio desta linha:
</p><pre class="examplecode">getActions().addAction(ActionFactory.createPanAction());</pre>
<p>Quando voc&ecirc; adicionar essa linha, o usu&aacute;rio poder&aacute; manter a roda do mouse pressionada e rolar em qualquer dire&ccedil;&atilde;o na cena.
<!-- ===================================================================================== -->
</p><p></p><h2><a name="adding-to-widget"></a>Adicionando funcionalidade ao IconNodeWidget</h2>
<p>Anteriormente, adicionamos <tt><a href="http://graph.netbeans.org/documentation.html#MoveAction">MoveAction</a></tt> ao IconNodeWidget, para ativar o comportamento de movimenta&ccedil;&atilde;o do widget. Dessa forma, muitos outros comportamentos podem ser adicionados ao widget. Nesta se&ccedil;&atilde;o, adicionamos <tt><a href="http://graph.netbeans.org/documentation.html#HoverAction">HoverAction</a></tt>, <tt><a href="http://graph.netbeans.org/documentation.html#SelectAction">SelectAction</a></tt> e <tt><a href="http://graph.netbeans.org/documentation.html#InplaceEditorAction">InplaceEditorAction</a></tt>.
</p><p>O <tt>InplaceEditorAction</tt> permitir&aacute; que o usu&aacute;rio altere o r&oacute;tulo:
</p><p><img border="1" src="../../images/tutorials/vislib/editable.png"/></p>
<p>O <tt>SelectAction</tt> ir&aacute; alterar a cor do r&oacute;tulo quando o widget for selecionado, enquanto o <tt>HoverAction</tt> ir&aacute; alterar a cor do r&oacute;tulo quando o mouse passar sobre o widget:
</p><p><img border="1" src="../../images/tutorials/vislib/selectable-hoverable.png"/></p>
<ol>
<p></p><li>Primeiro, defina a a&ccedil;&atilde;o do editor que adicionaremos ao IconNodeWidget:
<pre class="examplecode">private WidgetAction editorAction = ActionFactory.createInplaceEditorAction(new LabelTextFieldEditor());</pre>
<p></p></li><li>Agora, defina o <tt>LabelTextFieldEditor</tt>, da seguinte forma:
<pre class="examplecode">private class LabelTextFieldEditor implements TextFieldInplaceEditor {
public boolean isEnabled(Widget widget) {
return true;
}
public String getText(Widget widget) {
return ((LabelWidget) widget).getLabel();
}
public void setText(Widget widget, String text) {
((LabelWidget) widget).setLabel(text);
}
}</pre>
<p></p></li><li>Finalmente, atribua a a&ccedil;&atilde;o do editor ao IconNodeWidget, na mesma forma feita com a a&ccedil;&atilde;o de movimento anteriormente:
<pre class="examplecode">widget.getLabelWidget().getActions().addAction(editorAction);</pre>
<p>Aqui, primeiro obtemos o LabelWidget do IconNodeWidget. Em seguida, adicionamos a a&ccedil;&atilde;o do editor ao LabelWidget.</p>
<p></p></li><li>O IDE solicita que voc&ecirc; adicione v&aacute;rias instru&ccedil;&otilde;es de importa&ccedil;&atilde;o. Em cada caso, aceite a sugest&atilde;o oferecida pelo IDE.
<p></p></li><li>Em seguida, no caso de <tt>SelectAction</tt> e <tt>HoverAction</tt>, voc&ecirc; n&atilde;o precisa fazer nada al&eacute;m de atribuir essas a&ccedil;&otilde;es ao IconNodeWidget:
<pre class="examplecode">widget.getActions().addAction(createSelectAction());
widget.getActions().addAction(createObjectHoverAction());</pre>
<p></p></li><li>Em seguida, voc&ecirc; precisa pensar sobre a ordem das a&ccedil;&otilde;es criadas. Para obter detalhes, consulte a se&ccedil;&atilde;o <a href="http://graph.netbeans.org/documentation.html#OrderOfActions">Ordem de a&ccedil;&otilde;es</a> na documenta&ccedil;&atilde;o. Depois de reordenar as a&ccedil;&otilde;es, o <tt>attachNodeWidget</tt> deve ter a seguinte apar&ecirc;ncia:
<pre class="examplecode">protected Widget attachNodeWidget(MyNode node) {
IconNodeWidget widget = new IconNodeWidget(this);
widget.setImage(node.getImage());
widget.setLabel(Long.toString(node.hashCode()));
//double-click, the event is consumed while double-clicking only:
widget.getLabelWidget().getActions().addAction(editorAction);
//single-click, the event is not consumed:
widget.getActions().addAction(createSelectAction());
//mouse-dragged, the event is consumed while mouse is dragged:
widget.getActions().addAction(ActionFactory.createMoveAction());
//mouse-over, the event is consumed while the mouse is over the widget:
widget.getActions().addAction(createObjectHoverAction());
mainLayer.addChild(widget);
return widget;
}</pre>
<p></p></li><li>Instale e experimente o m&oacute;dulo novamente. Como mostrado no in&iacute;cio desta se&ccedil;&atilde;o, quando voc&ecirc; passar o mouse sobre o r&oacute;tulo do widget, ou quando voc&ecirc; o selecionar, sua cor mudar&aacute;. Al&eacute;m disso, quando voc&ecirc; clica em um r&oacute;tulo, &eacute; poss&iacute;vel editar seu conte&uacute;do.
</li></ol>
<p>Parab&eacute;ns, voc&ecirc; concluiu o Tutorial do Visual Library 2.0 para NetBeans 6.0.</p>
<br>
<div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback:%20Visual%20Library%20API%20Tutorial%20NetBeans%206.0">Envie-nos seus coment&aacute;rios</a></div>
<br style="clear:both;" />
<a name="next_steps"></a><h2>Pr&oacute;ximas etapas</h2>
<p>Para obter mais informa&ccedil;&otilde;es sobre como trabalhar com a API do Visual Library, consulte:</p>
<ul>
<li><a href="http://www.javalobby.org/eps/netbeans_visual_library/">Screencast sobre o Visual Library de Roman Strobl</a> em Javalobby.
</li><li><a href="http://graph.netbeans.org/">P&aacute;gina do projeto do Visual Library</a>
</li><li><a href="http://graph.netbeans.org/documentation.html">Visual Library 2.0 - Documenta&ccedil;&atilde;o</a>
</li></ul>
</ol></ol></body>
</html>