| <!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 do Feed Reader para a Plataforma NetBeans 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="FeedReader on 6.0."> |
| <!-- Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved. --> |
| <!-- Use is subject to license terms.--> |
| </head> |
| <body> |
| <H1> |
| |
| Tutorial do Feed Reader para a Plataforma NetBeans |
| |
| </H1> |
| |
| |
| <p> |
| Bem-vindo ao tutorial do Feed Reader para a Plataforma NetBeans. O Feed Reader construído neste tutorial é um simples navegador RSS/Atom feed, modelado de acordo com o plug-in Sage para Mozilla Firefox. Ele apresenta uma árvore de feeds com subnós representando entradas individuais de feeds que podem ser abertas em um navegador. |
| </p><p>Para ilustrar o resultado final, aqui você vê o Feed Reader que será construído neste tutorial, exibindo uma entrada de feed do <a href="https://netbeans.org/rss-091.xml">feed Destaques do NetBeans</a>:</P> |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-result.png" border="1"/> |
| </div> |
| |
| <p></p><p><b>Conteúdo</b></p> |
| |
| <img src="../../images/articles/60/netbeans-stamp60-61.gif" class="stamp" width="114" height="114" alt="O conteúdo desta página se aplica ao IDE NetBeans 6.1 " title="O conteúdo desta página se aplica ao IDE NetBeans 6.1"> </p> |
| <ul class="toc"> |
| <li><A HREF="#knowledge" CLASS="XRef">Conhecimento necessário</A> |
| </li><li><A HREF="#setting" CLASS="XRef">Configurando o aplicativo</A> |
| </li><li><A HREF="#creating" CLASS="XRef">Criando a janela Feed Reader</A> |
| </li><li><A HREF="#running" CLASS="XRef">Executando a aplicação</A> |
| </li><li><A HREF="#adding" CLASS="XRef">Adicionando o código ao aplicativo</A> |
| </li><li><A HREF="#branding" CLASS="XRef">Identificando a marca do aplicativo</A> |
| </li><li><A HREF="#distributing" CLASS="XRef">Distribuindo a aplicação</A> |
| </li></ul> |
| |
| <p><b>Para seguir este tutorial, você 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ão necessária</th> |
| </tr> |
| <tr> |
| <td class="tbltd1">NetBeans IDE</td> |
| <td class="tbltd1">versão <a href="http://download.netbeans.org/netbeans/6.1/final/">versão 6.1</a> ou<br> |
| versã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ão 6</a> ou<br> |
| versão 5</td> |
| </tr> |
| <tr> |
| <td class="tbltd1">Utilitários Rss e atom (<A HREF="https://rome.dev.java.net/" CLASS="URL">download</A></tt>)</td> |
| <td class="tbltd1"></td> |
| </tr> |
| <tr> |
| <td class="tbltd1">Rome Fetcher (<A HREF="http://wiki.java.net/bin/view/Javawsxml/RomeFetcherRelease06" CLASS="URL">download</A></tt>)</td> |
| <td class="tbltd1"></td> |
| </tr> |
| <tr> |
| <td class="tbltd1">JDom (<A HREF="http://jdom.org/downloads/index.html" CLASS="URL">download</A></tt>)</td> |
| <td class="tbltd1"></td> |
| </tr> |
| <tr> |
| <td class="tbltd1">Ícone e tela de splash do FeedReader (<A HREF="https://netbeans.org/files/documents/4/550/feedreader-images.zip" CLASS="URL">download</A></tt>).</td> |
| <td class="tbltd1"></td> |
| </tr> |
| </tbody> |
| </table> |
| |
| |
| |
| <h2><a name="knowledge"></a> Conhecimento de pré-requisito</H2> |
| <p>Você não precisa ter qualquer conhecimento sobre desenvolvimento da Plataforma NetBeans para trabalhar neste tutorial. Pode ser útil se você tiver algum conhecimento sobre programação Java, embora isso não seja essencial. Entretanto, a leitura dos seguintes documentos antes de iniciar este tutorial pode ser útil, para fornecer informações de suporte: |
| |
| </p><ul> |
| <li><a href="https://platform.netbeans.org/tutorials/60/nbm-feedreader_background.html">Preparando para criar o aplicativo FeedReader</a>. Este documento fornece o plano de fundo deste tutorial. Ele o conduz por tudo que será feito neste tutorial, conceitualmente. Ele também mostra onde encontrar o código-fonte da amostra construída neste tutorial.</li> |
| <li><a href="../61/nbm-htmleditor_pt_BR.html">NetBeans Platform Quick Start</a>. Este tutorial breve fornece orientação através de um processo completo de criação de um aplicativo de cliente avançado sobre a Plataforma NetBeans. As principais ferramentas e os estágios de desenvolvimento são abordados, e o Editor de HTML é o resultado do tutorial.</li> |
| </ul> |
| |
| <h2><a name="setting"></a> Configurando a aplicação</H2> |
| <p> |
| No NetBeans IDE, a construção de um aplicativo sobre a Plataforma NetBeans começa com a criação de vários arquivos que irão servir como base para o aplicativo. Por exemplo, o IDE fornece um Assistente de projeto de módulo, um Assistente de projeto de suíte de módulos e um Assistente de projeto de módulo de wrapper de bibliotecas que configuram todos os arquivos básicos que os módulos e aplicativos construídos na Plataforma NetBeans precisam.</P> |
| <UL> |
| <li> |
| <b>Projeto de suíte de módulos.</b> Um projeto que agrupa um conjunto de projetos de módulos e projetos de módulo de wrapper de bibliotecas que possuem dependências entre eles, e permite que você implante-os juntos como uma unidade.</li> |
| <li> |
| <b>Projeto de módulo de wrapper de bibliotecas.</b> Um projeto que coloca um arquivo JAR de biblioteca no seu classpath e exporta alguns ou todos os pacotes do arquivo JAR do módulo como pacotes públicos.</li> |
| <li> |
| <b>Projeto de módulo.</b> Um projeto para implementar a funcionalidade, lógica comercial e a interface do usuário de um módulo ou aplicativo construído na Plataforma NetBeans.</li> |
| </UL> |
| <h3> |
| Criando o projeto de suíte de módulos</H3> |
| <ol> |
| <li> |
| Escolha Arquivo > Novo projeto (Ctrl-Shift-N). Em Categorias, selecione Módulos do NetBeans. Em Projetos, selecione Projeto de suíte de módulos. Você deve ver o seguinte:</p> |
| <p><IMG SRC="../../images/tutorials/feedreader/60-suite-wiz.png" border="1"/> |
| </p><p>Clique em Próximo.</p></li> |
| <li> |
| No painel Nome e localização, digite <tt> feedreader-suite</tt> em Nome do projeto. |
| Altere Local do projeto para qualquer diretório no computador. Agora você deve ver o seguinte:</p> |
| <p><IMG SRC="../../images/tutorials/feedreader/60-suite-wiz2.png" border="1"/> |
| |
| </p><p>Clique em Terminar.</p></li> |
| </ol> |
| |
| <p>O IDE cria o projeto <tt> feedreader-suite</tt>, que tem a seguinte aparência na janela Projetos:</p> |
| <p><IMG SRC="../../images/tutorials/feedreader/60-suite.png" border="1"/> |
| |
| |
| </p><p>O projeto conterá o projeto de módulo e os projetos de módulo de wrapper de bibliotecas que você criará nas seguintes subseções. </P> |
| |
| <h3> |
| Empacotando as bibliotecas</H3> |
| |
| Você pode empacotar todo o aplicativo Feed Reader em um único módulo. Entretanto, o aplicativo precisa das bibliotecas Rome, Rome Fetcher e JDom:</P> |
| <UL> |
| <li> |
| <b>Rome.</b> Lê RSS e Atom feeds, usando uma API muito simples. </li> |
| <li> |
| <b>Rome Fetcher.</b> Permite a recuperação de feeds via HTTP. </li> |
| <li> |
| <b>JDom.</b> É uma API de análise de XML. O Feed Reader só precisará dela porque ela é utilizada pela biblioteca Rome.</li> |
| </UL> |
| |
| Posteriormente, se você desejar estender o aplicativo Feed Reader com mais módulos que possam usar estas bibliotecas, seria bom que eles dependessem somente dos módulos de biblioteca, e não de todo o Feed Reader. Além disso, os módulos de biblioteca podem ser de "carregamento automático", o que significa que o NetBeans só os carregará quando necessário. Até que isso aconteça, ele não utilizará nenhuma memória em tempo de execução.</P> |
| <ol> |
| <li>Clique com o botão direito do mouse no nó Módulos no projeto de suíte de módulos na janela Projetos, conforme mostrado abaixo, e clique em Adicionar nova biblioteca:</p> |
| <p><IMG SRC="../../images/tutorials/feedreader/60-add-lib0.png" border="1"/> |
| </p><p>Quando você fizer isso, deve ver o seguinte: </p> |
| <p><IMG SRC="../../images/tutorials/feedreader/60-lib-wiz.png" border="1"/> |
| |
| </p></li><li> |
| No painel Selecionar biblioteca, mostrado acima, vá até a pasta onde baixou JDom e selecione <tt> jdom.jar</tt> e <tt> LICENSE.txt.</tt> Clique em Próximo.</li> |
| <li> |
| No painel Nome e localização, aceite todos os padrões. Você deve ver o seguinte:</p> |
| <p><IMG SRC="../../images/tutorials/feedreader/60-lib-wiz3.png" border="1"/> |
| |
| |
| </p><p><b>Observação:</b> o projeto de módulo de wrapper de bibliotecas será armazenado no projeto de suíte de módulos. Você também poderia armazená-lo em outro lugar, mas por questões de versionamento, é melhor colocá-lo no projeto de suíte de módulos. Por isso, o projeto de suíte de módulos <tt> feedreader-suite</tt> é selecionado na lista suspensa Adicionar à suíte de módulos.</p> |
| <p>Clique em Próximo.</p></li> |
| <li> |
| No painel Configuração básica de módulos, aceite todos os padrões. Você deve ver o seguinte:</p> |
| <p><IMG SRC="../../images/tutorials/feedreader/60-lib-wiz2.png" border="1"/> |
| |
| |
| |
| |
| </p><p>Clique em Terminar.</p> |
| <p>O novo projeto de módulo de wrapper de bibliotecas é aberto no IDE e exibido na janela Projetos. Agora você deve ver o seguinte na janela Projetos:</P> |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-lib-wiz4.png" border="1"> |
| </div></li> |
| <li> |
| Retorne para a etapa 1 desta seção e crie um projeto de módulo de wrapper de bibliotecas para Rome. Aceite todos os padrões.</li> |
| <li> |
| Retorne para a etapa 1 desta seção e crie um projeto de módulo de wrapper de bibliotecas para Rome Fetcher. Aceite todos os padrões.</li> |
| </ol> |
| |
| <p>Você agora possui um projeto de suíte de módulos, com três projetos de módulo de wrapper de bibliotecas, fornecendo muitas classes Javas úteis que você poderá utilizar ao longo de todo este tutorial. |
| |
| |
| </p><h3> |
| Criando o projeto do módulo </H3> |
| <p>Nesta seção, criaremos um projeto para a funcionalidade que o seu aplicativo fornecerá. O projeto utilizará as classes disponibilizadas pelos módulos de wrapper de bibliotecas criados na seção anterior.</p> |
| <ol> |
| <li> |
| Clique com o botão direito do mouse no nó Módulos no projeto de suíte de módulos na janela Projetos, conforme mostrado abaixo, e clique em Adicionar novo:</p> |
| <p><IMG SRC="../../images/tutorials/feedreader/60-module-project.png" border="1"/> |
| </p><p>Quando você fizer isso, deve ver o seguinte: </p> |
| <p><IMG SRC="../../images/tutorials/feedreader/60-module-wiz.png" border="1"/> |
| </p></li> |
| <li> |
| No painel Nome e localização, digite <tt> FeedReader</tt> em Nome do projeto. |
| Aceite todos os padrões. Clique em Próximo. |
| </li><li> |
| No painel Configuração básica de módulos, substitua <tt> yourorghere</tt> em Nome base de código por <tt> myorg</tt> , de maneira que o nome base de código inteiro seja <tt> org.myorg.feedreader.</tt> Digite <tt>FeedReader</tt> in Module Display Name. Deixe o local do pacote de localização e a camada XML, para que sejam armazenados em um pacote com o nome <tt> org/myorg/feedreader.</tt> Agora você deve ver o seguinte:</p> |
| <p><IMG SRC="../../images/tutorials/feedreader/60-module-wiz2.png" border="1"/> |
| </p><p></p><p> |
| Clique em Terminar.</p></li> |
| </ol> |
| <p> |
| O IDE cria o projeto FeedReader. O projeto contém todos os metadados de projeto e códigos-fonte do módulo, como o script de construção Ant do projeto. O projeto se abre no IDE. Você pode ver a estrutura lógica na janela Projetos (Ctrl-1) e a estrutura de arquivos na janela Arquivos (Ctrl+2). A janela Projetos agora deve mostrar o seguinte:</P> |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-module.png" border="1"> |
| </div> |
| |
| <p></p><p>Você criou a estrutura do código-fonte do novo aplicativo. Na próxima seção, começaremos adicionando algum código. |
| |
| </p><h2><a name="creating"></a> Criando a janela Feed Reader</H2> |
| <p> |
| Nesta seção, você usará o Assistente de componente de janela para gerar arquivos que criam um componente de janela personalizado e uma ação para chamá-lo. O assistente também registra a ação como um item de menu no arquivo de configuração <tt> layer.xml </tt> e adiciona entradas para serializar o componente de janela. Logo após o término desta seção, você saberá como testar os arquivos que o Assistente de componente de janela gera para você.</P> |
| <ol> |
| <li> |
| Clique com o botão direito do mouse no nó do projeto <tt> FeedReader</tt> e escolha Novo > Outro. Em Categorias, selecione Desenvolvimento de módulo. Em Tipos de arquivos, selecione Componente de janela, conforme mostrado abaixo:</p> |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-windowcomp-wiz.png" border="1"> |
| </div> |
| |
| <p> |
| </p><p>Clique em Próximo.</p></li> |
| <li> |
| No painel Configurações básicas, selecione <tt>explorer</tt> na lista suspensa e clique em Abrir na inicialização do aplicativo, conforme mostrado abaixo:</p> |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-windowcomp-wiz2.png" border="1"> |
| </div> |
| |
| <p></p><p>Clique em Próximo.</p></li> |
| <li> |
| No painel Nome e localização, digite Feed como o Prefixo do nome da classe e vá até o local onde o arquivo <tt>rss16.gif (<IMG SRC="../../images/tutorials/feedreader/rss16.gif" />) foi salvo.</tt> O arquivo GIF será mostrado no item de menu que chama a ação. Agora você deve ver o seguinte:</p> |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-windowcomp-wiz3.png" border="1"> |
| </div> |
| |
| |
| <p></p><p>Clique em Terminar.</p></li> |
| </ol> |
| <p>O seguinte é mostrado agora na janela Projetos: |
| |
| </p><div> |
| <IMG SRC="../../images/tutorials/feedreader/60-windowcomp.png" border="1"> |
| </div> |
| |
| |
| <p></p><p>O IDE criou os novos arquivos a seguir:</P> |
| <UL> |
| <li> |
| <tt> FeedAction.java.</tt> Defina a ação que aparece no menu Janela com o rótulo Abrir janela de feed e a imagem <tt> rss16.gif</tt> (<IMG SRC="../../images/tutorials/feedreader/rss16.gif" />). Ele abre a janela Feed. </li> |
| <li> |
| <tt> FeedTopComponent.java.</tt> Define a janela Feed. </li> |
| <li> |
| <tt> FeedTopComponentSettings.xml.</tt> Especifica todas as interfaces do aplicativo rich-client <tt> org.myorg.feedreader</tt>. Possibilita a pesquisa fácil de instâncias, sem a necessidade de instanciar cada uma. Evita a necessidade de carregar classes ou criar objetos e, portanto, aumenta o desempenho. Registrado na pasta <tt>Windows2/Components</tt> do arquivo <tt>layer.xml</tt>.</li> |
| <li> |
| <tt> FeedTopComponentWstcref.xml.</tt> Especifica uma referência ao componente. Permite que o componente pertença a mais de um modo. Registrado na pasta <tt>Windows2/Modes</tt> do arquivo <tt>layer.xml</tt>.</li> |
| </UL> |
| |
| O IDE modificou os arquivos existentes a seguir:</P> |
| <UL> |
| <li> |
| <b> </b> <A NAME="project.xml"></A><tt> project.xml.</tt> Duas dependências de módulo foram adicionadas, <tt> API de utilitários </tt> (clique <A HREF="http://bits.netbeans.org/dev/javadoc/org-openide-util/overview-summary.html" CLASS="URL">aqui </A></tt> para Javadoc) e <tt> API do sistema Window </tt> (clique <A HREF="http://bits.netbeans.org/dev/javadoc/org-openide-windows/overview-summary.html" CLASS="URL">aqui</A></tt> para Javadoc).</li> |
| <li> |
| <tt> Bundle.properties.</tt> <A NAME="Bundle.properties"></A> Três pares de chave-valor foram adicionados:<br> |
| |
| <ul> |
| <li><tt>CTL_FeedAction.</tt> Localiza o rótulo do item de menu, definido em <tt>FeedAction.java</tt>. |
| </li><li><tt>CTL_FeedTopComponent.</tt> Localiza o rótulo de <tt>FeedTopComponent.java</tt>. |
| </li><li><tt>HINT_FeedTopComponent.</tt> Localiza a dica de ferramenta de <tt>FeedTopComponent.java</tt>. |
| </li></ul> |
| |
| </li> |
| </UL> |
| |
| <p>Finalmente, três entradas de registro foram adicionadas ao arquivo <tt>layer.xml</tt>.</li> |
| |
| </p><p> |
| Isto é o que as entradas no arquivo <tt> layer.xml</tt> fazem:</P> |
| <UL> |
| <li> |
| <tt> <Ações></tt> |
| <br> |
| Registra a ação como uma ação na pasta Janela.</li> |
| <li> |
| <tt> <Menu></tt> |
| <br> |
| Registra a ação como um item de menu no menu Janela.</li> |
| <li> |
| <tt> <Windows2> <br> |
| </tt> Registra o arquivo <tt>FeedTopComponentSettings.xml</tt>, que é usado para pesquisar o componente de janela. Registra o arquivo de referência do componente <tt>FeedTopComponentWstcref.xml</tt> na área do "explorer". |
| <br> |
| </tt> |
| </li> |
| </UL> |
| <h2><a name="running"></a> Executando a aplicação</H2> |
| <p> |
| Sem ter digitado uma única linha de código, ainda é possível fazer um teste com o aplicativo. Testar significa implantar os módulos na Plataforma NetBeans e depois verificar se a janela Feed vazia é exibida corretamente.</P> |
| |
| <ol> |
| <li>Vamos primeiro remover todos os módulos que definem o NetBeans IDE, mas que não serão necessários no aplicativo Feed Reader. Clique com o botão direito do mouse no projeto <tt>feedreader-suite</tt>, escolha Propriedades e clique em Bibliotecas na caixa de diálogo Propriedades do projeto.</p> |
| |
| <p>É mostrada uma lista de 'grupos'. Cada cluster é um conjunto de módulos relacionados. O único cluster que precisaremos será o de plataforma. Assim, desmarque todos os outros, até que somente o de plataforma esteja selecionado:</p> |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-runapp4.png" border="1"> |
| </div> |
| |
| <p></p><p>Expanda o cluster de plataforma e navegue através dos módulos fornecidos: |
| </p><div> |
| <IMG SRC="../../images/tutorials/feedreader/60-runapp5.png" border="1"> |
| </div> |
| |
| <p></p><p>Os módulos da plataforma fornecem a infra-estrutura comum de aplicativos Swing. Assim, como nós incluímos o cluster de plataforma, não será necessário criar o código 'básico' para a infra-estrutura do aplicativo, como a barra de menu, o sistema de janelas e a funcionalidade de inicialização. |
| |
| |
| </p><p></p><p>Clique em OK. |
| |
| </p></li><li>Na janela Projetos, clique com o botão direito do mouse no nó do projeto <tt> feedreader-suite</tt> e escolha Limpar e construir tudo. |
| |
| </li><li>Na janela Projetos, clique com o botão direito do mouse no projeto <tt>feedreader-suite</tt> e escolha Executar, conforme mostrado abaixo:</p> |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-runapp.png" border="1"> |
| </div> |
| </li></ol> |
| |
| <p> |
| </p><p>O aplicativo é iniciado. Você vê uma tela de abertura. Em seguida, o aplicativo é aberto e exibe a nova janela Feed, como uma janela do explorer, como mostrado abaixo:</p> |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-runapp2.png" border="1"> |
| </div> |
| |
| <p></p><p><b>Observação:</b> o que você possui agora é um aplicativo que consiste nos seguintes módulos: |
| </p><ul> |
| <li>Os módulos fornecidos pela Plataforma NetBeans, para inicialização do aplicativo, gerenciamento do ciclo de vida e outros processos relacionados à infra-estrutura. |
| </li><li>Os três módulos de wrapper de bibliotecas criados neste tutorial. |
| </li><li>O módulo da funcionalidade FeedReader criado neste tutorial, para fornecer a janela Feed. |
| </li></ul> |
| |
| |
| <p></p><p>No menu Janela do aplicativo, você verá o novo item de menu, que pode ser usado para abrir a janela Feed, caso ela esteja fechada, conforme mostrado abaixo:</li> |
| |
| |
| </p><div> |
| <IMG SRC="../../images/tutorials/feedreader/60-runapp3.png" border="1"> |
| </div> |
| <p> |
| </p><p>Como você pode ver, sem ter feito qualquer código, temos um aplicativo completo. Ainda não é muita coisa, mas a infra-estrutura já existe e funciona como esperado. Em seguida, começaremos a usar algumas das APIs do NetBeans para adicionar código ao aplicativo. |
| |
| </p><h2><a name="adding"></a>Adicionando o código ao aplicativo</H2> |
| <p> |
| Agora que a base do aplicativo está pronta, é hora de começar a adicionar seu próprio código. Antes de fazer isso, especifique as dependências do aplicativo. As dependências são módulos que fornecem as APIs do NetBeans que você irá estender ou implementar. Em seguida, use o Assistente de novo arquivo e o Editor de código-fonte para criar e codificar as classes que compõem o aplicativo Feed Reader. |
| </p><h3> |
| Especificando as dependências do aplicativo</H3> |
| |
| Você precisa criar subclasses de várias classes que pertencem às APIs do NetBeans. As classes pertencem a módulos que precisam ser declarados como dependências do aplicativo Feed Reader. Use a caixa de diálogo Propriedades do projeto para isso, conforme explicado nas etapas abaixo.</P> |
| <ol> |
| <li> |
| Na janela Projetos, clique com o botão direito do mouse no projeto <tt> FeedReader</tt> e escolha Propriedades. Na caixa de diálogo Propriedades do projeto, clique em Bibliotecas. Observe que algumas APIs já foram declaradas como Dependências do módulo, como mostrado abaixo:</p> |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-add-lib1.png" border="1"> |
| </div> |
| |
| <p> |
| </p><p>Os registros de biblioteca acima foram feitos por você pelo Assistente de componente de janela, anteriormente neste tutorial.</p></li> |
| <li> |
| Clique em Adicionar dependência.</li> |
| <li> |
| Adicione as seguintes APIs: |
| <pre class="examplecode"> |
| Actions API |
| Datasystems API |
| Dialogs API |
| Explorer and Property Sheet API |
| File System API |
| Nodes API |
| rome |
| rome-fetcher</pre> |
| |
| |
| <p>Agora você deve ver o seguinte:</p> |
| |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-add-lib2.png" border="1"> |
| </div> |
| |
| |
| <p></p><p>Clique em OK para sair da caixa de diálogo Propriedades do projeto. </p></li> |
| |
| |
| <li>Expanda o nó Bibliotecas do projeto <tt>FeedReader</tt> e observe a lista de módulos que estão disponíveis para este projeto:</p> |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-add-lib5.png" border="1"> |
| </div> |
| |
| </li></ol> |
| |
| <h3> |
| Definindo dependências entre módulos do wrapper de biblioteca</h3> |
| |
| <p>Agora que definimos as dependências nos módulos de APIs do NetBeans que iremos usar, vamos definir também as dependências entre os módulos de wrapper de bibliotecas. Por exemplo, o JAR de Rome utiliza as classes do JAR de JDom. Agora que eles estão dispostos em módulos de wrapper de biblioteca separados, é necessário especificar a relação entre os JARs através da caixa de diálogo Propriedades do projeto de módulo de wrapper de bibliotecas.</p> |
| |
| <ol> |
| <li> |
| Primeiro, vamos tornar Rome dependente de JDom. Clique com o botão direito do mouse no projeto de módulo de wrapper da biblioteca Rome na janela Projetos e escolha Propriedades. Na caixa de diálogo Propriedades do projeto, clique em Bibliotecas e, em seguida, em Adicionar dependência. Adicionar <tt>jdom</tt>. Agora você deve ver o seguinte:</p> |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-add-lib3.png" border="1"> |
| </div> |
| |
| <p></p><p>Clique em OK para sair da caixa de diálogo Propriedades do projeto.</p></li> |
| <li> |
| Finalmente, como Rome Fetcher depende de Rome e JDom, você precisa tornar Rome Fetcher dependente de Rome, como mostrado abaixo:</p> |
| |
| <div> |
| <IMG SRC="../../images/tutorials/feedreader/60-add-lib4.png" border="1"> |
| </div> |
| |
| |
| <p></p><p>Como Rome já depende de JDom, não é necessário tornar Rome Fetcher dependente de JDom. </p></li> |
| </ol> |
| <h3> |
| Criando a pasta RssFeeds</H3> |
| |
| <p>Você usará a interface do usuário do IDE para adicionar uma pasta ao arquivo <tt>layer.xml</tt>. A pasta conterá os objetos RSS feed. Posteriormente, você adicionará código ao <tt> FeedTopComponent.java</tt>, que foi criado por você pelo Assistente de componente de janela, para exibir o conteúdo desta pasta.</P> |
| <ol> |
| <li> |
| Na janela Projetos, expanda o nó do projeto <tt> FeedReader</tt>, expanda o nó Arquivos importantes e expanda o nó Camada XML. Você deve ver o seguinte nós:<p></p><p> |
| </p><ul><li><tt> <this layer>.</tt> Expõe as pastas fornecidas pelo módulo atual. Por exemplo, como você pode ver abaixo, o módulo FeedReader fornece pastas denominadas Actions, Menu e Windows2, conforme discutido anteriormente neste tutorial: |
| |
| <p></p><div> |
| <IMG SRC="../../images/tutorials/feedreader/60-feedfolder-1.png" border="1"> |
| </div> |
| |
| <p></p><p></p></li><li><tt> <this layer in context>. </tt> Expõe todas as pastas disponíveis para o aplicativo inteiro. Examinaremos este nó posteriormente neste tutorial.<br> |
| <br></li></ul> |
| </li> |
| <li> |
| Clique com o botão direito do mouse no nó <tt><esta camada></tt> e escolha Novo > Pasta, conforme mostrado abaixo: |
| |
| |
| <p></p><div> |
| <IMG SRC="../../images/tutorials/feedreader/60-feedfolder-2.png" border="1"> |
| </div> |
| |
| |
| </li> |
| <li> |
| Digite <tt>RssFeeds</tt> na caixa de diálogo Nova pasta. Clique em OK. Você agora tem uma nova pasta, como mostrado abaixo: |
| |
| <p></p><div> |
| <IMG SRC="../../images/tutorials/feedreader/60-feedfolder-3.png" border="1"> |
| </div> |
| |
| |
| </li><li>Clique duas vezes no nó do arquivo <tt>layer.xml</tt> para que ele seja aberto no Editor de código-fonte. Observe que esta entrada foi adicionada:<br> |
| <tt> |
| <br> |
| <folder name="RssFeeds"/></tt> |
| </li> |
| </ol> |
| <h3> |
| Criando o objeto Feed</H3> |
| |
| <p>Em seguida, você criará um POJO simples para encapsular uma URL e seu Rome feed associado.</p> |
| <ol> |
| <li> |
| Clique com o botão direito do mouse no nó do projeto <tt> FeedReader</tt> e selecione Novo > Classe Java. Clique em Próximo. </li> |
| <li> |
| Nomeie a classe como <tt>Feed</tt> e selecione <tt>org.myorg.feedreader</tt> na lista suspensa Pacote. Clique em Terminar.</li> |
| <li> |
| No Editor de código-fonte, substitua a classe padrão <tt>Feed</tt> pela seguinte:</li> |
| </ol> |
| <pre class="examplecode">public class Feed implements Serializable { |
| |
| private static FeedFetcher s_feedFetcher |
| = new HttpURLFeedFetcher(HashMapFeedInfoCache.getInstance()); |
| private transient SyndFeed m_syndFeed; |
| private URL m_url; |
| private String m_name; |
| |
| protected Feed() { |
| } |
| |
| public Feed(String str) throws MalformedURLException { |
| m_url = new URL(str); |
| m_name = str; |
| } |
| |
| public URL getURL() { |
| return m_url; |
| } |
| |
| public SyndFeed getSyndFeed() throws IOException { |
| if (m_syndFeed == null) { |
| try { |
| m_syndFeed = s_feedFetcher.retrieveFeed(m_url); |
| if (m_syndFeed.getTitle() != null) { |
| m_name = m_syndFeed.getTitle(); |
| } |
| } catch (Exception ex) { |
| throw new IOException(ex.getMessage()); |
| } |
| } |
| return m_syndFeed; |
| } |
| |
| @Override |
| public String toString() { |
| return m_name; |
| } |
| |
| }</pre> |
| |
| Uma grande parte do código é sublinhada, pois você não declarou seus pacotes. Você fará isso nas próximas etapas. </P> |
| |
| Utilize as etapas a seguir para reformatar o arquivo e declarar suas dependências:</P> |
| <ol> |
| <li> |
| Pressione Alt-Shift-F para reformatar o código. </li> |
| <li> |
| Pressione Ctrl-Shift-I e certifique-se de que os seguintes comandos import sejam selecionados: |
| |
| |
| <p></p><div> |
| <IMG SRC="../../images/tutorials/feedreader/60-imports.png" border="1"> |
| </div> |
| |
| |
| <p></p><p>Clique em OK e o IDE adicionará os seguintes comandos import à classe: |
| |
| </p><pre class="examplecode">import com.sun.syndication.feed.synd.SyndFeed; |
| import com.sun.syndication.fetcher.FeedFetcher; |
| import com.sun.syndication.fetcher.impl.HashMapFeedInfoCache; |
| import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher; |
| import java.io.IOException; |
| import java.io.Serializable; |
| import java.net.MalformedURLException; |
| import java.net.URL;</pre> |
| </li> |
| </ol> |
| |
| Todo o sublinhado vermelho deve ter desaparecido. Caso não tenha, prossiga com este tutorial até que você tenha solucionado o problema.</P> |
| <h3> |
| Estendendo a janela Feed</H3> |
| <ol> |
| <li> |
| Clique duas vezes em <tt> FeedTopComponent.java</tt> para abri-lo no editor de código-fonte.</li> |
| <li> |
| Digite <tt>implements ExplorerManager.Provider</tt> no final da declaração da classe.</li> |
| <li> |
| Pressione Alt-Enter na linha e clique na sugestão. O IDE adiciona um comando import para o pacote necessário <tt>org.openide.explorer.ExplorerManager</tt>.</li> |
| <li> |
| Pressione Alt-Enter novamente e clique na sugestão. O IDE implementa o método abstrato <tt>getExplorerManager()</tt>. </li> |
| <li> |
| Digite <tt>return manager;</tt> no corpo do novo método <tt>getExplorerManager()</tt>. Pressione Alt-Enter na linha e deixe que o IDE crie um campo chamado <tt>manager</tt> para você. Substitua a definição padrão por esta: |
| <pre class="examplecode">private final ExplorerManager manager = new ExplorerManager();</pre> |
| </li> |
| <li> |
| Logo abaixo da declaração de campo na etapa anterior, declare este:<br> |
| <pre class="examplecode">private final BeanTreeView view = new BeanTreeView();</pre> |
| </li> |
| <li> |
| Finalmente, adicione o seguinte código ao final do construtor:<br> |
| <pre class="examplecode">setLayout(new BorderLayout()); |
| add(view, BorderLayout.CENTER); |
| view.setRootVisible(true); |
| try { |
| manager.setRootContext(new RssNode.RootRssNode()); |
| } catch (DataObjectNotFoundException ex) { |
| ErrorManager.getDefault().notify(ex); |
| } |
| ActionMap map = getActionMap(); |
| map.put("delete", ExplorerUtils.actionDelete(manager, true)); |
| associateLookup(ExplorerUtils.createLookup(manager, map));</pre> |
| </li> |
| </ol> |
| |
| <p> |
| Uma grande parte do código é sublinhada, pois você não declarou seus pacotes associados. Você fará isso nas próximas etapas. </P> |
| <p> |
| Utilize as etapas a seguir para reformatar o arquivo e declarar suas dependências:</P> |
| <ol> |
| <li> |
| Pressione Alt-Shift-F para reformatar o código. </li> |
| <li> |
| Pressione Ctrl-Shift-I, selecione <tt>org.openide.ErrorManager</tt>, clique em OK, e o IDE adiciona vários comandos import abaixo do comando package. A lista completa de comandos import agora deve ser a seguinte: |
| |
| <pre class="examplecode">import java.awt.BorderLayout; |
| import java.io.Serializable; |
| import javax.swing.ActionMap; |
| import org.openide.ErrorManager; |
| import org.openide.explorer.ExplorerManager; |
| import org.openide.explorer.ExplorerUtils; |
| import org.openide.explorer.view.BeanTreeView; |
| import org.openide.loaders.DataObjectNotFoundException; |
| import org.openide.util.NbBundle; |
| import org.openide.util.RequestProcessor; |
| import org.openide.util.Utilities; |
| import org.openide.windows.TopComponent;</pre> |
| |
| </li> |
| <li> |
| Observe que a linha <tt>manager.setRootContext(new RssNode.RootRssNode());</tt> ainda está sublinhada em vermelho, porque você ainda não criou <tt>RssNode.java</tt>. Você fará isso na próxima subseção. Todo o sublinhado vermelho restante deve ter desaparecido. Caso não tenha, prossiga com este tutorial até que você tenha solucionado o problema.</li> |
| </ol> |
| <h3> |
| Criando a classe RssNode</H3> |
| |
| <p></p><p>O nó de nível superior do Feed Reader é fornecido pela classe RssNode. A classe estende <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/FilterNode.html">FilterNode</a></tt>, que representa o nó 'RssFeeds'. Aqui definimos um nome de exibição e declaramos dois itens de menu, 'Adicionar' e 'Adicionar pasta', conforme mostrado a seguir: |
| |
| </p><p></p><div> |
| <IMG SRC="../../images/tutorials/feedreader/60-actions.png" border="1"> |
| </div></p> |
| |
| <p>Realize as seguintes etapas para criar esta classe: |
| |
| </p><ol> |
| <li> |
| Crie <tt> RssNode.java</tt> no pacote <tt> org.myorg.feedreader</tt>.</li> |
| <li> |
| Substitua a classe padrão pela seguinte:</li> |
| </ol> |
| <pre class="examplecode">public class RssNode extends FilterNode { |
| |
| public RssNode(Node folderNode) throws DataObjectNotFoundException { |
| super(folderNode, new RssFolderChildren(folderNode)); |
| } |
| |
| @Override |
| public Action[] getActions(boolean popup) { |
| |
| <b>//Declare our actions |
| //and pass along the node's data folder:</b> |
| DataFolder df = getLookup().lookup(DataFolder.class); |
| return new Action[]{ |
| new AddRssAction(df), |
| new AddFolderAction(df) |
| }; |
| |
| } |
| |
| public static class RootRssNode extends RssNode { |
| |
| <b>//The filter node will serve as a proxy |
| //for the 'RssFeeds' node, which we here |
| //obtain from the NetBeans user directory:</b> |
| public RootRssNode() throws DataObjectNotFoundException { |
| super(DataObject.find(Repository.getDefault().getDefaultFileSystem(). |
| getRoot().getFileObject("RssFeeds")).getNodeDelegate()); |
| } |
| |
| <b>//Set the display name of the node, |
| //referring to the bundle file, and |
| //a key, which we will define later:</b> |
| @Override |
| public String getDisplayName() { |
| return NbBundle.getMessage(RssNode.class, "FN_title"); |
| } |
| |
| } |
| |
| }</pre> |
| |
| |
| </ol> |
| |
| <p>Várias marcas de sublinhado vermelho permanecem na classe porque ainda não criamos as ações e porque a classe que define os filhos do nó também não foi criada ainda. |
| |
| |
| </p><h3> |
| Criando a classe RssFolderChildren</H3> |
| |
| <p>A seguir, nos preocuparemos com os filhos do nó "RSS/Atom Feeds". Os filhos são pastas ou feeds. Isso é tudo o que acontece no código abaixo. |
| |
| |
| </p><p>Realize as seguintes etapas para criar esta classe: |
| |
| |
| </p><ol> |
| <li> |
| Crie <tt> RssFolderChildren.java</tt> no pacote <tt> org.myorg.feedreader</tt>.</li> |
| <li> |
| Substitua a classe padrão pela seguinte:</li> |
| </ol> |
| <pre class="examplecode">public class RssFolderChildren extends FilterNode.Children { |
| |
| RssFolderChildren(Node rssFolderNode) { |
| super(rssFolderNode); |
| } |
| |
| @Override |
| protected Node[] createNodes(Node key) { |
| Node n = key; |
| |
| <b>//If we can find a data folder, then we create an RssNode, |
| //if not, we look for the feed and then create a OneFeedNode:</b> |
| try { |
| if (n.getLookup().lookup(DataFolder.class) != null) { |
| return new Node[]{new RssNode(n)}; |
| } else { |
| Feed feed = getFeed(n); |
| if (feed != null) { |
| return new Node[]{ |
| new OneFeedNode(n, feed.getSyndFeed()) |
| }; |
| } else { |
| // best effort |
| return new Node[]{new FilterNode(n)}; |
| } |
| } |
| } catch (IOException ioe) { |
| Exceptions.printStackTrace(ioe); |
| } catch (IntrospectionException exc) { |
| Exceptions.printStackTrace(exc); |
| } |
| // Some other type of Node (gotta do something) |
| return new Node[]{new FilterNode(n)}; |
| } |
| |
| /** Looking up a feed */ |
| private static Feed getFeed(Node node) { |
| InstanceCookie ck = node.getCookie(InstanceCookie.class); |
| if (ck == null) { |
| throw new IllegalStateException("Bogus file in feeds folder: " + node.getLookup().lookup(FileObject.class)); |
| } |
| try { |
| return (Feed) ck.instanceCreate(); |
| } catch (ClassNotFoundException ex) { |
| Exceptions.printStackTrace(ex); |
| } catch (IOException ex) { |
| Exceptions.printStackTrace(ex); |
| } |
| return null; |
| } |
| |
| }</pre> |
| </ol> |
| |
| |
| <p>Várias marcações de sublinhado vermelho permanecem na classe, porque não criamos a classe <tt>OneFeedNode</tt> ainda. |
| |
| |
| </p><h3> |
| Criando a classe OneFeedNode</H3> |
| |
| <p>Aqui nós estamos interessados no contêiner dos nós de artigo, conforme mostrado abaixo para o nó 'Destaques do NetBeans': |
| |
| </p><p></p><div> |
| <IMG SRC="../../images/tutorials/feedreader/60-actions2.png" border="1"> |
| </div></p> |
| |
| <p>Como pode ser visto, cada um desses nós possui um nome de exibição, recuperado do feed, um ícone e um item de menu Excluir. |
| |
| |
| </p><p>Realize as seguintes etapas para criar esta classe: |
| |
| </p><ol> |
| <li> |
| Crie <tt> OneFeedNode.java</tt> no pacote <tt> org.myorg.feedreader</tt>.</li> |
| <li> |
| Substitua a classe padrão pela seguinte:</li> |
| </ol> |
| <pre class="examplecode">public class OneFeedNode extends FilterNode { |
| |
| OneFeedNode(Node feedFileNode, SyndFeed feed) throws IOException, IntrospectionException { |
| super(feedFileNode, |
| new FeedChildren(feed), |
| new ProxyLookup( |
| new Lookup[]{Lookups.fixed( |
| new Object[]{feed}), |
| feedFileNode.getLookup() |
| })); |
| } |
| |
| @Override |
| public String getDisplayName() { |
| SyndFeed feed = getLookup().lookup(SyndFeed.class); |
| return feed.getTitle(); |
| } |
| |
| @Override |
| public Image getIcon(int type) { |
| return Utilities.loadImage("org/myorg/feedreader/rss16.gif"); |
| } |
| |
| @Override |
| public Image getOpenedIcon(int type) { |
| return getIcon(0); |
| } |
| |
| @Override |
| public Action[] getActions(boolean context) { |
| return new Action[]{SystemAction.get(DeleteAction.class)}; |
| } |
| |
| }</pre> |
| |
| </ol> |
| |
| |
| <p>Várias marcações de sublinhado vermelho permanecem na classe, pois não criamos a classe <tt>FeedChildren</tt> ainda. |
| |
| |
| </p><h3> |
| Criando a classe FeedChildren</H3> |
| |
| <p>Nesta seção, adicionaremos código que fornecerá nós para cada um dos artigos fornecidos pelo feed. |
| |
| </p><p>Realize as seguintes etapas para criar esta classe: |
| |
| </p><ol> |
| <li> |
| Crie <tt> FeedChildren.java</tt> no pacote <tt> org.myorg.feedreader</tt>.</li> |
| <li> |
| Substitua a classe padrão pela seguinte:</li> |
| </ol> |
| <pre class="examplecode">public class FeedChildren extends Children.Keys { |
| |
| private final SyndFeed feed; |
| |
| public FeedChildren(SyndFeed feed) { |
| this.feed = feed; |
| } |
| |
| @SuppressWarnings(value = "unchecked") |
| @Override |
| protected void addNotify() { |
| setKeys(feed.getEntries()); |
| } |
| |
| public Node[] createNodes(Object key) { |
| |
| <b>//Return new article-level nodes:</b> |
| try { |
| return new Node[]{ |
| new EntryBeanNode((SyndEntry) key) |
| }; |
| |
| } catch (final IntrospectionException ex) { |
| Exceptions.printStackTrace(ex); |
| <b>//Should never happen, no reason for it to fail above:</b> |
| return new Node[]{new AbstractNode(Children.LEAF) { |
| @Override |
| public String getHtmlDisplayName() { |
| return "" + ex.getMessage() + ""; |
| } |
| }}; |
| } |
| } |
| }</pre> |
| |
| </ol> |
| |
| <p>Várias marcações de sublinhado vermelho permanecem na classe, pois não criamos nossa classe <tt>EntryBeanNode</tt> ainda. |
| |
| |
| </p><h3> |
| Criando a classe EntryBeanNode</H3> |
| |
| <p>Finalmente, lidaremos com os nós de nível mais inferior, aqueles que representam artigos fornecidos pelo feed. |
| |
| </p><p>Para criar esta classe, realize as seguintes etapas: |
| |
| </p><ol> |
| <li> |
| Crie <tt> EntryBeanNode.java</tt> no pacote <tt> org.myorg.feedreader</tt>.</li> |
| <li> |
| Substitua a classe padrão pela seguinte:</li> |
| </ol> |
| <pre class="examplecode">public class EntryBeanNode extends FilterNode { |
| |
| private SyndEntry entry; |
| |
| @SuppressWarnings(value = "unchecked") |
| public EntryBeanNode(SyndEntry entry) throws IntrospectionException { |
| super(new BeanNode(entry), Children.LEAF, |
| Lookups.fixed(new Object[]{ |
| entry, |
| new EntryOpenCookie(entry) |
| })); |
| this.entry = entry; |
| } |
| |
| <b>/** Using HtmlDisplayName ensures any HTML in RSS entry titles are |
| * /**properly handled, escaped, entities resolved, etc. */</b> |
| @Override |
| public String getHtmlDisplayName() { |
| return entry.getTitle(); |
| } |
| |
| <b>/** Making a tooltip out of the entry's description */</b> |
| @Override |
| public String getShortDescription() { |
| return entry.getDescription().getValue(); |
| } |
| |
| <b>/** Providing the Open action on a feed entry */</b> |
| @Override |
| public Action[] getActions(boolean popup) { |
| return new Action[]{SystemAction.get(OpenAction.class)}; |
| } |
| |
| @Override |
| public Action getPreferredAction() { |
| return (SystemAction) getActions(false) [0]; |
| } |
| |
| <b>/** Specifying what should happen when the user invokes the Open action */</b> |
| private static class EntryOpenCookie implements OpenCookie { |
| |
| private final SyndEntry entry; |
| |
| EntryOpenCookie(SyndEntry entry) { |
| this.entry = entry; |
| } |
| |
| public void open() { |
| try { |
| URLDisplayer.getDefault().showURL(new URL(entry.getUri())); |
| } catch (MalformedURLException mue) { |
| Exceptions.printStackTrace(mue); |
| } |
| } |
| |
| } |
| |
| }</pre> |
| |
| </ol> |
| |
| |
| |
| <h3> |
| Criando o item de menu Adicionar pasta</H3> |
| |
| <p>Agora criaremos o item de menu para criação de pastas, conforme declarado anteriormente. |
| |
| </p><p>Para criar esta classe, realize as seguintes etapas: |
| |
| </p><ol> |
| <li> |
| Crie <tt> AddFolderAction.java</tt> no pacote <tt> org.myorg.feedreader</tt>.</li> |
| <li> |
| Substitua a classe padrão pela seguinte:</li> |
| </ol> |
| <pre class="examplecode">public class AddFolderAction extends AbstractAction { |
| |
| private DataFolder folder; |
| |
| public AddFolderAction(DataFolder df) { |
| folder = df; |
| putValue(Action.NAME, NbBundle.getMessage(RssNode.class, "FN_addfolderbutton")); |
| } |
| |
| public void actionPerformed(ActionEvent ae) { |
| NotifyDescriptor.InputLine nd = |
| new NotifyDescriptor.InputLine( |
| NbBundle.getMessage(RssNode.class, "FN_askfolder_msg"), |
| NbBundle.getMessage(RssNode.class, "FN_askfolder_title"), |
| NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.PLAIN_MESSAGE); |
| Object result = DialogDisplayer.getDefault().notify(nd); |
| if (result.equals(NotifyDescriptor.OK_OPTION)) { |
| final String folderString = nd.getInputText(); |
| try { |
| DataFolder.create(folder, folderString); |
| } catch (IOException ex) { |
| Exceptions.printStackTrace(ex); |
| } |
| } |
| } |
| }</pre> |
| |
| </ol> |
| |
| |
| <h3> |
| Criando o item de menu Adicionar RSS</H3> |
| |
| <p>Nesta seção, criaremos o item de menu que adiciona novos feeds. |
| |
| </p><p>Para criar esta classe, realize as seguintes etapas: |
| |
| </p><ol> |
| <li> |
| Crie <tt> AddRssAction.java</tt> no pacote <tt> org.myorg.feedreader</tt>.</li> |
| <li> |
| Substitua a classe padrão pela seguinte:</li> |
| </ol> |
| <pre class="examplecode">public class AddRssAction extends AbstractAction { |
| |
| private DataFolder folder; |
| |
| public AddRssAction(DataFolder df) { |
| folder = df; |
| putValue(Action.NAME, NbBundle.getMessage(RssNode.class, "FN_addbutton")); |
| } |
| |
| public void actionPerformed(ActionEvent ae) { |
| |
| NotifyDescriptor.InputLine nd = new NotifyDescriptor.InputLine( |
| NbBundle.getMessage(RssNode.class, "FN_askurl_msg"), |
| NbBundle.getMessage(RssNode.class, "FN_askurl_title"), |
| NotifyDescriptor.OK_CANCEL_OPTION, |
| NotifyDescriptor.PLAIN_MESSAGE); |
| |
| Object result = DialogDisplayer.getDefault().notify(nd); |
| |
| if (result.equals(NotifyDescriptor.OK_OPTION)) { |
| String urlString = nd.getInputText(); |
| URL url; |
| try { |
| url = new URL(urlString); |
| } catch (MalformedURLException e) { |
| String message = NbBundle.getMessage(RssNode.class, "FN_askurl_err", urlString); |
| Exceptions.attachLocalizedMessage(e, message); |
| Exceptions.printStackTrace(e); |
| return; |
| } |
| try { |
| checkConnection(url); |
| } catch (IOException e) { |
| String message = NbBundle.getMessage(RssNode.class, "FN_cannotConnect_err", urlString); |
| Exceptions.attachLocalizedMessage(e, message); |
| Exceptions.printStackTrace(e); |
| return; |
| } |
| Feed f = new Feed(url); |
| FileObject fld = folder.getPrimaryFile(); |
| String baseName = "RssFeed"; |
| int ix = 1; |
| while (fld.getFileObject(baseName + ix, "ser") != null) { |
| ix++; |
| } |
| try { |
| FileObject writeTo = fld.createData(baseName + ix, "ser"); |
| FileLock lock = writeTo.lock(); |
| try { |
| ObjectOutputStream str = new ObjectOutputStream(writeTo.getOutputStream(lock)); |
| try { |
| str.writeObject(f); |
| } finally { |
| str.close(); |
| } |
| } finally { |
| lock.releaseLock(); |
| } |
| } catch (IOException ioe) { |
| Exceptions.printStackTrace(ioe); |
| } |
| } |
| |
| private static void checkConnection(final URL url) throws IOException { |
| InputStream is = url.openStream(); |
| is.close(); |
| } |
| |
| }</pre> |
| |
| </ol> |
| |
| |
| |
| <h3> |
| Localizando a classe RssNode</H3> |
| <ol> |
| <li> |
| Abra o arquivo <tt>Bundle.properties</tt> do módulo <tt>FeedReader</tt>.</li> |
| <li> |
| Adicione os seguintes pares de valores de chave:<br> |
| |
| <pre class="examplecode">FN_title=RSS/Atom Feeds |
| FN_addbutton=Add |
| FN_askurl_title=New Feed |
| FN_askurl_msg=Enter the URL of an RSS/Atom Feed |
| FN_askurl_err=Invalid URL: {0}| |
| FN_addfolderbutton=Add Folder |
| FN_askfolder_msg=Enter the folder name |
| FN_askfolder_title=New Folder</pre> |
| |
| </li> |
| </ol> |
| |
| Eis uma explicação dos novos pares de valores de chave, que localizam a strings definidas em <tt>RssNode.java</tt>:</P> |
| <UL> |
| <li> |
| <b> FN_title.</b> Localiza o rótulo do nó mais alto na janela Feed.</li> |
| </UL> |
| |
| Localização da interface do usuário para adicionar um feed:</P> |
| <UL> |
| <li> |
| <b> FN_addbutton.</b> Localiza o rótulo do menu Adicionar que aparece no pop-up do nó mais alto.</li> |
| <li> |
| <b> FN_askurl_title.</b> Localiza o título da caixa de diálogo Novo feed.</li> |
| <li> |
| <b> FN_askurl_msg.</b> Localiza a mensagem que aparece na caixa de diálogo Novo feed.</li> |
| <li> |
| <b> FN_askurl_err.</b> Localiza a string de erro que é exibida se a URL for inválida.</li> |
| </UL> |
| |
| Localização da interface do usuário para adicionar uma pasta:</P> |
| <UL> |
| <li> |
| <b> FN_addfolderbutton.</b> Localiza o rótulo do menu Adicionar pasta que aparece no pop-up do nó mais alto.</li> |
| <li> |
| <b> FN_askfolder_msg.</b> Localize a mensagem que aparece na caixa de diálogo Adicionar pasta.</li> |
| <li> |
| <b> FN_askfolder_title. </b> Localiza o título da caixa de diálogo Adicionar pasta.</li> |
| </UL> |
| <h2><a name="branding"></a> Marcando o aplicativo</H2> |
| <p> |
| Agora que está no final do ciclo de desenvolvimento, ao empacotar o aplicativo, você tem as seguintes preocupações:</P> |
| <UL> |
| <li> |
| Qual deve ser o nome do executável do aplicativo?</li> |
| <li> |
| O que o usuário deve ver ao iniciar o aplicativo? Uma barra de progresso? Uma tela de abertura? Ambos?</li> |
| <li> |
| Quando o aplicativo for iniciado, o que deve ser exibido na barra de título?</li> |
| <li> |
| Eu preciso de todos os menus e botões da barra de ferramentas que a Plataforma NetBeans fornece por padrão?</li> |
| </UL> |
| <p> |
| Estas questões são relacionadas à identificação de marca, a atividade de personalização de um aplicativo construído na Plataforma NetBeans. O IDE fornece um painel na caixa de diálogo Propriedades do projeto de projetos de suíte de módulos para ajudá-lo na identificação de marca.</P> |
| <ol> |
| <li> |
| Clique com o botão direito do mouse no nó do projeto <tt>feedreader-suite</tt> (não no nó do projeto <tt> FeedReader</tt>) e escolha Propriedades. Na caixa de diálogo Propriedades do projeto, clique em Construir. </li> |
| <li> |
| No painel Construir, digite <tt>feedreader</tt> em Nome de marca. Digite <tt>Aplicativo Feed Reader</tt> em Título do aplicativo. O valor no nome de marca define o nome do executável, enquanto o valor no título do aplicativo define a barra de título do aplicativo. </li> |
| <li> |
| Clique em Procurar para ir para o ícone <tt>rss16.gif</tt> (<IMG SRC="../../images/tutorials/feedreader/rss16.gif" />). Escolha o ícone que será exibido na caixa de diálogo Ajuda > Sobre.</li> |
| |
| <p>Agora você deve ver o seguinte:</p> |
| <IMG SRC="../../images/tutorials/feedreader/60-brand1.png" border="1"/> |
| |
| |
| <li> |
| No painel Tela de splash, clique em Procurar para ir para <tt>splash.gif</tt> . Opcionalmente, altere a cor e o tamanho do texto da barra de progresso. Ou, caso não deseje uma barra de progresso, desmarque Habilitado.</li> |
| |
| <p>Agora você deve ver o seguinte:</p> |
| <IMG SRC="../../images/tutorials/feedreader/60-brand2.png" border="1"/> |
| |
| |
| <li> |
| Clique em OK.<br> |
| A pasta <tt>branding</tt> é criada no projeto <tt>Aplicativo FeedReader</tt>. Ela é visível na janela Arquivos (Ctrl-2).</li> |
| <li> |
| Na janela Arquivos, expanda o nó do projeto <tt>Aplicativo FeedReader</tt>. Em seguida, continue expandindo nós até encontrar este:<br> |
| <tt> branding/modules/org-netbeans-core-window.jar/org/netbeans/core/windows</tt> |
| </li> |
| <li> |
| Clique com o botão direito do mouse no nó, escolha Novo > Outro e selecione Pasta na categoria Outros. Clique em Próximo e nomeie a pasta como <tt>resources</tt> . Clique em Terminar. </li> |
| <li> |
| Clique com o botão direito do mouse no novo nó <tt>resources</tt>, escolha Novo > Outro e selecione Documento XML na categoria XML. Clique em Próximo. Nomeie o arquivo como <tt>layer</tt> . Clique em Próximo e, em seguida, em Terminar. Substitua o conteúdo do novo arquivo <tt>layer.xml</tt> pelo seguinte:</li> |
| </ol> |
| <pre class="examplecode"><?xml version="1.0" encoding="UTF-8"?> |
| <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "https://netbeans.org/dtds/filesystem-1_1.dtd"> |
| <!-- |
| This is a `branding' layer. Ela é mesclada ao arquivo layer que ela está identificando. |
| Neste caso, está apenas ocultando itens de menu e barras de ferramentas que não queremos. |
| --> |
| <filesystem> |
| |
| <!-- hide unused toolbars --> |
| <folder name="Toolbars"> |
| <folder name="File_hidden"/> |
| <folder name="Edit_hidden"/> |
| </folder> |
| |
| <folder name="Menu"> |
| <folder name="File"> |
| <file name="org-openide-actions-SaveAction.instance_hidden"/> |
| <file name="org-openide-actions-SaveAllAction.instance_hidden"/> |
| <file name="org-netbeans-core-actions-RefreshAllFilesystemsAction.instance_hidden"/> |
| <file name="org-openide-actions-PageSetupAction.instance_hidden"/> |
| <file name="org-openide-actions-PrintAction.instance_hidden"/> |
| </folder> |
| <folder name="Edit_hidden"/> |
| <folder name="Tools_hidden"/> |
| </folder> |
| |
| </filesystem></pre> |
| <h2><a name="distributing"></a>Distribuindo a aplicação</H2> |
| <p> |
| O IDE usa um script de construção Ant para criar uma distribuição do aplicativo. O script de construção é criado quando o projeto é criado.</P> |
| <ol> |
| <li> |
| Na janela Projetos, clique com o botão direito do mouse no nó do projeto <tt>Aplicativo FeedReader</tt> e escolha Construir distribuição ZIP. A janela Saída mostra onde a distribuição ZIP é criada. </li> |
| <li> |
| No sistema de arquivos, localize a distribuição <tt>feedreader.zip</tt> na pasta <tt>dist</tt> no diretório do projeto. Descompacte-a. Inicie o aplicativo, que é encontrado na pasta <tt>bin</tt>. Durante a inicialização, uma tela de splash é exibida. Quando o aplicativo tiver sido iniciado, vá para a caixa de diálogo Ajuda > Sobre e observe o ícone e a tela de splash especificados na seção <A HREF="#branding" CLASS="XRef">Identificando a marca do aplicativo</A>.</li> |
| </ol> |
| <p> |
| Quando estiver em funcionamento, o aplicativo Feed Reader exibe a janela RSS/Atom Feeds, que contém um nó chamado RSS/Atom Feeds. </P> |
| <p> |
| Parabéns! Você concluiu o tutorial FeedReader.</P> |
| <br> |
| <div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&subject=Feedback: NetBeans Platform 6.0 Feed Reader Tutorial">Envie-nos seus comentários</a></div> |
| <br style="clear:both;" /> |
| <hr> |
| </BODY> |
| </HTML> |