| <!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 do aplicativo Paint para a Plataforma NetBeans 6.8</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="gwielenga@netbeans.org"/> |
| <meta name="indexed" content="y"/> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <meta name="description" |
| content="A guide to creating a Paint application."/> |
| <!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. --> |
| <!-- Use is subject to license terms.--> |
| </head> |
| <body> |
| |
| <h1>Tutorial do aplicativo Paint para a Plataforma NetBeans</h1> |
| |
| <p>Este tutorial orienta-o através dos fundamentos do uso do NetBeans IDE para desenvolver aplicativos rich-client na Plataforma NetBeans. Ao desenvolver aplicativos na Plataforma NetBeans, você está desenvolvendo no núcleo do NetBeans IDE. Todos os módulos que pertençam ao IDE e não sejam relevantes para o seu aplicativo serão excluídos, mas os úteis serão mantidos. Ao reutilizar recursos prontamente disponíveis no núcleo do IDE, você economiza tempo e energia. </p> |
| |
| <p><strong class="notes">Nota:</strong> este documento utiliza a versão NetBeans IDE 6.5. Se você estiver utilizando o NetBeans IDE 0.x, consulte <a href="60/nbm-paintapp_pt_BR.html">a versão 6.0/6.1 deste documento</a>.</p> |
| |
| <p><b>Conteúdo</b></p> |
| |
| <p><img src="../../images/articles/69/netbeans-stamp7-8-9.png" class="stamp" width="114" height="114" alt="O conteúdo desta página se aplica ao NetBeans IDE 6.5, 6.7, 6.8" title="O conteúdo desta página se aplica ao NetBeans IDE 6.5, 6.7, 6.8" /></p> |
| <ul class="toc"> |
| <li><a href="#intro">Introdução ao aplicativo Paint</a></li> |
| <li><a href="#setup">Configurando o aplicativo Paint</a> |
| <ul> |
| <li><a href="#creatingModuleSuite">Criando o esqueleto do aplicativo</a></li> |
| <li><a href="#creatingLibWrapModule">Criando o módulo de wrapper de bibliotecas</a></li> |
| <li><a href="#creatingModProj">Criando o módulo</a></li> |
| <li><a href="#specifyingModProjDep">Especificando as dependências do módulo</a></li> |
| </ul></li> |
| <li><a href="#impMod">Criando e incorporando a tela do Paint</a> |
| <ul> |
| <li><a href="#creatingCanv">Criando a tela</a></li> |
| <li><a href="#prepTopComp">Preparando a classe TopComponent</a></li> |
| <li><a href="#initTopComp">Inicializando a classe TopComponent</a></li> |
| <li><a href="#fillSkelMeth">Preenchendo os métodos do esqueleto</a></li> |
| <li><a href="#savingImage">Salvando a imagem em disco</a></li> |
| </ul></li> |
| <li><a href="#defNew">Criando o item de menu Nova tela</a></li> |
| <li><a href="#defSave">Criando o item de menu Salvar tela</a></li> |
| <li><a href="#wrappingUp">Empacotando</a></li> |
| <li><a href="#creatingDist">Criando uma distribuição</a></li> |
| </ul> |
| |
| <p><b>Para seguir este tutorial, os softwares e recursos listados na tabela seguinte são necessários.</b></p> |
| |
| <table> |
| <tbody> |
| <tr> |
| <th class="tblheader" scope="col">Software ou recurso</th> |
| <th class="tblheader" scope="col">Versão necessária</th> |
| </tr> |
| <tr> |
| <td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td> |
| <td class="tbltd1">versã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ão 6 ou<br/>versão 5</td> |
| </tr> |
| </tbody> |
| </table> |
| |
| <h2>Introdução ao aplicativo Paint</h2><p><a name="intro"></a></p> |
| |
| <p>Este tutorial foi concebido para começar o mais rápido possível. Você gerará criar e instalar um aplicativo simples na Plataforma NetBeans. O aplicativo permite que o usuário pinte na tela e salve os resultados:</p> |
| |
| <p><img src="../../images/tutorials/paintapp/result-without-menus-60.png" alt="imagem do aplicativo concluído" /></p> |
| |
| <p>Esta versão inicial está longe de ser um aplicativo paint desenvolvido, mas demonstra um caso muito simples de criação de um aplicativo na Plataforma NetBeans.</p> |
| |
| <p><b class="notes">Nota:</b> o <a href="nbm-google_pt_BR.html">Início rápido do plug-in do NetBeans</a> é um tutorial melhor se você quiser aprender sobre módulos do NetBeans e não sobre aplicativos rich-client. </p> |
| |
| <p>Neste tutorial, recriaremos um aplicativo que é uma amostra fornecida com o IDE. Para ver o produto final, ou para solucionar problemas enquanto trabalhar neste tutorial, obtenha a amostra do Assistente para novo projeto, na localização mostrada abaixo:</p> |
| |
| <p><img src="../../images/tutorials/paintapp/sample-in-new-project-60.png" alt="Painel Nome e localização" /></p> |
| |
| |
| <h2>Configurando o aplicativo Paint</h2><p><a name="setup"/></p> |
| |
| <p>Nesta seção, a estrutura do aplicativo será criada. Primeiro é preciso criar o esqueleto de um aplicativo, o que pode ser feito através de um assistente. O aplicativo depende de uma biblioteca, assim, você também gerará criar um módulo de wrapper de bibliotecas que conterá o arquivo JAR da biblioteca. Finalmente, você gerará criar o módulo que conterá o código.</p> |
| |
| <div class="indent"> |
| |
| <p><a name="creatingModuleSuite"></a></p><h3 class="tutorial">Criando o esqueleto do aplicativo</h3> |
| |
| <p>O modelo "Aplicativo da plataforma NetBeans" gerará criar o esqueleto do aplicativo. O esqueleto consistirá em um conjunto de módulos que funcionam juntos para formar a base do aplicativo. Você utilizará a caixa de diálogo Propriedades do projeto para atribuir a tela inicial do aplicativo, o nome do aplicativo e o tipo e o número de módulos NetBeans que deseja utilizar. Também é possível se beneficiar de ações como a criação de uma distribuição ZIP e a construção de um aplicativo JNLP (Java WebStart), que são ferramentas importantes para tornar seu aplicativo disponível para os outros usuários.</p> |
| |
| <ol> |
| <li>Escolha Arquivo > Novo projeto. Em Categorias, selecione Módulos do NetBeans. Em Projetos, selecione Aplicativo da plataforma NetBeans: |
| <p><img src="../../images/tutorials/paintapp/paintapp-proj-wiz.png" alt="modelo de projeto" /></p> |
| <p>Clique em Próximo.</p></li> |
| <li>No painel Nome e local, digite <tt>PaintApp</tt> em Nome do projeto. Altere Local de projeto para qualquer diretório no computador. Deixe marcada a caixa de verificação Definir como projeto principal. Clique em Terminar.</li> |
| |
| </ol> |
| |
| <p>O novo esqueleto do aplicativo é aberto no IDE. Ele contém dois nós na janela Projetos. O primeiro nó, o nó "Módulos", é para adição manual de módulos e módulos de wrapper de bibliotecas no aplicativo. Além disso, ao utilizar o assistente para Módulo ou o assistente para Módulo de wrapper de bibliotecas, o módulo que você criar poderá ser adicionado automaticamente ao aplicativo.</p> |
| |
| <h3 class="tutorial"><a name="creatingLibWrapModule"></a>Criando o módulo de wrapper de bibliotecas</h3> |
| |
| <p>Um módulo de wrapper de biblioteca é um módulo cujo arquivo JAR não contém código, ele apenas aponta para uma biblioteca. Ele transforma a biblioteca em um módulo do NetBeans, para que todas as proteções do sistema carregador de classes do NetBeans sejam aplicadas nele, sem modificar o arquivo JAR original. O aplicativo poderá, então, depender da biblioteca simplesmente como se ela fosse outro módulo do NetBeans. E, se novas versões da biblioteca se tornarem disponíveis, é possível distribuí-las sem precisar distribuir nada além de um simples arquivo NBM (NetBeans Module) para o wrapper de bibliotecas.</p> |
| |
| <p><b class="notes">Nota:</b> um dos benefícios da construção na Plataforma NetBeans é que a interface do usuário é baseada em Swing: o kit de ferramentas padrão de interface do usuário para Java. Como o Swing tem sido utilizado há bastante tempo, há muitos componentes Swing que podem ser reutilizados no aplicativo. Neste tutorial, reutilize um JavaBean de seletor de cores existente (é possível encontrar o código-fonte para tal no NetBeans CVS em <tt>contrib/coloreditor</tt>). O arquivo JAR é nomeado <tt>ColorChooser.jar</tt>. É possível fazer o download da biblioteca <a href="https://colorchooser.dev.java.net/">aqui</a>. Salve-a em qualquer lugar no sistema de arquivos. </p> |
| |
| <p>Para criar um módulo de wrapper de bibliotecas para o arquivo <tt>ColorChooser.jar</tt> faça o seguinte:</p> |
| |
| <ol> |
| <li>Escolha Arquivo > Novo projeto. Em Categorias, selecione Módulos do NetBeans. Em Projetos, selecione Módulo de wrapper de bibliotecas e clique em Próximo.</li> |
| <li>No painel Selecionar biblioteca, para a caixa de texto Biblioteca, digite o caminho para <tt>ColorChooser.jar</tt> ou navegue até sua localização.</li> |
| <li>Deixe o campo de texto Licença vazio. Se você pretender distribuir o produto completo, deverá incluir o arquivo de licença da biblioteca externa. Clique em Próximo.</li> |
| <li>No painel Nome e localização, preencha o nome do projeto, defina o local do projeto e certifique-se de que a lista suspensa Adicionar à suíte de módulos mostra que o módulo será adicionado ao aplicativo. Clique em Próximo.</li> |
| <li>No painel Configuração básica de módulos, digite um nome exclusivo no nome base do código, especifique um nome de exibição para o módulo e o local do pacote de localização do módulo: |
| |
| <p><img src="../../images/tutorials/paintapp/lib-wrap-1.png" alt="Painel Nome e localização" /></p> |
| |
| <p>Clique em Terminar.</p></li></ol> |
| |
| <p>O módulo que empacota o <tt>colorchooser.jar</tt> selecionado é criado pelo IDE. A estrutura do novo módulo é mostrada na janela Projetos. O nó "Módulos" na estrutura do aplicativo mostra que o módulo faz parte do aplicativo.</p> |
| |
| <h3 class="tutorial"><a name="creatingModProj"></a>Criando o módulo</h3> |
| <p>Agora, é preciso um módulo para receber o código real que você vai escrever.</p> |
| <ol> |
| <li>Escolha Arquivo > Novo projeto. Em Categorias, selecione Módulos do NetBeans. Em Projetos, selecione Módulo e clique em Próximo.</li> |
| <li>No painel Nome e local, digite <tt>Paint</tt> em Nome do projeto. Altere Local do projeto para qualquer diretório no computador. Certifique-se de que o botão de opção Adicionar à suíte de módulos esteja selecionado e de que o aplicativo <tt>PaintApp</tt> esteja selecionado na lista suspensa Suíte de módulos. Selecione a caixa de verificação Definir como projeto principal. Clique em Próximo.</li> |
| |
| <li>No painel Configuração básica de módulos, digite <tt>org.netbeans.paint</tt>. Deixe <tt>Paint</tt> como o Nome de exibição do módulo. Deixe o local do pacote de localização. Clique em Gerar camada XML e não altere o local sugerido, para que o pacote de localização e o arquivo de camada XML sejam armazenados em um pacote com o nome <tt>org.netbeans.paint</tt>. |
| <p>Esses destinos fazem o seguinte:</p> |
| <ul> |
| <li><b>Pacote de localização.</b> Especifica as strings de linguagem específica para internacionalização.</li> |
| <li><b>Camada XML.</b> Registra itens como menus e botões da barra de ferramentas no aplicativo da plataforma NetBeans. |
| </li> |
| </ul> |
| |
| |
| <p>Clique em Terminar.</p></li></ol> |
| |
| <p> O IDE cria o projeto <tt>Paint</tt>. O projeto contém todos os metadados de projeto e códigos-fonte, como o script de construção Ant do projeto. O projeto se abre no IDE. É possível ver a estrutura lógica na janela Projetos (Ctrl-1) e a estrutura de arquivos na janela Arquivos (Ctrl+2). Por exemplo, a janela Projetos deve ter esta aparência:</p> |
| |
| <p><img src="../../images/tutorials/paintapp/paintapp-start-1.png" alt="paint app" /></p> |
| |
| |
| <p>Além do pacote de localização e da camada XML, o projeto também inclui os seguintes arquivos importantes:</p> |
| <ul> |
| <li><b>Manifesto do módulo.</b> Declara que o projeto é um módulo. Além disso, define algumas configurações específicas do módulo, tais como a localização da camada XML, a localização do pacote de bundle e a versão do módulo.</li> |
| <li><b>Script de construção.</b> Fornece um local onde é possível criar seus próprios destinos Ant e substituir aqueles que são especificados em <tt>nbproject/build-impl.xml</tt>.</li> |
| <li><b>Metadados do projeto.</b> Contém informações como o tipo do projeto, conteúdo, plataforma, classpath, dependências e mapeamentos entre os comandos do projeto e os destinos em scripts Ant.</li> |
| |
| </ul> |
| <p>Não será preciso modificar qualquer um desses arquivos durante este tutorial.</p> |
| |
| |
| |
| <h3 class="tutorial"><a name="specifyingModProjDep"></a>Especificando as dependências do módulo</h3> |
| |
| |
| |
| <p>É preciso criar subclasses de várias classes que pertencem às <a href="http://bits.netbeans.org/dev/javadoc/index.html">APIs do NetBeans</a>. Além disso, o projeto depende do arquivo <tt>ColorChooser.jar</tt>. Todas as APIs do NetBeans são implementadas por módulos, portanto, concluir ambas essas tarefas realmente significa adicionar alguns módulos à lista de módulos de que nosso módulo precisa para ser executado.</p> |
| |
| <ol> |
| <li>Na janela Projetos, clique com o botão direito do mouse no nó do projeto <tt>Paint</tt> e escolha Propriedades. A caixa de diálogo Propriedades do projeto é aberta. Em Categorias, clique em Bibliotecas.</li> |
| |
| <li>Para cada uma das APIs listadas na tabela abaixo, clique em "Adicionar dependência..." e, em seguida, na caixa de texto Filtro, comece digitando o nome da classe cuja subclasse deseja criar. |
| |
| <table width="76%" border="1"> |
| <tbody> |
| <tr> |
| <td> |
| <div><b>Classe</b></div> |
| </td> |
| <td> |
| <div><b>API</b></div> |
| </td> |
| |
| <td> |
| <div><b>Finalidade</b></div> |
| </td> |
| </tr> |
| <tr> |
| <td><tt>Seletor de cores</tt></td> |
| <td><tt>Seletor de cores</tt></td> |
| |
| <td>O módulo do wrapper de biblioteca do componente seletor de cores criado</td> |
| </tr> |
| <tr> |
| <td><tt>DataObject</tt></td> |
| <td><tt>API de sistemas de dados</tt></td> |
| |
| <td>O módulo do NetBeans que contém a classe DataObject</td> |
| </tr> |
| <tr> |
| <td><tt>DialogDisplayer</tt></td> |
| <td><tt>API de caixas de diálogo</tt></td> |
| |
| <td>Isso permite a criação da notificação do usuário, uma descrição da caixa de diálogo e permite que ela seja exibida</td> |
| </tr> |
| <tr> |
| <td><tt>AbstractFile</tt></td> |
| <td><tt>API do sistema de arquivos</tt></td> |
| |
| <td>Isso fornece uma API comum para acessar os arquivos de uma maneira uniforme</td> |
| </tr> |
| <tr> |
| <td><tt>AbstractNode</tt></td> |
| <td><tt>API de nós</tt></td> |
| |
| <td>Isso serve como o aparato principal para a visualização de objetos no NetBeans</td> |
| </tr> |
| <tr> |
| <td><tt>StatusDisplayer</tt></td> |
| <td><tt>API de utilitários para UI</tt></td> |
| |
| <td>A classe StatusDisplayer utilizada para criar a barra de status na janela principal</td> |
| </tr> |
| <tr> |
| <td><tt>WeakListeners</tt></td> |
| <td><tt>API de utilitários</tt></td> |
| |
| <td>Isso contém a classe WeakListeners</td> |
| </tr> |
| <tr> |
| <td><tt>TopComponent</tt></td> |
| <td><tt>API do sistema de janelas</tt></td> |
| |
| <td>Isso contém a classe JPanel TopComponent</td> |
| </tr> |
| |
| </tbody> |
| </table> |
| |
| <p>A primeira coluna na tabela acima, lista todas as classes cuja subclasse será criada neste tutorial. Em cada caso, comece a digitar o nome da classe no filtro e veja a lista Módulo diminuir. Utilize a segunda coluna da tabela para selecionar a API apropriada (ou, no caso de <tt>ColorChooser</tt>, a biblioteca) na lista Módulo diminuída e clique em OK para confirmar a escolha:</p> |
| |
| <p><img src="../../images/tutorials/paintapp/libfilter-60.png" alt="initial-proj-window" /></p> |
| </li> |
| <li>Clique em OK para sair da caixa de diálogo Propriedades do projeto.</li> |
| <li>Na janela Projetos, expanda o nó do projeto do módulo do Paint se ele ainda não estiver expandido. Em seguida, expanda o nó Arquivos importantes e clique duas vezes no nó Metadados do projeto. Observe que as APIs selecionadas foram declaradas como dependências de módulo.</li> |
| |
| |
| </ol> |
| </div> |
| <h2><a name="impMod"></a>Criando e incorporando a tela do Paint</h2> |
| |
| |
| <div class="indent"> |
| <h3 class="tutorial"><a name="creatingCanv"></a>Criando a tela</h3> |
| <p>A próxima etapa é criar o componente real que o usuário pode pintar. Aqui, um componente Swing puro é utilizado: portanto, vamos ignorar os detalhes de sua implementação e fornecer apenas a versão final. O bean do seletor de cores, para o qual o wrapper de biblioteca foi criado, é utilizado no código-fonte desse painel: quando você executar o aplicativo concluído, gerará vê-lo na barra de ferramentas do painel para edição de imagens.</p> |
| <ol> |
| <li>Na janela Projetos, expanda o nó <tt>Paint</tt>e, em seguida, expanda o nó Pacotes de códigos-fonte e clique com o botão direito do mouse no nó <tt>org.netbeans.paint</tt>. Escolha Nova > Classe Java.</li> |
| <li>Insira <tt>PaintCanvas</tt> como o Nome da classe. Garanta que <tt>org.netbeans.paint</tt> esteja listado como o pacote. Clique em Terminar. <tt>PaintCanvas.java</tt> se abre no editor de código-fonte.</li> |
| <li>Substitua o conteúdo padrão do arquivo pelo conteúdo encontrado <a href="https://platform.netbeans.org/guide/tutorials/paintTutorial/PaintCanvas.java">aqui</a>. Se você chamou o pacote de algo diferente de <tt>org.netbeans.paint</tt>, corrija o nome do pacote no editor de código-fonte.</li> |
| </ol> |
| |
| <h3 class="tutorial"><a name="prepTopComp"></a>Preparando a classe TopComponent</h3> |
| |
| <p>Agora sua primeira classe que utiliza as <a href="http://bits.netbeans.org/dev/javadoc/index.html">APIs do NetBeans</a> será escrita. Trata-se de uma classe <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a></tt>. Uma classe <tt>TopComponent</tt> é apenas uma classe <tt>JPanel</tt> com a qual o sistema de janelas do NetBeans sabe se comunicar: portanto, ela pode ser colocada dentro de um contêiner com guias dentro da janela principal.</p> |
| |
| <ol> |
| <li>Na janela Projetos, expanda o nó <tt>Paint</tt>e, em seguida, expanda o nó Pacotes de códigos-fonte e clique com o botão direito do mouse no nó <tt>org.netbeans.paint</tt>. Escolha Nova > Classe Java. Indique <tt>PaintTopComponent</tt> como o Nome da classe. Garanta que <tt>org.netbeans.paint</tt> esteja listado como o pacote. Clique em Terminar. <tt>PaintTopComponent.java</tt> se abre no editor de código-fonte.</li> |
| <li>Próximo à parte superior do arquivo, altere a declaração da classe para o seguinte: |
| <pre class="examplecode">public class PaintTopComponent extends TopComponent implements ActionListener, ChangeListener {</pre></li> |
| <li>Pressione Ctrl-Shift-I para corrigir as importações e clique em OK na caixa de diálogo. O IDE faz as declarações de pacote de importação necessárias na parte superior do arquivo. |
| <p>Observe a linha vermelha sob a declaração da classe que você acabou de indicar. Posicione o cursor na linha e observe que uma lâmpada aparece na margem esquerda. Clique na lâmpada (ou pressione Alt-Enter), como mostrado abaixo:</p> |
| |
| <p><img src="../../images/tutorials/paintapp/lightbulb-60.png" alt="Lâmpada." /></p> |
| |
| Selecione Implementar todos os métodos abstratos. O IDE gera dois esqueletos de método: <tt>actionPerformed()</tt> e <tt>stateChanged()</tt>. Você os experimentará neste tutorial.</li> |
| <li>Adicione as três declarações de variável seguintes no início da classe <tt>PaintTopComponent</tt> e corrija as instruções de importação (Ctrl-Shift-I). |
| <pre class="examplecode"> private PaintCanvas canvas = new PaintCanvas(); //The component the user draws on |
| private JComponent preview; //A component in the toolbar that shows the paintbrush size |
| private static int ct = 0; //A counter you use to provide names for new images</pre></li> |
| <li>Agora é preciso implementar dois métodos padronizados. O primeiro diz ao sistema de janelas para ignorar as janelas abertas quando o aplicativo é encerrado; o segundo fornece uma string base de um ID de string único do nosso componente. Cada <tt>TopComponent</tt> possui um ID de string único que é utilizado ao salvar o <tt>TopComponent</tt>. Insira os dois métodos seguintes na classe <tt>PaintTopComponent</tt>: |
| <pre class="examplecode"> @Override |
| public int getPersistenceType() { |
| return PERSISTENCE_NEVER; |
| } |
| |
| @Override |
| public String preferredID() { |
| return "Image"; |
| }</pre></li> |
| </ol> |
| |
| <p>A classe agora deve ter esta aparência:</p> |
| |
| <pre class="examplecode">public class PaintTopComponent extends TopComponent implements ActionListener, ChangeListener { |
| |
| private PaintCanvas canvas = new PaintCanvas(); //The component the user draws on |
| private JComponent preview; //A component in the toolbar that shows the paintbrush size |
| private static int ct = 0; //A counter you use to provide names for new images |
| |
| public PaintTopComponent() { |
| } |
| |
| @Override |
| public void actionPerformed(ActionEvent arg0) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public void stateChanged(ChangeEvent arg0) { |
| throw new UnsupportedOperationException("Not supported yet."); |
| } |
| |
| @Override |
| public int getPersistenceType() { |
| return PERSISTENCE_NEVER; |
| } |
| |
| @Override |
| public String preferredID() { |
| return "Image"; |
| } |
| |
| }</pre> |
| |
| <h3 class="tutorial"><a name="initTopComp"></a>Inicializando a classe TopComponent</h3> |
| |
| <p>Nesta seção, adicionamos o código que inicializa a interface do usuário.</p> |
| |
| <ol> |
| <li>Defina o construtor e depois corrija as sentenças import (Ctrl-Shift-I): |
| |
| <pre class="examplecode"> public PaintTopComponent() { |
| |
| initComponents(); |
| |
| String displayName = NbBundle.getMessage( |
| PaintTopComponent.class, |
| "UnsavedImageNameFormat", |
| new Object[] { new Integer(ct++) } |
| ); |
| |
| setDisplayName(displayName); |
| |
| }</pre> |
| |
| <p>O código aqui é muito simples. A primeira chamada a um método que você ainda não escreveu, <tt>initComponents()</tt>, que adicionará uma barra de ferramentas e um PaintCanvas ao seu <tt>TopComponent</tt>. Como o método ainda não foi escrito, uma linha vermelha aparece abaixo dele. Como antes, clique na lâmpada (ou pressione Alt-Enter) e aceite a sugestão:</p> |
| |
| <p><img src="../../images/tutorials/paintapp/lightbulb-initcomponents-60.png" alt="Lâmpada." /></p> |
| |
| <p>O esqueleto do método <tt>initComponents()</tt> é gerado para você.</p></li> |
| |
| |
| <li>Expanda o pacote <tt>org.netbeans.paint</tt> na janela Projetos. Clique duas vezes no arquivo <tt>Bundle.properties</tt> para abrí-lo no editor de código-fonte. Adicionando a linha seguinte no fim: |
| <pre class="examplecode"> UnsavedImageNameFormat=Image {0}</pre> |
| <p>Isso especifica o texto que será utilizado para identificar um novo arquivo de imagem no aplicativo antes de ser salvo pelo usuário. Por exemplo, quando um usuário clicar em Nova tela pela primeira vez em seu aplicativo concluído, aparecerá uma aba acima do editor de código-fonte com o rótulo, 'Image 0'. Salve o arquivo antes de continuar.</p> |
| </li></ol> |
| |
| |
| <h3 class="tutorial"><a name="fillSkelMeth"></a>Preenchendo os métodos do esqueleto</h3> |
| |
| <p>Nesta seção, codificamos a interface do usuário do nosso aplicativo. Também poderíamos utilizar o Construtor de GUIs do IDE para criar visualmente o layout.</p> |
| |
| <ol> |
| |
| <li>O método <tt>initComponents()</tt> instala os componentes em seu painel, de forma que o usuário tenha algo com que interagir. O método de esqueleto foi gerado durante a seção anterior na classe <tt>PaintTopComponent.java</tt>. Preencha da seguinte forma: |
| |
| <pre class="examplecode"> private void initComponents() { |
| |
| setLayout(new BorderLayout()); |
| JToolBar bar = new JToolBar(); |
| |
| ColorChooser fg = new ColorChooser(); |
| preview = canvas.createBrushSizeView(); |
| |
| //Now build our toolbar: |
| |
| //Make sure components don't get squished: |
| Dimension min = new Dimension(32, 32); |
| preview.setMaximumSize(min); |
| fg.setPreferredSize(new Dimension(16, 16)); |
| fg.setMinimumSize(min); |
| fg.setMaximumSize(min); |
| |
| JButton clear = new JButton( |
| NbBundle.getMessage(PaintTopComponent.class, "LBL_Clear")); |
| |
| JLabel fore = new JLabel( |
| NbBundle.getMessage(PaintTopComponent.class, "LBL_Foreground")); |
| |
| fg.addActionListener(this); |
| clear.addActionListener(this); |
| |
| JSlider js = new JSlider(); |
| js.setMinimum(1); |
| js.setMaximum(24); |
| js.setValue(canvas.getDiam()); |
| js.addChangeListener(this); |
| |
| fg.setColor(canvas.getColor()); |
| |
| bar.add(clear); |
| bar.add(fore); |
| bar.add(fg); |
| JLabel bsize = new JLabel( |
| NbBundle.getMessage(PaintTopComponent.class, "LBL_BrushSize")); |
| |
| bar.add(bsize); |
| bar.add(js); |
| bar.add(preview); |
| |
| JLabel spacer = new JLabel(" "); //Just a spacer so the brush preview |
| //isn't stretched to the end of the |
| //toolbar |
| |
| spacer.setPreferredSize(new Dimension(400, 24)); |
| bar.add(spacer); |
| |
| //And install the toolbar and the painting component: |
| add(bar, BorderLayout.NORTH); |
| add(canvas, BorderLayout.CENTER); |
| |
| }</pre> |
| <p>Pressione Ctrl-Shift-I para gerar as instruções de importação necessárias. </p></li> |
| |
| <li>Preencha os outros dois métodos gerados. Eles são utilizados para ouvir a classe <tt>PaintTopComponent</tt>: |
| <pre class="examplecode"> public void actionPerformed(ActionEvent e) { |
| |
| if (e.getSource() instanceof JButton) { |
| canvas.clear(); |
| } else if (e.getSource() instanceof ColorChooser) { |
| ColorChooser cc = (ColorChooser) e.getSource(); |
| canvas.setPaint (cc.getColor()); |
| } |
| |
| preview.paintImmediately(0, 0, preview.getWidth(), preview.getHeight()); |
| |
| }</pre> |
| |
| <pre class="examplecode"> public void stateChanged(ChangeEvent e) { |
| |
| JSlider js = (JSlider) e.getSource(); |
| canvas.setDiam (js.getValue()); |
| preview.paintImmediately(0, 0, preview.getWidth(), preview.getHeight()); |
| |
| }</pre> |
| </li> |
| <li>No arquivo <tt>Bundle.properties</tt>, adicione os pares chave-valor seguintes ao fim do arquivo: |
| <pre class="examplecode"> |
| LBL_Clear = Clear |
| LBL_Foreground = Foreground |
| LBL_BrushSize = Brush Size |
| </pre> |
| <p>Salve o arquivo antes de continuar.</p> |
| |
| </li> |
| </ol> |
| |
| <h3 class="tutorial"><a name="savingImage"></a>Salvando a imagem em disco</h3> |
| |
| <p>Em seu novo aplicativo, seria uma boa idéia permitir aos usuários salvar as imagens que eles criam. Incluindo o código seguinte na classe <tt>PaintTopComponent</tt>, essa funcionalidade será ativada.</p> |
| |
| <ol> |
| <li>Insira o código seguinte na classe <tt>PaintTopComponent</tt>: |
| |
| <pre class="examplecode"> public void save() throws IOException { |
| |
| if (getDisplayName().endsWith(".png")) { |
| doSave(new File(getDisplayName())); |
| } else { |
| saveAs(); |
| } |
| |
| } |
| |
| public void saveAs() throws IOException { |
| |
| JFileChooser ch = new JFileChooser(); |
| if (ch.showSaveDialog(this) == JFileChooser.APPROVE_OPTION && ch.getSelectedFile() != null) { |
| |
| File f = ch.getSelectedFile(); |
| |
| if (!f.getPath().endsWith(".png")) { |
| f = new File(f.getPath() + ".png"); |
| } |
| |
| if (!f.exists()) { |
| |
| if (!f.createNewFile()) { |
| String failMsg = NbBundle.getMessage( |
| PaintTopComponent.class, |
| "MSG_SaveFailed", new Object[] { f.getPath() } |
| ); |
| JOptionPane.showMessageDialog(this, failMsg); |
| return; |
| } |
| |
| } else { |
| String overwriteMsg = NbBundle.getMessage( |
| PaintTopComponent.class, |
| "MSG_Overwrite", new Object[] { f.getPath() } |
| ); |
| |
| if (JOptionPane.showConfirmDialog(this, overwriteMsg) |
| != JOptionPane.OK_OPTION) { |
| return; |
| } |
| |
| } |
| |
| doSave(f); |
| |
| } |
| |
| } |
| |
| private void doSave(File f) throws IOException { |
| |
| BufferedImage img = canvas.getImage(); |
| ImageIO.write(img, "png", f); |
| String statusMsg = NbBundle.getMessage(PaintTopComponent.class, |
| "MSG_Saved", new Object[] { f.getPath() }); |
| StatusDisplayer.getDefault().setStatusText(statusMsg); |
| setDisplayName(f.getName()); |
| |
| }</pre></li> |
| |
| <li>Adicione as linhas seguintes ao arquivo <tt>Bundle.properties</tt>: |
| <pre class="examplecode"> MSG_SaveFailed = Could not write to file {0} |
| MSG_Overwrite = {0} exists. Sobrescrever? MSG_Saved = Saved image to {0}</pre> |
| |
| <p>Salve o arquivo antes de continuar.</p> |
| |
| </li> |
| |
| <li>Clique em Ctrl-Shift-I para corrigir as instruções de importação. Você observará que haverá dois nomes totalmente classificados para a classe <tt>File</tt>. Escolha a opção <tt>java.io.File</tt>.</li> |
| </ol> |
| |
| </div> |
| <h2><a name="defNew"></a>Criando o item de menu Nova tela</h2> |
| |
| <p>Utilize os modelos de arquivo de desenvolvimento de módulo para criar a base da funcionalidade do método. Quando um modelo de arquivo é utilizado, o IDE registra o item que você cria no arquivo <tt>layer.xml</tt>. Depois de utilizar um assistente para criar o arquivo de modelo, utilize as <a href="https://netbeans.org/download/dev/javadoc/">APIs do NetBeans</a> para continuar a desenvolver o módulo.</p> |
| |
| <ol> |
| <li>Na janela Projetos, clique com o botão direito do mouse no nó do projeto do módulo Paint e escolha Novo > Outro. No assistente para Novo arquivo, escolha Desenvolvimento de módulo em Categorias e Ação em Tipos de arquivo. Clique em Próximo.</li> |
| |
| <li>No painel Tipo de ação, aceite os padrões. Clique em Próximo.</li> |
| <li>No painel Registro de GUI, selecione Item de menu global e selecione Barra de ferramentas global. Defina os seguintes valores: |
| <ul><li><b>Categoria:</b> Editar</li> |
| <li><b>Menu:</b> Arquivo</li> |
| <li><b>Posição:</b> Qualquer lugar que você desejar! </li> |
| <li><b>Barra de ferramentas:</b> Arquivo</li> |
| <li><b>Posição:</b> Qualquer lugar que você desejar! </li> |
| </ul> |
| <p><b class="notes">Nota:</b> O local em que a ação é posicionada não é importante, desde que ela esteja no menu Arquivo e na barra de ferramentas Arquivo.</p> |
| <p>Agora você deve ver o seguinte:</p> |
| <p><img src="../../images/tutorials/paintapp/newcanvasaction-60.png" alt="Painel de registro da GUI." /></p> |
| |
| <p>Clique em Próximo.</p></li> |
| <li>No painel Nome, ícone e localização, digite <tt>NewCanvasAction</tt> em Nome da classe e digite <tt>Nova tela</tt> em Nome de exibição. |
| |
| <p>Em Ícone, navegue até este ícone (clique com o botão direito do mouse aqui e em, seguida, salve-o na pasta <tt>org.netbeans.paint</tt>): <img src="../../images/tutorials/paintapp/new_icon.png" alt="ícone Nova tela." /></p></li> |
| |
| <li><p>Clique em Terminar.</p> |
| |
| <p>O IDE cria <tt>NewCanvasAction.java</tt> em <tt>org.netbeans.paint</tt> e abre-o no editor de código-fonte. Isto é o que você deve ver:</p> |
| |
| <pre class="examplecode">/* |
| * To change this template, choose Tools | Templates |
| * and open the template in the editor. |
| */ |
| package org.netbeans.paint; |
| |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| |
| public final class NewCanvasAction implements ActionListener { |
| |
| public void actionPerformed(ActionEvent e) { |
| // TODO implement action body |
| } |
| |
| }</pre> |
| |
| |
| |
| <p>Como especificado no painel Registro da GUI, o IDE registra a classe da ação como um item e menu e um botão da barra de ferramentas no arquivo <tt>layer.xml</tt>, junto com informações sobre o ícone e o nome de exibição.</p></li> |
| |
| |
| <li>No editor de código-fonte, abra <tt>NewCanvasAction.java</tt> e preencha o método <tt>actionPerformed()</tt> da seguinte forma: |
| |
| |
| <pre class="examplecode"> public void actionPerformed(ActionEvent e) { |
| PaintTopComponent tc = new PaintTopComponent(); |
| tc.open(); |
| tc.requestActive(); |
| }</pre> |
| <p>O que ele faz é simplesmente criar uma nova instância do nosso componente de edição de imagem, abrí-lo de modo que ele apareça na janela principal e ativá-lo, enviando o foco do teclado para ele e selecionando sua aba.</p></li> |
| </ol> |
| |
| <h2 class="tutorial"><a name="defSave"></a>Criando o item de menu Salvar tela</h2> |
| |
| <p>Como na seção anterior, utilizamos o assistente para Nova ação a fim de criar um item de menu, dessa vez para salvar imagens.</p> |
| |
| <ol> |
| <li>Na janela Projetos, clique com o botão direito do mouse no nó do projeto do módulo Paint e escolha Novo > Outro. No assistente para Novo arquivo, escolha Desenvolvimento de módulo em Categorias e Ação em Tipos de arquivo. Clique em Próximo.</li> |
| |
| <li>No painel Tipo de ação, aceite os padrões. Clique em Próximo.</li> |
| <li>No painel Registro de GUI, selecione Item de menu global e selecione Barra de ferramentas global. Defina os seguintes valores: |
| |
| <ul><li><b>Categoria:</b> Editar</li> |
| <li><b>Menu:</b> Arquivo</li> |
| <li><b>Posição:</b> Qualquer lugar que você desejar! </li> |
| <li><b>Barra de ferramentas:</b> Arquivo</li> |
| <li><b>Posição:</b> Qualquer lugar que você desejar!</li> |
| </ul> |
| <p><b class="notes">Nota:</b> o local em que a ação é posicionada não é importante, desde que ela esteja no menu Arquivo e na barra de ferramentas Arquivo.</p> |
| |
| |
| Clique em Próximo.</li> |
| <li>No painel Nome, ícone e localização, digite <tt>SaveCanvasAction</tt> em Nome da classe e digite <tt>Salvar tela</tt> em Nome de exibição. |
| |
| <p>Em Ícone, cole esse ícone (clique com o botão direito do mouse aqui e salve-o na pasta <tt>org.netbeans.paint</tt>):</p> |
| <img src="../../images/tutorials/paintapp/save_icon.png" alt="Salvar ícone de tela." /></li> |
| |
| <li>Clique em Terminar. |
| |
| <p>O IDE cria <tt>SaveCanvasAction.java</tt> em <tt>org.netbeans.paint</tt> e abre-o no editor de código-fonte. </p></li> |
| |
| <li>Altere a assinatura da classe para que <tt>CallableSystemAction</tt> seja estendida e <tt>PropertyChangeListener</tt> seja implementada: |
| |
| <pre class="examplecode">public final class SaveCanvasAction extends CallableSystemAction implements PropertyChangeListener</pre></li> |
| |
| <li>No editor de código-fonte, certifique-se de que <tt>SaveCanvasAction.java</tt> está aberto e preencha o método <tt>actionPerformed()</tt> da seguinte forma: |
| |
| <pre class="examplecode"> @Override |
| public void actionPerformed(ActionEvent e) { |
| TopComponent tc = TopComponent.getRegistry().getActivated(); |
| |
| if (tc instanceof PaintTopComponent) { |
| |
| try { |
| ((PaintTopComponent) tc).saveAs(); |
| } catch (IOException ioe) { |
| ErrorManager.getDefault().notify(ioe); |
| } |
| |
| } else { |
| |
| //Theoretically the active component could have changed |
| //between the time the menu item or toolbar button was |
| //pressed and when the action was invoked. Not likely, |
| //but theoretically possible |
| Toolkit.getDefaultToolkit().beep(); |
| |
| } |
| }</pre> |
| <p>Pressione Ctrl-Shift-I para gerar as instruções de importação necessárias: </p> |
| <img src="../../images/tutorials/paintapp/fiximports-60.png" alt="Corrigir importações." /></li> |
| |
| <li>Preencha os métodos da classe <tt>CallableSystemAction</tt> da seguinte maneira: |
| |
| <pre class="examplecode"> @Override |
| public String getName() { |
| return "Save Canvas"; |
| } |
| |
| @Override |
| public HelpCtx getHelpCtx() { |
| return null; |
| } |
| </pre> </li> |
| |
| <li>Preencha o método <tt>propertyChange()</tt> da classe <tt>PropertyChangeListener</tt> da seguinte maneira: |
| |
| <pre class="examplecode"> @Override |
| public void propertyChange(PropertyChangeEvent evt) { |
| |
| if (TopComponent.Registry.PROP_ACTIVATED.equals(evt.getPropertyName())){ |
| updateEnablement(); |
| } |
| |
| }</pre> |
| |
| <p>Quando uma linha vermelha aparecer, clique em Alt + Enter para permitir o IDE criar um método <tt>updateEnablement()</tt> na classe <tt>SaveCanvasAction</tt>.</p></li> |
| |
| <li>Em seguida, defina o método <tt>updateEnablement()</tt>: |
| |
| <pre class="examplecode"> private void updateEnablement() { |
| |
| setEnabled(TopComponent.getRegistry().getActivated() |
| instanceof PaintTopComponent); |
| |
| }</pre></li> |
| |
| <li>Finalmente, defina o construtor: |
| |
| <pre class="examplecode"> public SaveCanvasAction() { |
| |
| TopComponent.getRegistry().addPropertyChangeListener ( |
| WeakListeners.propertyChange(this, |
| TopComponent.getRegistry())); |
| |
| updateEnablement(); |
| |
| }</pre> |
| |
| <p>Quando uma linha vermelha aparece, clique em Alt + Enter para permitir ao IDE importar <tt>org.openide.util.WeakListeners</tt>.</p> |
| |
| <p>O código principal de interesse é a adição do ouvinte de alteração de propriedade. <tt>TopComponent.Registry</tt> é um registro de todos os <tt>TopComponents</tt> abertos no sistema: todas as abas abertas. O que queremos fazer é ouvir as alterações e ativar e desativar a ação dependendo do que possui o foco.</p> |
| |
| <b class="notes">Nota:</b> em vez de anexar diretamente um ouvinte de alteração de propriedade, chame <tt>WeakListeners.propertyChange()</tt>. O que ele faz é gerar um ouvinte de alteração de propriedade que se refere ligeiramente à sua ação. Na prática, sua ação existirá enquanto o aplicativo estiver aberto, é uma boa e duradoura prática, utilizar um ouvinte fraco, se um ouvinte estiver anexado e não houver código que o desanexe. Caso contrário, você terá um vazamento de memória potencial: sua ação nunca poderia ter o lixo recolhido porque o registro está mantendo uma referência a ele em sua lista de ouvintes. |
| </li> |
| </ol> |
| |
| <p>Isso é o que você deve ver agora na janela Projetos:</p> |
| |
| <p><img src="../../images/tutorials/paintapp/final-paint-module.png" alt="visualização final da janela Projetos" /></p> |
| |
| <h2><a name="wrappingUp"></a>Empacotando</h2> |
| <p>É claro que você deseja criar um aplicativo aprimorado. Assim, há algumas etapas finais que podem ser realizadas. Primeiro, crie uma tela de abertura para o aplicativo e, em seguida, uma distribuição de ZIP e um aplicativo JNLP.</p> |
| |
| <ol> |
| <li>Execute o projeto <tt>PaintApp</tt>. Depois que o aplicativo é iniciado, redimensione a tela principal de forma que fique bem pequena e desenhe uma tela de abertura. Utilize o botão Salvar para salvar a tela de abertura. </li> |
| <li>No projeto original, clique com o botão direito do mouse no nó <tt>PaintApp</tt>, escolha Propriedades e, em seguida, clique em Construir na caixa de diálogo Propriedades do projeto.</li> |
| |
| <li>Selecione Criar aplicativo independente. Agora é possível especificar um nome de marca (que será o nome do iniciador que o IDE pode gerar para você) e um título de aplicativo (que aparecerá na barra de título do aplicativo). Como padrão, você deve ver o seguinte: |
| |
| <p><img src="../../images/tutorials/paintapp/splashscreen1-60.png" alt="tela de abertura" /></p></li> |
| |
| <li>Clique em Tela de abertura. Vá para a sua tela de abertura. Se não possuir uma, utilize <a href="https://platform.netbeans.org/images/tutorials/paintapp/splash.gif">esta</a>. Clique em OK para anexá-la ao seu aplicativo: |
| <p><img src="../../images/tutorials/paintapp/splashscreen-60.png" alt="tela de abertura" /></p></li> |
| |
| <li>Agora, no arquivo <tt>layer.xml</tt> do módulo do Paint, adicione as marcas seguintes na pasta Menu. Essas marcas removem os menus Ir para e Exibir, dos quais o aplicativo Paint não precisam. |
| |
| <pre class="examplecode"><file name="GoTo_hidden"/> |
| <file name="View_hidden"/></pre> |
| |
| <p>Alternativamente, em vez de adicionar manualmente as marcas acima, é possível excluir as pastas no nó <tt><esta camada no contexto></tt> do arquivo <tt>layer.xml</tt>. Para fazer isso, expanda <tt><esta camada no contexto></tt> e, em seguida, expanda o nó Barra de menus. Escolha Excluir no menu do botão direito do mouse de ambos os nós Ir para e Exibir.</p></li> |
| |
| <li>Finalmente, execute o aplicativo novamente e observe a tela de abertura. Quando o aplicativo tiver sido inicializado, observe que a barra de título exibe o título que você especificou. Além disso, existem muito menos itens de menu, botões da barra de ferramentas e outros recursos: <img src="../../images/tutorials/paintapp/result-without-menus-60.png" alt="resultados sem menus" /> |
| </li> |
| </ol> |
| |
| <h2 class="tutorial"><a name="creatingDist"/>Criando uma distribuição</h2> |
| |
| <p> |
| Agora, é hora de escolher o meio de distribuição. Clique com o botão direito do mouse no nó <tt>PaintApp</tt> e escolha Criar distribuição de ZIP para empacotar o aplicativo inteiro, com todos os módulos e arquivos necessários, como um arquivo zip. Você também pode escolher Construir aplicativo JNLP para criar uma versão JavaWebStart™ do aplicativo que você pode colocar em um serviço Web e vincular diretamente a partir de uma página da Web (você precisa definir uma URL correta — o descritor gerado usa arquivo: protocolo de forma que você possa testar localmente sua distribuição iniciável via Web).</p> |
| |
| |
| <p>Isso é tudo! Você completou seu aplicativo construído sobre a plataforma NetBeans. Próxima parada: <a href="https://platform.netbeans.org/tutorials/nbm-feedreader.html">Tutorial Feed Reader da Plataforma NetBeans</a>.</p> |
| |
| <div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&subject=Feedback: NetBeans Platform Paint Application Tutorial">Envie-nos seus comentários</a></div> |
| |
| </body> |
| </html> |