blob: f6ecb9f8df72657ce7669c352c6d03fc903b17c9 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- -*- xhtml -*- -->
<title>Tutorial 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&iacute;do neste tutorial &eacute; um simples navegador RSS/Atom feed, modelado de acordo com o plug-in Sage para Mozilla Firefox. Ele apresenta uma &aacute;rvore de feeds com subn&oacute;s representando entradas individuais de feeds que podem ser abertas em um navegador.
</p><p>Para ilustrar o resultado final, aqui voc&ecirc; v&ecirc; o Feed Reader que ser&aacute; constru&iacute;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&uacute;do</b></p>
<img src="../../images/articles/60/netbeans-stamp60-61.gif" class="stamp" width="114" height="114" alt="O conte&uacute;do desta p&aacute;gina se aplica ao IDE NetBeans 6.1 " title="O conte&uacute;do desta p&aacute;gina se aplica ao IDE NetBeans 6.1"> </p>
<ul class="toc">
<li><A HREF="#knowledge" CLASS="XRef">Conhecimento necess&aacute;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&ccedil;&atilde;o</A>
</li><li><A HREF="#adding" CLASS="XRef">Adicionando o c&oacute;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&ccedil;&atilde;o</A>
</li></ul>
<p><b>Para seguir este tutorial, voc&ecirc; preciso dos softwares e recursos listados na tabela seguinte.</b></p>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software ou recurso</th>
<th class="tblheader" scope="col">Vers&atilde;o necess&aacute;ria</th>
</tr>
<tr>
<td class="tbltd1">NetBeans IDE</td>
<td class="tbltd1">vers&atilde;o <a href="http://download.netbeans.org/netbeans/6.1/final/">vers&atilde;o 6.1</a> ou<br>
vers&atilde;o 6.0</td>
</tr>
<tr>
<td class="tbltd1">Java Developer Kit (JDK)</td>
<td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">vers&atilde;o 6</a> ou<br>
vers&atilde;o 5</td>
</tr>
<tr>
<td class="tbltd1">Utilit&aacute;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">&Iacute;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&eacute;-requisito</H2>
<p>Voc&ecirc; n&atilde;o precisa ter qualquer conhecimento sobre desenvolvimento da Plataforma NetBeans para trabalhar neste tutorial. Pode ser &uacute;til se voc&ecirc; tiver algum conhecimento sobre programa&ccedil;&atilde;o Java, embora isso n&atilde;o seja essencial. Entretanto, a leitura dos seguintes documentos antes de iniciar este tutorial pode ser &uacute;til, para fornecer informa&ccedil;&otilde;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&aacute; feito neste tutorial, conceitualmente. Ele tamb&eacute;m mostra onde encontrar o c&oacute;digo-fonte da amostra constru&iacute;da neste tutorial.</li>
<li><a href="../61/nbm-htmleditor_pt_BR.html">NetBeans Platform Quick Start</a>. Este tutorial breve fornece orienta&ccedil;&atilde;o atrav&eacute;s de um processo completo de cria&ccedil;&atilde;o de um aplicativo de cliente avan&ccedil;ado sobre a Plataforma NetBeans. As principais ferramentas e os est&aacute;gios de desenvolvimento s&atilde;o abordados, e o Editor de HTML &eacute; o resultado do tutorial.</li>
</ul>
<h2><a name="setting"></a> Configurando a aplica&ccedil;&atilde;o</H2>
<p>
No NetBeans IDE, a constru&ccedil;&atilde;o de um aplicativo sobre a Plataforma NetBeans come&ccedil;a com a cria&ccedil;&atilde;o de v&aacute;rios arquivos que ir&atilde;o servir como base para o aplicativo. Por exemplo, o IDE fornece um Assistente de projeto de m&oacute;dulo, um Assistente de projeto de su&iacute;te de m&oacute;dulos e um Assistente de projeto de m&oacute;dulo de wrapper de bibliotecas que configuram todos os arquivos b&aacute;sicos que os m&oacute;dulos e aplicativos constru&iacute;dos na Plataforma NetBeans precisam.</P>
<UL>
<li>
<b>Projeto de su&iacute;te de m&oacute;dulos.</b> Um projeto que agrupa um conjunto de projetos de m&oacute;dulos e projetos de m&oacute;dulo de wrapper de bibliotecas que possuem depend&ecirc;ncias entre eles, e permite que voc&ecirc; implante-os juntos como uma unidade.</li>
<li>
<b>Projeto de m&oacute;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&oacute;dulo como pacotes p&uacute;blicos.</li>
<li>
<b>Projeto de m&oacute;dulo.</b> Um projeto para implementar a funcionalidade, l&oacute;gica comercial e a interface do usu&aacute;rio de um m&oacute;dulo ou aplicativo constru&iacute;do na Plataforma NetBeans.</li>
</UL>
<h3>
Criando o projeto de su&iacute;te de m&oacute;dulos</H3>
<ol>
<li>
Escolha Arquivo &gt; Novo projeto (Ctrl-Shift-N). Em Categorias, selecione M&oacute;dulos do NetBeans. Em Projetos, selecione Projeto de su&iacute;te de m&oacute;dulos. Voc&ecirc; deve ver o seguinte:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-suite-wiz.png" border="1"/>
</p><p>Clique em Pr&oacute;ximo.</p></li>
<li>
No painel Nome e localiza&ccedil;&atilde;o, digite <tt> feedreader-suite</tt> em Nome do projeto.
Altere Local do projeto para qualquer diret&oacute;rio no computador. Agora voc&ecirc; 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&ecirc;ncia na janela Projetos:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-suite.png" border="1"/>
</p><p>O projeto conter&aacute; o projeto de m&oacute;dulo e os projetos de m&oacute;dulo de wrapper de bibliotecas que voc&ecirc; criar&aacute; nas seguintes subse&ccedil;&otilde;es. </P>
<h3>
Empacotando as bibliotecas</H3>
Voc&ecirc; pode empacotar todo o aplicativo Feed Reader em um &uacute;nico m&oacute;dulo. Entretanto, o aplicativo precisa das bibliotecas Rome, Rome Fetcher e JDom:</P>
<UL>
<li>
<b>Rome.</b> L&ecirc; RSS e Atom feeds, usando uma API muito simples. </li>
<li>
<b>Rome Fetcher.</b> Permite a recupera&ccedil;&atilde;o de feeds via HTTP. </li>
<li>
<b>JDom.</b> &Eacute; uma API de an&aacute;lise de XML. O Feed Reader s&oacute; precisar&aacute; dela porque ela &eacute; utilizada pela biblioteca Rome.</li>
</UL>
Posteriormente, se voc&ecirc; desejar estender o aplicativo Feed Reader com mais m&oacute;dulos que possam usar estas bibliotecas, seria bom que eles dependessem somente dos m&oacute;dulos de biblioteca, e n&atilde;o de todo o Feed Reader. Al&eacute;m disso, os m&oacute;dulos de biblioteca podem ser de &quot;carregamento autom&aacute;tico&quot;, o que significa que o NetBeans s&oacute; os carregar&aacute; quando necess&aacute;rio. At&eacute; que isso aconte&ccedil;a, ele n&atilde;o utilizar&aacute; nenhuma mem&oacute;ria em tempo de execu&ccedil;&atilde;o.</P>
<ol>
<li>Clique com o bot&atilde;o direito do mouse no n&oacute; M&oacute;dulos no projeto de su&iacute;te de m&oacute;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&ecirc; 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&aacute; at&eacute; a pasta onde baixou JDom e selecione <tt> jdom.jar</tt> e <tt> LICENSE.txt.</tt> Clique em Pr&oacute;ximo.</li>
<li>
No painel Nome e localiza&ccedil;&atilde;o, aceite todos os padr&otilde;es. Voc&ecirc; deve ver o seguinte:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-lib-wiz3.png" border="1"/>
</p><p><b>Observa&ccedil;&atilde;o:</b> o projeto de m&oacute;dulo de wrapper de bibliotecas ser&aacute; armazenado no projeto de su&iacute;te de m&oacute;dulos. Voc&ecirc; tamb&eacute;m poderia armazen&aacute;-lo em outro lugar, mas por quest&otilde;es de versionamento, &eacute; melhor coloc&aacute;-lo no projeto de su&iacute;te de m&oacute;dulos. Por isso, o projeto de su&iacute;te de m&oacute;dulos <tt> feedreader-suite</tt> &eacute; selecionado na lista suspensa Adicionar &agrave; su&iacute;te de m&oacute;dulos.</p>
<p>Clique em Pr&oacute;ximo.</p></li>
<li>
No painel Configura&ccedil;&atilde;o b&aacute;sica de m&oacute;dulos, aceite todos os padr&otilde;es. Voc&ecirc; 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&oacute;dulo de wrapper de bibliotecas &eacute; aberto no IDE e exibido na janela Projetos. Agora voc&ecirc; 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&ccedil;&atilde;o e crie um projeto de m&oacute;dulo de wrapper de bibliotecas para Rome. Aceite todos os padr&otilde;es.</li>
<li>
Retorne para a etapa 1 desta se&ccedil;&atilde;o e crie um projeto de m&oacute;dulo de wrapper de bibliotecas para Rome Fetcher. Aceite todos os padr&otilde;es.</li>
</ol>
<p>Voc&ecirc; agora possui um projeto de su&iacute;te de m&oacute;dulos, com tr&ecirc;s projetos de m&oacute;dulo de wrapper de bibliotecas, fornecendo muitas classes Javas &uacute;teis que voc&ecirc; poder&aacute; utilizar ao longo de todo este tutorial.
</p><h3>
Criando o projeto do m&oacute;dulo </H3>
<p>Nesta se&ccedil;&atilde;o, criaremos um projeto para a funcionalidade que o seu aplicativo fornecer&aacute;. O projeto utilizar&aacute; as classes disponibilizadas pelos m&oacute;dulos de wrapper de bibliotecas criados na se&ccedil;&atilde;o anterior.</p>
<ol>
<li>
Clique com o bot&atilde;o direito do mouse no n&oacute; M&oacute;dulos no projeto de su&iacute;te de m&oacute;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&ecirc; 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&ccedil;&atilde;o, digite <tt> FeedReader</tt> em Nome do projeto.
Aceite todos os padr&otilde;es. Clique em Pr&oacute;ximo.
</li><li>
No painel Configura&ccedil;&atilde;o b&aacute;sica de m&oacute;dulos, substitua <tt> yourorghere</tt> em Nome base de c&oacute;digo por <tt> myorg</tt> , de maneira que o nome base de c&oacute;digo inteiro seja <tt> org.myorg.feedreader.</tt> Digite <tt>FeedReader</tt> in Module Display Name. Deixe o local do pacote de localiza&ccedil;&atilde;o e a camada XML, para que sejam armazenados em um pacote com o nome <tt> org/myorg/feedreader.</tt> Agora voc&ecirc; 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&eacute;m todos os metadados de projeto e c&oacute;digos-fonte do m&oacute;dulo, como o script de constru&ccedil;&atilde;o Ant do projeto. O projeto se abre no IDE. Voc&ecirc; pode ver a estrutura l&oacute;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&ecirc; criou a estrutura do c&oacute;digo-fonte do novo aplicativo. Na pr&oacute;xima se&ccedil;&atilde;o, come&ccedil;aremos adicionando algum c&oacute;digo.
</p><h2><a name="creating"></a> Criando a janela Feed Reader</H2>
<p>
Nesta se&ccedil;&atilde;o, voc&ecirc; usar&aacute; o Assistente de componente de janela para gerar arquivos que criam um componente de janela personalizado e uma a&ccedil;&atilde;o para cham&aacute;-lo. O assistente tamb&eacute;m registra a a&ccedil;&atilde;o como um item de menu no arquivo de configura&ccedil;&atilde;o <tt> layer.xml </tt> e adiciona entradas para serializar o componente de janela. Logo ap&oacute;s o t&eacute;rmino desta se&ccedil;&atilde;o, voc&ecirc; saber&aacute; como testar os arquivos que o Assistente de componente de janela gera para voc&ecirc;.</P>
<ol>
<li>
Clique com o bot&atilde;o direito do mouse no n&oacute; do projeto <tt> FeedReader</tt> e escolha Novo &gt; Outro. Em Categorias, selecione Desenvolvimento de m&oacute;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&oacute;ximo.</p></li>
<li>
No painel Configura&ccedil;&otilde;es b&aacute;sicas, selecione <tt>explorer</tt> na lista suspensa e clique em Abrir na inicializa&ccedil;&atilde;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&oacute;ximo.</p></li>
<li>
No painel Nome e localiza&ccedil;&atilde;o, digite Feed como o Prefixo do nome da classe e v&aacute; at&eacute; o local onde o arquivo <tt>rss16.gif (<IMG SRC="../../images/tutorials/feedreader/rss16.gif" />) foi salvo.</tt> O arquivo GIF ser&aacute; mostrado no item de menu que chama a a&ccedil;&atilde;o. Agora voc&ecirc; 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 &eacute; 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&ccedil;&atilde;o que aparece no menu Janela com o r&oacute;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&aacute;cil de inst&acirc;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&ecirc;ncia ao componente. Permite que o componente perten&ccedil;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&ecirc;ncias de m&oacute;dulo foram adicionadas, <tt> API de utilit&aacute;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&ecirc;s pares de chave-valor foram adicionados:<br>
<ul>
<li><tt>CTL_FeedAction.</tt> Localiza o r&oacute;tulo do item de menu, definido em <tt>FeedAction.java</tt>.
</li><li><tt>CTL_FeedTopComponent.</tt> Localiza o r&oacute;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&ecirc;s entradas de registro foram adicionadas ao arquivo <tt>layer.xml</tt>.</li>
</p><p>
Isto &eacute; o que as entradas no arquivo <tt> layer.xml</tt> fazem:</P>
<UL>
<li>
<tt> &lt;A&ccedil;&otilde;es&gt;</tt>
<br>
Registra a a&ccedil;&atilde;o como uma a&ccedil;&atilde;o na pasta Janela.</li>
<li>
<tt> &lt;Menu&gt;</tt>
<br>
Registra a a&ccedil;&atilde;o como um item de menu no menu Janela.</li>
<li>
<tt> &lt;Windows2&gt; <br>
</tt> Registra o arquivo <tt>FeedTopComponentSettings.xml</tt>, que &eacute; usado para pesquisar o componente de janela. Registra o arquivo de refer&ecirc;ncia do componente <tt>FeedTopComponentWstcref.xml</tt> na &aacute;rea do &quot;explorer&quot;.
<br>
</tt>
</li>
</UL>
<h2><a name="running"></a> Executando a aplica&ccedil;&atilde;o</H2>
<p>
Sem ter digitado uma &uacute;nica linha de c&oacute;digo, ainda &eacute; poss&iacute;vel fazer um teste com o aplicativo. Testar significa implantar os m&oacute;dulos na Plataforma NetBeans e depois verificar se a janela Feed vazia &eacute; exibida corretamente.</P>
<ol>
<li>Vamos primeiro remover todos os m&oacute;dulos que definem o NetBeans IDE, mas que n&atilde;o ser&atilde;o necess&aacute;rios no aplicativo Feed Reader. Clique com o bot&atilde;o direito do mouse no projeto <tt>feedreader-suite</tt>, escolha Propriedades e clique em Bibliotecas na caixa de di&aacute;logo Propriedades do projeto.</p>
<p>&Eacute; mostrada uma lista de 'grupos'. Cada cluster &eacute; um conjunto de m&oacute;dulos relacionados. O &uacute;nico cluster que precisaremos ser&aacute; o de plataforma. Assim, desmarque todos os outros, at&eacute; 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&eacute;s dos m&oacute;dulos fornecidos:
</p><div>
<IMG SRC="../../images/tutorials/feedreader/60-runapp5.png" border="1">
</div>
<p></p><p>Os m&oacute;dulos da plataforma fornecem a infra-estrutura comum de aplicativos Swing. Assim, como n&oacute;s inclu&iacute;mos o cluster de plataforma, n&atilde;o ser&aacute; necess&aacute;rio criar o c&oacute;digo 'b&aacute;sico' para a infra-estrutura do aplicativo, como a barra de menu, o sistema de janelas e a funcionalidade de inicializa&ccedil;&atilde;o.
</p><p></p><p>Clique em OK.
</p></li><li>Na janela Projetos, clique com o bot&atilde;o direito do mouse no n&oacute; do projeto <tt> feedreader-suite</tt> e escolha Limpar e construir tudo.
</li><li>Na janela Projetos, clique com o bot&atilde;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 &eacute; iniciado. Voc&ecirc; v&ecirc; uma tela de abertura. Em seguida, o aplicativo &eacute; 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&ccedil;&atilde;o:</b> o que voc&ecirc; possui agora &eacute; um aplicativo que consiste nos seguintes m&oacute;dulos:
</p><ul>
<li>Os m&oacute;dulos fornecidos pela Plataforma NetBeans, para inicializa&ccedil;&atilde;o do aplicativo, gerenciamento do ciclo de vida e outros processos relacionados &agrave; infra-estrutura.
</li><li>Os tr&ecirc;s m&oacute;dulos de wrapper de bibliotecas criados neste tutorial.
</li><li>O m&oacute;dulo da funcionalidade FeedReader criado neste tutorial, para fornecer a janela Feed.
</li></ul>
<p></p><p>No menu Janela do aplicativo, voc&ecirc; ver&aacute; 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&ecirc; pode ver, sem ter feito qualquer c&oacute;digo, temos um aplicativo completo. Ainda n&atilde;o &eacute; muita coisa, mas a infra-estrutura j&aacute; existe e funciona como esperado. Em seguida, come&ccedil;aremos a usar algumas das APIs do NetBeans para adicionar c&oacute;digo ao aplicativo.
</p><h2><a name="adding"></a>Adicionando o c&oacute;digo ao aplicativo</H2>
<p>
Agora que a base do aplicativo est&aacute; pronta, &eacute; hora de come&ccedil;ar a adicionar seu pr&oacute;prio c&oacute;digo. Antes de fazer isso, especifique as depend&ecirc;ncias do aplicativo. As depend&ecirc;ncias s&atilde;o m&oacute;dulos que fornecem as APIs do NetBeans que voc&ecirc; ir&aacute; estender ou implementar. Em seguida, use o Assistente de novo arquivo e o Editor de c&oacute;digo-fonte para criar e codificar as classes que comp&otilde;em o aplicativo Feed Reader.
</p><h3>
Especificando as depend&ecirc;ncias do aplicativo</H3>
Voc&ecirc; precisa criar subclasses de v&aacute;rias classes que pertencem &agrave;s APIs do NetBeans. As classes pertencem a m&oacute;dulos que precisam ser declarados como depend&ecirc;ncias do aplicativo Feed Reader. Use a caixa de di&aacute;logo Propriedades do projeto para isso, conforme explicado nas etapas abaixo.</P>
<ol>
<li>
Na janela Projetos, clique com o bot&atilde;o direito do mouse no projeto <tt> FeedReader</tt> e escolha Propriedades. Na caixa de di&aacute;logo Propriedades do projeto, clique em Bibliotecas. Observe que algumas APIs j&aacute; foram declaradas como Depend&ecirc;ncias do m&oacute;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&ecirc; pelo Assistente de componente de janela, anteriormente neste tutorial.</p></li>
<li>
Clique em Adicionar depend&ecirc;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&ecirc; 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&aacute;logo Propriedades do projeto. </p></li>
<li>Expanda o n&oacute; Bibliotecas do projeto <tt>FeedReader</tt> e observe a lista de m&oacute;dulos que est&atilde;o dispon&iacute;veis para este projeto:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-add-lib5.png" border="1">
</div>
</li></ol>
<h3>
Definindo depend&ecirc;ncias entre m&oacute;dulos do wrapper de biblioteca</h3>
<p>Agora que definimos as depend&ecirc;ncias nos m&oacute;dulos de APIs do NetBeans que iremos usar, vamos definir tamb&eacute;m as depend&ecirc;ncias entre os m&oacute;dulos de wrapper de bibliotecas. Por exemplo, o JAR de Rome utiliza as classes do JAR de JDom. Agora que eles est&atilde;o dispostos em m&oacute;dulos de wrapper de biblioteca separados, &eacute; necess&aacute;rio especificar a rela&ccedil;&atilde;o entre os JARs atrav&eacute;s da caixa de di&aacute;logo Propriedades do projeto de m&oacute;dulo de wrapper de bibliotecas.</p>
<ol>
<li>
Primeiro, vamos tornar Rome dependente de JDom. Clique com o bot&atilde;o direito do mouse no projeto de m&oacute;dulo de wrapper da biblioteca Rome na janela Projetos e escolha Propriedades. Na caixa de di&aacute;logo Propriedades do projeto, clique em Bibliotecas e, em seguida, em Adicionar depend&ecirc;ncia. Adicionar <tt>jdom</tt>. Agora voc&ecirc; 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&aacute;logo Propriedades do projeto.</p></li>
<li>
Finalmente, como Rome Fetcher depende de Rome e JDom, voc&ecirc; 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&aacute; depende de JDom, n&atilde;o &eacute; necess&aacute;rio tornar Rome Fetcher dependente de JDom. </p></li>
</ol>
<h3>
Criando a pasta RssFeeds</H3>
<p>Voc&ecirc; usar&aacute; a interface do usu&aacute;rio do IDE para adicionar uma pasta ao arquivo <tt>layer.xml</tt>. A pasta conter&aacute; os objetos RSS feed. Posteriormente, voc&ecirc; adicionar&aacute; c&oacute;digo ao <tt> FeedTopComponent.java</tt>, que foi criado por voc&ecirc; pelo Assistente de componente de janela, para exibir o conte&uacute;do desta pasta.</P>
<ol>
<li>
Na janela Projetos, expanda o n&oacute; do projeto <tt> FeedReader</tt>, expanda o n&oacute; Arquivos importantes e expanda o n&oacute; Camada XML. Voc&ecirc; deve ver o seguinte n&oacute;s:<p></p><p>
</p><ul><li><tt> &lt;this layer&gt;.</tt> Exp&otilde;e as pastas fornecidas pelo m&oacute;dulo atual. Por exemplo, como voc&ecirc; pode ver abaixo, o m&oacute;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> &lt;this layer in context&gt;. </tt> Exp&otilde;e todas as pastas dispon&iacute;veis para o aplicativo inteiro. Examinaremos este n&oacute; posteriormente neste tutorial.<br>
<br></li></ul>
</li>
<li>
Clique com o bot&atilde;o direito do mouse no n&oacute; <tt>&lt;esta camada&gt;</tt> e escolha Novo &gt; 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&aacute;logo Nova pasta. Clique em OK. Voc&ecirc; 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&oacute; do arquivo <tt>layer.xml</tt> para que ele seja aberto no Editor de c&oacute;digo-fonte. Observe que esta entrada foi adicionada:<br>
<tt>
<br>
&lt;folder name=&quot;RssFeeds&quot;/&gt;</tt>
</li>
</ol>
<h3>
Criando o objeto Feed</H3>
<p>Em seguida, voc&ecirc; criar&aacute; um POJO simples para encapsular uma URL e seu Rome feed associado.</p>
<ol>
<li>
Clique com o bot&atilde;o direito do mouse no n&oacute; do projeto <tt> FeedReader</tt> e selecione Novo &gt; Classe Java. Clique em Pr&oacute;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&oacute;digo-fonte, substitua a classe padr&atilde;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&oacute;digo &eacute; sublinhada, pois voc&ecirc; n&atilde;o declarou seus pacotes. Voc&ecirc; far&aacute; isso nas pr&oacute;ximas etapas. </P>
Utilize as etapas a seguir para reformatar o arquivo e declarar suas depend&ecirc;ncias:</P>
<ol>
<li>
Pressione Alt-Shift-F para reformatar o c&oacute;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&aacute; os seguintes comandos import &agrave; 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&atilde;o tenha, prossiga com este tutorial at&eacute; que voc&ecirc; 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&oacute;digo-fonte.</li>
<li>
Digite <tt>implements ExplorerManager.Provider</tt> no final da declara&ccedil;&atilde;o da classe.</li>
<li>
Pressione Alt-Enter na linha e clique na sugest&atilde;o. O IDE adiciona um comando import para o pacote necess&aacute;rio <tt>org.openide.explorer.ExplorerManager</tt>.</li>
<li>
Pressione Alt-Enter novamente e clique na sugest&atilde;o. O IDE implementa o m&eacute;todo abstrato <tt>getExplorerManager()</tt>. </li>
<li>
Digite <tt>return manager;</tt> no corpo do novo m&eacute;todo <tt>getExplorerManager()</tt>. Pressione Alt-Enter na linha e deixe que o IDE crie um campo chamado <tt>manager</tt> para voc&ecirc;. Substitua a defini&ccedil;&atilde;o padr&atilde;o por esta:
<pre class="examplecode">private final ExplorerManager manager = new ExplorerManager();</pre>
</li>
<li>
Logo abaixo da declara&ccedil;&atilde;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&oacute;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(&quot;delete&quot;, ExplorerUtils.actionDelete(manager, true));
associateLookup(ExplorerUtils.createLookup(manager, map));</pre>
</li>
</ol>
<p>
Uma grande parte do c&oacute;digo &eacute; sublinhada, pois voc&ecirc; n&atilde;o declarou seus pacotes associados. Voc&ecirc; far&aacute; isso nas pr&oacute;ximas etapas. </P>
<p>
Utilize as etapas a seguir para reformatar o arquivo e declarar suas depend&ecirc;ncias:</P>
<ol>
<li>
Pressione Alt-Shift-F para reformatar o c&oacute;digo. </li>
<li>
Pressione Ctrl-Shift-I, selecione <tt>org.openide.ErrorManager</tt>, clique em OK, e o IDE adiciona v&aacute;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&aacute; sublinhada em vermelho, porque voc&ecirc; ainda n&atilde;o criou <tt>RssNode.java</tt>. Voc&ecirc; far&aacute; isso na pr&oacute;xima subse&ccedil;&atilde;o. Todo o sublinhado vermelho restante deve ter desaparecido. Caso n&atilde;o tenha, prossiga com este tutorial at&eacute; que voc&ecirc; tenha solucionado o problema.</li>
</ol>
<h3>
Criando a classe RssNode</H3>
<p></p><p>O n&oacute; de n&iacute;vel superior do Feed Reader &eacute; 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&oacute; 'RssFeeds'. Aqui definimos um nome de exibi&ccedil;&atilde;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&atilde;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(&quot;RssFeeds&quot;)).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, &quot;FN_title&quot;);
}
}
}</pre>
</ol>
<p>V&aacute;rias marcas de sublinhado vermelho permanecem na classe porque ainda n&atilde;o criamos as a&ccedil;&otilde;es e porque a classe que define os filhos do n&oacute; tamb&eacute;m n&atilde;o foi criada ainda.
</p><h3>
Criando a classe RssFolderChildren</H3>
<p>A seguir, nos preocuparemos com os filhos do n&oacute; &quot;RSS/Atom Feeds&quot;. Os filhos s&atilde;o pastas ou feeds. Isso &eacute; tudo o que acontece no c&oacute;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&atilde;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(&quot;Bogus file in feeds folder: &quot; + 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&aacute;rias marca&ccedil;&otilde;es de sublinhado vermelho permanecem na classe, porque n&atilde;o criamos a classe <tt>OneFeedNode</tt> ainda.
</p><h3>
Criando a classe OneFeedNode</H3>
<p>Aqui n&oacute;s estamos interessados no cont&ecirc;iner dos n&oacute;s de artigo, conforme mostrado abaixo para o n&oacute; '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&oacute;s possui um nome de exibi&ccedil;&atilde;o, recuperado do feed, um &iacute;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&atilde;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(&quot;org/myorg/feedreader/rss16.gif&quot;);
}
@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&aacute;rias marca&ccedil;&otilde;es de sublinhado vermelho permanecem na classe, pois n&atilde;o criamos a classe <tt>FeedChildren</tt> ainda.
</p><h3>
Criando a classe FeedChildren</H3>
<p>Nesta se&ccedil;&atilde;o, adicionaremos c&oacute;digo que fornecer&aacute; n&oacute;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&atilde;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 = &quot;unchecked&quot;)
@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 &quot;&quot; + ex.getMessage() + &quot;&quot;;
}
}};
}
}
}</pre>
</ol>
<p>V&aacute;rias marca&ccedil;&otilde;es de sublinhado vermelho permanecem na classe, pois n&atilde;o criamos nossa classe <tt>EntryBeanNode</tt> ainda.
</p><h3>
Criando a classe EntryBeanNode</H3>
<p>Finalmente, lidaremos com os n&oacute;s de n&iacute;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&atilde;o pela seguinte:</li>
</ol>
<pre class="examplecode">public class EntryBeanNode extends FilterNode {
private SyndEntry entry;
@SuppressWarnings(value = &quot;unchecked&quot;)
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&ccedil;&atilde;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&atilde;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, &quot;FN_addfolderbutton&quot;));
}
public void actionPerformed(ActionEvent ae) {
NotifyDescriptor.InputLine nd =
new NotifyDescriptor.InputLine(
NbBundle.getMessage(RssNode.class, &quot;FN_askfolder_msg&quot;),
NbBundle.getMessage(RssNode.class, &quot;FN_askfolder_title&quot;),
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&ccedil;&atilde;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&atilde;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, &quot;FN_addbutton&quot;));
}
public void actionPerformed(ActionEvent ae) {
NotifyDescriptor.InputLine nd = new NotifyDescriptor.InputLine(
NbBundle.getMessage(RssNode.class, &quot;FN_askurl_msg&quot;),
NbBundle.getMessage(RssNode.class, &quot;FN_askurl_title&quot;),
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, &quot;FN_askurl_err&quot;, urlString);
Exceptions.attachLocalizedMessage(e, message);
Exceptions.printStackTrace(e);
return;
}
try {
checkConnection(url);
} catch (IOException e) {
String message = NbBundle.getMessage(RssNode.class, &quot;FN_cannotConnect_err&quot;, urlString);
Exceptions.attachLocalizedMessage(e, message);
Exceptions.printStackTrace(e);
return;
}
Feed f = new Feed(url);
FileObject fld = folder.getPrimaryFile();
String baseName = &quot;RssFeed&quot;;
int ix = 1;
while (fld.getFileObject(baseName + ix, &quot;ser&quot;) != null) {
ix++;
}
try {
FileObject writeTo = fld.createData(baseName + ix, &quot;ser&quot;);
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&oacute;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&ccedil;&atilde;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&oacute;tulo do n&oacute; mais alto na janela Feed.</li>
</UL>
Localiza&ccedil;&atilde;o da interface do usu&aacute;rio para adicionar um feed:</P>
<UL>
<li>
<b> FN_addbutton.</b> Localiza o r&oacute;tulo do menu Adicionar que aparece no pop-up do n&oacute; mais alto.</li>
<li>
<b> FN_askurl_title.</b> Localiza o t&iacute;tulo da caixa de di&aacute;logo Novo feed.</li>
<li>
<b> FN_askurl_msg.</b> Localiza a mensagem que aparece na caixa de di&aacute;logo Novo feed.</li>
<li>
<b> FN_askurl_err.</b> Localiza a string de erro que &eacute; exibida se a URL for inv&aacute;lida.</li>
</UL>
Localiza&ccedil;&atilde;o da interface do usu&aacute;rio para adicionar uma pasta:</P>
<UL>
<li>
<b> FN_addfolderbutton.</b> Localiza o r&oacute;tulo do menu Adicionar pasta que aparece no pop-up do n&oacute; mais alto.</li>
<li>
<b> FN_askfolder_msg.</b> Localize a mensagem que aparece na caixa de di&aacute;logo Adicionar pasta.</li>
<li>
<b> FN_askfolder_title. </b> Localiza o t&iacute;tulo da caixa de di&aacute;logo Adicionar pasta.</li>
</UL>
<h2><a name="branding"></a> Marcando o aplicativo</H2>
<p>
Agora que est&aacute; no final do ciclo de desenvolvimento, ao empacotar o aplicativo, voc&ecirc; tem as seguintes preocupa&ccedil;&otilde;es:</P>
<UL>
<li>
Qual deve ser o nome do execut&aacute;vel do aplicativo?</li>
<li>
O que o usu&aacute;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&iacute;tulo?</li>
<li>
Eu preciso de todos os menus e bot&otilde;es da barra de ferramentas que a Plataforma NetBeans fornece por padr&atilde;o?</li>
</UL>
<p>
Estas quest&otilde;es s&atilde;o relacionadas &agrave; identifica&ccedil;&atilde;o de marca, a atividade de personaliza&ccedil;&atilde;o de um aplicativo constru&iacute;do na Plataforma NetBeans. O IDE fornece um painel na caixa de di&aacute;logo Propriedades do projeto de projetos de su&iacute;te de m&oacute;dulos para ajud&aacute;-lo na identifica&ccedil;&atilde;o de marca.</P>
<ol>
<li>
Clique com o bot&atilde;o direito do mouse no n&oacute; do projeto <tt>feedreader-suite</tt> (n&atilde;o no n&oacute; do projeto <tt> FeedReader</tt>) e escolha Propriedades. Na caixa de di&aacute;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&iacute;tulo do aplicativo. O valor no nome de marca define o nome do execut&aacute;vel, enquanto o valor no t&iacute;tulo do aplicativo define a barra de t&iacute;tulo do aplicativo. </li>
<li>
Clique em Procurar para ir para o &iacute;cone <tt>rss16.gif</tt> (<IMG SRC="../../images/tutorials/feedreader/rss16.gif" />). Escolha o &iacute;cone que ser&aacute; exibido na caixa de di&aacute;logo Ajuda &gt; Sobre.</li>
<p>Agora voc&ecirc; 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&atilde;o deseje uma barra de progresso, desmarque Habilitado.</li>
<p>Agora voc&ecirc; 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> &eacute; criada no projeto <tt>Aplicativo FeedReader</tt>. Ela &eacute; vis&iacute;vel na janela Arquivos (Ctrl-2).</li>
<li>
Na janela Arquivos, expanda o n&oacute; do projeto <tt>Aplicativo FeedReader</tt>. Em seguida, continue expandindo n&oacute;s at&eacute; encontrar este:<br>
<tt> branding/modules/org-netbeans-core-window.jar/org/netbeans/core/windows</tt>
</li>
<li>
Clique com o bot&atilde;o direito do mouse no n&oacute;, escolha Novo &gt; Outro e selecione Pasta na categoria Outros. Clique em Pr&oacute;ximo e nomeie a pasta como <tt>resources</tt> . Clique em Terminar. </li>
<li>
Clique com o bot&atilde;o direito do mouse no novo n&oacute; <tt>resources</tt>, escolha Novo &gt; Outro e selecione Documento XML na categoria XML. Clique em Pr&oacute;ximo. Nomeie o arquivo como <tt>layer</tt> . Clique em Pr&oacute;ximo e, em seguida, em Terminar. Substitua o conte&uacute;do do novo arquivo <tt>layer.xml</tt> pelo seguinte:</li>
</ol>
<pre class="examplecode">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE filesystem PUBLIC &quot;-//NetBeans//DTD Filesystem 1.1//EN&quot; &quot;https://netbeans.org/dtds/filesystem-1_1.dtd&quot;&gt;
&lt;!--
This is a `branding' layer. Ela &eacute; mesclada ao arquivo layer que ela est&aacute; identificando.
Neste caso, est&aacute; apenas ocultando itens de menu e barras de ferramentas que n&atilde;o queremos.
--&gt;
&lt;filesystem&gt;
&lt;!-- hide unused toolbars --&gt;
&lt;folder name=&quot;Toolbars&quot;&gt;
&lt;folder name=&quot;File_hidden&quot;/&gt;
&lt;folder name=&quot;Edit_hidden&quot;/&gt;
&lt;/folder&gt;
&lt;folder name=&quot;Menu&quot;&gt;
&lt;folder name=&quot;File&quot;&gt;
&lt;file name=&quot;org-openide-actions-SaveAction.instance_hidden&quot;/&gt;
&lt;file name=&quot;org-openide-actions-SaveAllAction.instance_hidden&quot;/&gt;
&lt;file name=&quot;org-netbeans-core-actions-RefreshAllFilesystemsAction.instance_hidden&quot;/&gt;
&lt;file name=&quot;org-openide-actions-PageSetupAction.instance_hidden&quot;/&gt;
&lt;file name=&quot;org-openide-actions-PrintAction.instance_hidden&quot;/&gt;
&lt;/folder&gt;
&lt;folder name=&quot;Edit_hidden&quot;/&gt;
&lt;folder name=&quot;Tools_hidden&quot;/&gt;
&lt;/folder&gt;
&lt;/filesystem&gt;</pre>
<h2><a name="distributing"></a>Distribuindo a aplica&ccedil;&atilde;o</H2>
<p>
O IDE usa um script de constru&ccedil;&atilde;o Ant para criar uma distribui&ccedil;&atilde;o do aplicativo. O script de constru&ccedil;&atilde;o &eacute; criado quando o projeto &eacute; criado.</P>
<ol>
<li>
Na janela Projetos, clique com o bot&atilde;o direito do mouse no n&oacute; do projeto <tt>Aplicativo FeedReader</tt> e escolha Construir distribui&ccedil;&atilde;o ZIP. A janela Sa&iacute;da mostra onde a distribui&ccedil;&atilde;o ZIP &eacute; criada. </li>
<li>
No sistema de arquivos, localize a distribui&ccedil;&atilde;o <tt>feedreader.zip</tt> na pasta <tt>dist</tt> no diret&oacute;rio do projeto. Descompacte-a. Inicie o aplicativo, que &eacute; encontrado na pasta <tt>bin</tt>. Durante a inicializa&ccedil;&atilde;o, uma tela de splash &eacute; exibida. Quando o aplicativo tiver sido iniciado, v&aacute; para a caixa de di&aacute;logo Ajuda &gt; Sobre e observe o &iacute;cone e a tela de splash especificados na se&ccedil;&atilde;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&eacute;m um n&oacute; chamado RSS/Atom Feeds. </P>
<p>
Parab&eacute;ns! Voc&ecirc; concluiu o tutorial FeedReader.</P>
<br>
<div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans Platform 6.0 Feed Reader Tutorial">Envie-nos seus coment&aacute;rios</a></div>
<br style="clear:both;" />
<hr>
</BODY>
</HTML>