blob: 25753fe1c9add2ea98b9219819f15ec2cca4675b [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>Руководство по созданию приложения для чтения каналов на платформе 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>
Руководство по созданию приложения для чтения каналов на платформе NetBeans
</H1>
<p>
Добро пожаловать в руководство по разработке приложений для чтения каналов на платформе NetBeans. Приложение для чтения каналов, создаваемое в настоящем руководстве, является простейшим обозревателем каналов RSS/Atom, моделируемых после запуска подключаемого модуля Sage для Mozilla Firefox. Он представляет собой дерево каналов с подузлами, отражающими отдельные сообщения каналов, которые могут быть открыты в обозревателе.
</p><p>Для иллюстрации конечного результата на рисунке показано приложение для чтения каналов, которое будет создано в этом руководстве, с сообщением из канала <a href="https://netbeans.org/rss-091.xml">NetBeans Highlights</a>:</P>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-result.png" border="1"/>
</div>
<p></p><p><b>Содержание</b></p>
<img src="../../images/articles/60/netbeans-stamp60-61.gif" class="stamp" width="114" height="114" alt="Содержимое на этой странице относится к среде IDE NetBeans 6.1" title="Содержимое на этой странице относится к среде IDE NetBeans 6.1"> </p>
<ul class="toc">
<li><A HREF="#knowledge" CLASS="XRef">Необходимые предварительные знания</A>
</li><li><A HREF="#setting" CLASS="XRef">Создание приложения</A>
</li><li><A HREF="#creating" CLASS="XRef">Создание окна приложения для чтения каналов</A>
</li><li><A HREF="#running" CLASS="XRef">Выполнение приложения</A>
</li><li><A HREF="#adding" CLASS="XRef">Добавление кода к приложению</A>
</li><li><A HREF="#branding" CLASS="XRef">Выбор стиля для приложения</A>
</li><li><A HREF="#distributing" CLASS="XRef">Подготовка дистрибутива приложения</A>
</li></ul>
<p><b>Для работы с этим руководством требуется программное обеспечение и ресурсы, перечисленные в следующей таблице. </b></p>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Программное обеспечение или ресурс</th>
<th class="tblheader" scope="col">Требуемая версия</th>
</tr>
<tr>
<td class="tbltd1">Среда IDE NetBeans</td>
<td class="tbltd1">версия <a href="http://download.netbeans.org/netbeans/6.1/final/">версия 6.1</a> или<br>
версия 6.0</td>
</tr>
<tr>
<td class="tbltd1">Комплект для разработчика на языке Java (JDK)</td>
<td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">версия 6</a> или<br>
версия 5</td>
</tr>
<tr>
<td class="tbltd1">Служебные программы RSS и atOM (<A HREF="https://rome.dev.java.net/" CLASS="URL">загрузить</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">загрузить</A></tt>)</td>
<td class="tbltd1"></td>
</tr>
<tr>
<td class="tbltd1">JDom (<A HREF="http://jdom.org/downloads/index.html" CLASS="URL">загрузить</A></tt>)</td>
<td class="tbltd1"></td>
</tr>
<tr>
<td class="tbltd1">Значок &quot;FeedReader&quot; и экран заставки (<A HREF="https://netbeans.org/files/documents/4/550/feedreader-images.zip" CLASS="URL">загрузить</A></tt>).</td>
<td class="tbltd1"></td>
</tr>
</tbody>
</table>
<h2><a name="knowledge"></a> Необходимые предварительные знания</H2>
<p>Для работы с настоящим руководством не требуются знания в области разработки на платформе NetBeans. Опыт программирования на Java может быть полезен, но его наличие не является обязательным условием. Тем не менее, перед работой с руководством желательно ознакомиться со следующими документами, содержащими рекомендуемую базовую информацию:
</p><ul>
<li><a href="https://platform.netbeans.org/tutorials/60/nbm-feedreader_background.html">Подготовка к созданию приложения для чтения каналов</a>. Этот документ содержит базовую информацию, с которой рекомендуется ознакомиться перед началом работы с данным руководством. В нем представлены концептуальные основы всех операций, описываемых в руководстве. В этом документе также приведены указания по получению исходного кода примера, который будет разработан по мере изучения настоящего руководства.</li>
<li><a href="../61/nbm-htmleditor_ru.html">Руководство по началу работы с платформой NetBeans</a>. Это краткое руководство содержит описание всего процесса создания функционально насыщенного клиентского приложения на платформе NetBeans. В нем рассматриваются основные этапы и средства разработки, при помощи которых в руководстве создается редактор HTML.</li>
</ul>
<h2><a name="setting"></a> Создание приложения</H2>
<p>
Создание приложения в среде IDE NetBeans начинается с создания большого количества файлов, используемых в качестве основы для приложения. Например, в среду IDE входит мастер проектов модулей, мастер проектов пакетов модулей и мастер модулей-оберток библиотек, применяемые для создания всех базовых файлов, необходимых для модулей и приложений, основанных на платформе NetBeans.</P>
<UL>
<li>
<b>Проект пакета модулей.</b> Проект, в рамках которого группируются проекты модулей и проекты модулей-оберток библиотек, зависящие друг от друга, которые могут развертываться совместно одним блоком.</li>
<li>
<b>Проект модуля-обертки библиотеки.</b> Проект, устанавливающий путь к классам для архива JAR библиотеки и экспортирующий некоторые или все пакеты архива JAR из модуля в виде общедоступных пакетов.</li>
<li>
<b>Проект модуля.</b> Проект, используемый для внедрения функциональных возможностей, бизнес-логики и интерфейса пользователя модуля или приложения на базе платформы NetBeans.</li>
</UL>
<h3>
Создание проекта пакета модулей</H3>
<ol>
<li>
Выберите &quot;File &gt; New Project&quot; (Ctrl-Shift-N). В области &quot;Categories&quot; выберите &quot;NetBeans Modules&quot;. В области &quot;Projects&quot; выберите &quot;Module Suite Project&quot;. Экран должен выглядеть следующим образом:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-suite-wiz.png" border="1"/>
</p><p>Нажмите кнопку &quot;Next&quot;.</p></li>
<li>
На экране &quot;Name and Location&quot; введите <tt> feedreader-suite</tt> в поле &quot;Project Name&quot;. В поле &quot;Project Location&quot; укажите любой каталог на компьютере. Экран должен выглядеть следующим образом:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-suite-wiz2.png" border="1"/>
</p><p>Нажмите кнопку &quot;Finish&quot;.</p></li>
</ol>
<p>В среде IDE создается проект <tt> feedreader-suite</tt>, который отображается в окне &quot;Projects&quot;:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-suite.png" border="1"/>
</p><p>Этот проект будет содержать проект модуля и проекты модулей-оберток библиотек, которые будут созданы в следующих подразделах. </P>
<h3>
Обертывание библиотек</H3>
Все приложение для чтения каналов может быть выполнено как отдельный модуль. Однако этому приложению требуются библиотеки Rome, Rome Fetcher и JDom:</P>
<UL>
<li>
<b>Rome.</b> Используется для чтения каналов RSS и Atom при помощи очень простого интерфейса API. </li>
<li>
<b>Rome Fetcher.</b> Позволяет получать каналы посредством HTTP. </li>
<li>
<b>JDom.</b> Представляет собой интерфейс API для синтаксического анализа XML. Необходимость наличия этой библиотеки для приложения для чтения каналов обусловлена лишь тем, что она используется библиотекой Rome.</li>
</UL>
Позднее при необходимости расширить приложение для чтения каналов путем добавления большего числа модулей, которые могут использовать эти библиотеки, целесообразно установить их зависимость от модулей библиотек, а не от всего приложения для чтения каналов. Кроме того, библиотечные модули могут быть &quot;автоматически загружаемыми&quot;, т.е. их загрузка будет осуществляться средой NetBeans только в случае необходимости. До этого момента ресурсы памяти на этапе выполнения расходоваться не будут.</P>
<ol>
<li>Щелкните правой кнопкой мыши узел &quot;Modules&quot; в проекте пакета модулей в окне &quot;Projects&quot;, как показано ниже, и выберите пункт &quot;Add New Library&quot;:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-add-lib0.png" border="1"/>
</p><p>После этого на экране должно отображаться следующее:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-lib-wiz.png" border="1"/>
</p></li><li>
На экране &quot;Select Library&quot;, показанном выше, найдите папку, в которую была загружена библиотека JDom, и затем выберите <tt> jdom.jar</tt> и <tt> LICENSE.txt</tt>. Нажмите кнопку &quot;Next&quot;.</li>
<li>
На экране &quot;Name and Location&quot; примите все значения по умолчанию. Экран должен выглядеть следующим образом:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-lib-wiz3.png" border="1"/>
</p><p><b>Примечание:</b> Модуль-обертка библиотеки будет сохранен в проекте пакета модулей. Он также может быть сохранен в другом месте, однако в целях управления версиями рекомендуется разместить его в проекте пакета модулей. Поэтому в раскрывающемся списке &quot;Add to Module Suite&quot; выбирается проект пакета модулей <tt> feedreader-suite</tt>.</p>
<p>Нажмите кнопку &quot;Next&quot;.</p></li>
<li>
На экране &quot;Basic Module Configuration&quot; примите все значения по умолчанию. Экран должен выглядеть следующим образом:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-lib-wiz2.png" border="1"/>
</p><p>Нажмите кнопку &quot;Finish&quot;.</p>
<p>Новый модуль-обертка библиотеки открывается в среде IDE и будет отображен в окне &quot;Projects&quot;. Окно &quot;Projects&quot; должно выглядеть следующим образом:</P>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-lib-wiz4.png" border="1">
</div></li>
<li>
Вернитесь к действию 1 этого раздела и создайте модуль-обертку для библиотеки Rome. Примите все значения по умолчанию.</li>
<li>
Вернитесь к действию 1 этого раздела и создайте модуль-обертку для библиотеки Rome Fetcher. Примите все значения по умолчанию.</li>
</ol>
<p>В этом разделе был создан проект пакета модулей с тремя модулями-обертками библиотек, содержащий большое количество удобных классов Java, которые могут использоваться по мере изучения руководства.
</p><h3>
Создание проекта модуля </H3>
<p>В этом разделе создается проект для реализации функциональных возможностей, которые должны предоставляться приложением. В проекте будут использоваться классы, доступные благодаря применению модулей-оберток библиотек, созданных в предыдущем разделе.</p>
<ol>
<li>
Щелкните правой кнопкой мыши узел &quot;Modules&quot; в проекте пакета модулей в окне &quot;Projects&quot;, как показано ниже, и выберите &quot;Add New&quot;:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-module-project.png" border="1"/>
</p><p>После этого на экране должно отображаться следующее:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-module-wiz.png" border="1"/>
</p></li>
<li>
На экране &quot;Name and Location&quot;, показанном выше, введите <tt> FeedReader</tt> в поле &quot;Project Name&quot;. Примите все значения по умолчанию. Нажмите кнопку &quot;Next&quot;.
</li><li>
На экране &quot;Basic Module Configuration&quot; замените значение <tt> yourorghere</tt> в поле &quot;Code Name Base&quot; на <tt> myorg</tt>, чтобы основа названия кода выглядела как <tt> org.myorg.feedreader.</tt> Введите <tt>FeedReader</tt> в поле &quot;Module Display Name&quot;. Не изменяйте местоположение пакета локализации и файла layer.xml для их сохранения в пакете с именем <tt> org/myorg/feedreader.</tt> Экран должен выглядеть следующим образом:</p>
<p><IMG SRC="../../images/tutorials/feedreader/60-module-wiz2.png" border="1"/>
</p><p></p><p>
Нажмите кнопку &quot;Finish&quot;.</p></li>
</ol>
<p>
Средой IDE будет создан проект &quot;FeedReader&quot;. Проект содержит все исходные файлы модуля и метаданные проекта, например, сценарий сборки Ant. Проект открывается в среде IDE. Логическую структуру проекта можно просмотреть в окне &quot;Projects&quot; (Ctrl-1), а структуру файлов &ndash; в окне &quot;Files&quot; (Ctrl-2). Теперь окно &quot;Projects&quot; должно выглядеть следующим образом:</P>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-module.png" border="1">
</div>
<p></p><p>Создана структура исходных файлов нового приложения. В следующем разделе мы приступим к добавлению кода.
</p><h2><a name="creating"></a> Создание окна приложения для чтения каналов </H2>
<p>
В этом разделе при помощи мастера оконных элементов генерируются файлы, необходимые для создания пользовательского элемента, а также действия для его вызова. Мастер также регистрирует действие как пункт меню в файле настройки <tt> layer.xml </tt> и добавляет значения, необходимые для многократного использования оконного элемента. После завершения этого раздела демонстрируется процесс использования некоторых файлов, созданных мастером оконных элементов.</P>
<ol>
<li>
Щелкните правой кнопкой мыши узел проекта <tt> FeedReader</tt> и выберите &quot;New &gt; Other&quot;. В области &quot;Categories&quot; выберите &quot;Module Development&quot;. В области &quot;File Types&quot; выберите &quot;Window Component&quot;, как показано ниже:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-windowcomp-wiz.png" border="1">
</div>
<p>
</p><p>Нажмите кнопку &quot;Next&quot;.</p></li>
<li>
На экране &quot;Basic Settings&quot; выберите <tt> explorer</tt> в раскрывающемся списке и установите флажок &quot;Open on Application Start&quot;, как показано ниже:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-windowcomp-wiz2.png" border="1">
</div>
<p></p><p>Нажмите кнопку &quot;Next&quot;.</p></li>
<li>
На экране &quot;Name and Location&quot; введите &quot;Feed&quot; в поле &quot;Class Name Prefix&quot; и укажите местоположение сохраненного файла <tt> rss16.gif (<IMG SRC="../../images/tutorials/feedreader/rss16.gif" />).</tt> Файл GIF будет показан в пункте меню, инициирующем действие. Экран должен выглядеть следующим образом:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-windowcomp-wiz3.png" border="1">
</div>
<p></p><p>Нажмите кнопку &quot;Finish&quot;.</p></li>
</ol>
<p>Окно &quot;Projects&quot; должно выглядеть следующим образом:
</p><div>
<IMG SRC="../../images/tutorials/feedreader/60-windowcomp.png" border="1">
</div>
<p></p><p>В среде IDE созданы следующие новые файлы:</P>
<UL>
<li>
<tt> FeedAction.java.</tt> Определяет действие, отображаемое в меню &quot;Window&quot; с текстом &quot;Open Feed Window&quot; и изображением <tt> rss16.gif</tt> (<IMG SRC="../../images/tutorials/feedreader/rss16.gif" />). Оно используется для открытия окна &quot;Feed Window&quot;. </li>
<li>
<tt> FeedTopComponent.java.</tt> Определяет окно &quot;Feed Window&quot;. </li>
<li>
<tt> FeedTopComponentSettings.xml.</tt> Используется для определения всех интерфейсов функционально насыщенного клиентского приложения <tt> org.myorg.feedreader</tt>. Обеспечивает простой поиск экземпляров без необходимости создания каждого из них; позволяет избежать необходимости в загрузке классов или создании объектов и, тем самым, повышает производительность. Регистрируется в папке <tt> Windows2/Components</tt> файла <tt> layer.xml</tt>.</li>
<li>
<tt> FeedTopComponentWstcref.xml.</tt> Используется для определения ссылки на элемент; дает возможность присвоения элемента более чем одному режиму и регистрируется в папке <tt>Windows2/Modes</tt> файла <tt> layer.xml</tt>.</li>
</UL>
Средой IDE были изменены следующие существующие файлы:</P>
<UL>
<li>
<b></b> <A NAME="project.xml"></A><tt> project.xml.</tt> Добавлены две зависимости модулей, <tt> Utilities API </tt> (щелкните <A HREF="http://bits.netbeans.org/dev/javadoc/org-openide-util/overview-summary.html" CLASS="URL">здесь</A></tt> для просмотра документации Javadoc) и <tt> Window System API </tt> (щелкните <A HREF="http://bits.netbeans.org/dev/javadoc/org-openide-windows/overview-summary.html" CLASS="URL">здесь</A></tt> для просмотра документации Javadoc).</li>
<li>
<tt> Bundle.properties.</tt> <A NAME="Bundle.properties"></A> Добавлены три пары &quot;ключ-значение&quot;:<br>
<ul>
<li><tt>CTL_FeedAction.</tt> Позволяет локализовать текст пункта меню, определенного в <tt>FeedAction.java</tt>.
</li><li><tt>CTL_FeedTopComponent.</tt> Позволяет локализовать текст <tt>FeedTopComponent.java</tt>.
</li><li><tt>HINT_FeedTopComponent.</tt> Позволяет локализовать всплывающую подсказку <tt>FeedTopComponent.java</tt>.
</li></ul>
</li>
</UL>
<p>Итак, в файл <tt>layer.xml</tt> добавлены три регистрационных записи.</li>
</p><p>
Эти записи в файле <tt> layer.xml</tt> предназначены для следующего:</P>
<UL>
<li>
<tt> &lt;Actions&gt;</tt>
<br>
Регистрирует действие в качестве действия в папке &quot;Window&quot;.</li>
<li>
<tt> &lt;Menu&gt;</tt>
<br>
Регистрирует действие в качестве пункта в меню &quot;Window&quot;.</li>
<li>
<tt> &lt;Windows2&gt; <br>
</tt> Регистрирует файл <tt>FeedTopComponentSettings.xml</tt>, используемый для поиска оконного элемента. Регистрирует ссылочный файл элемента <tt>FeedTopComponentWstcref.xml</tt> в области &quot;explorer&quot;.
<br>
</tt>
</li>
</UL>
<h2><a name="running"></a> Выполнение приложения</H2>
<p>
Приложение, для которого не была написана ни одна строка кода, уже может быть запущено. Попытка его использования приведет к развертыванию модулей на платформе NetBeans и к последующей проверки корректности отображения пустого окна &quot;Feed Window&quot;.</P>
<ol>
<li>Сначала удалим все модули, определяющие среду IDE NetBeans, которые не потребуются в приложении для чтения каналов. Щелкните правой кнопкой мыши проект <tt>feedreader-suite</tt>, выберите &quot;Properties&quot;, а затем щелкните пункт &quot;Libraries&quot; в диалоговом окне &quot;Project Properties&quot;.</p>
<p>Появится список &quot;кластеров&quot;. Каждый кластер представляет собой ряд связанных модулей. Единственным необходимым кластером является кластер &quot;platform&quot;, поэтому отмените выбор всех других кластеров и оставьте только один флажок напротив кластера &quot;platform&quot;:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-runapp4.png" border="1">
</div>
<p></p><p>Разверните кластер &quot;platform&quot; и просмотрите содержащиеся в нем модули:
</p><div>
<IMG SRC="../../images/tutorials/feedreader/60-runapp5.png" border="1">
</div>
<p></p><p>Модули платформы обеспечивают общую платформу приложений Swing. Так как был выбран кластер &quot;platform&quot;, создавать &quot;технический&quot; код для инфраструктуры приложения, например, строки меню, системы управления окнами и функциональности для начальной загрузки, не потребуется.
</p><p></p><p>Нажмите кнопку &quot;OK&quot;.
</p></li><li>В окне &quot;Projects&quot; щелкните правой кнопкой мыши проект <tt> feedreader-suite</tt> и выберите &quot;Clean and Build All&quot;.
</li><li>В окне &quot;Projects&quot; щелкните правой кнопкой мыши проект <tt> feedreader-suite</tt> и выберите &quot;Run&quot;, как показано ниже:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-runapp.png" border="1">
</div>
</li></ol>
<p>
</p><p>Приложение будет запущено. На экране появится заставка. После этого будет открыто приложение и появится новое окно &quot;Feed Window&quot;, представляющее собой окно обозревателя, показанное ниже:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-runapp2.png" border="1">
</div>
<p></p><p><b>Примечание:</b> В настоящий момент в состав приложения входят следующие модули:
</p><ul>
<li>Модули, поставляемые с платформой NetBeans и предназначенные для загрузки приложения, управления жизненным циклом и выполнения других операций, связанных с инфраструктурой.
</li><li>Три модуля-обертки библиотек, созданные в рамках этого руководства.
</li><li>Модуль функциональных возможностей чтения каналов, созданный в рамках этого руководства и предназначенный для вывода окна &quot;Feed Window&quot;.
</li></ul>
<p></p><p>В меню &quot;Window&quot; приложения должен появиться новый пункт (см. ниже), используемый для открытия окна &quot;Feed Window&quot; в случае, если оно закрыто:</li>
</p><div>
<IMG SRC="../../images/tutorials/feedreader/60-runapp3.png" border="1">
</div>
<p>
</p><p>Итак, нами было создано готовое приложение без написания какого-либо кода. Оно не содержит множества возможностей, однако его инфраструктура существует и функционирует так, как ожидалось. В следующих разделах мы приступим к добавлению кода в приложение при помощи интерфейсов API среды NetBeans.
</p><h2><a name="adding"></a> Добавление кода к приложению</H2>
<p>
После создания основы для приложения можно приступить к добавлению собственного кода. Перед этим для приложения необходимо определить зависимости. Зависимости &ndash; это модули, предоставляющие интерфейсы API NetBeans, которые будут расширены или реализованы. После этого при помощи мастера создания файла и редактора исходного кода будут созданы и закодированы классы, добавляемые в приложение для чтения каналов.
</p><h3>
Определение зависимостей для приложения</H3>
Необходимо создать подклассы нескольких классов, принадлежащих интерфейсам API среды NetBeans. Классы относятся к модулям, которые должны быть объявлены как зависимости приложения для чтения каналов. Для этой цели используйте диалоговое окно &quot;Project Properties&quot;, как показано ниже.</P>
<ol>
<li>
В окне &quot;Projects&quot; щелкните правой кнопкой мыши проект <tt> FeedReader</tt> и выберите &quot;Properties&quot;. В диалоговом окне &quot;Project Properties&quot; выберите &quot;Libraries&quot;. Обратите внимание, что некоторые показанные ниже интерфейсы API уже были объявлены в качестве зависимостей (область &quot;Module Dependencies&quot;):</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-add-lib1.png" border="1">
</div>
<p>
</p><p>Показанные выше регистрационные записи библиотек были созданы ранее при работе с данным руководством с использованием мастера оконных элементов.</p></li>
<li>
Нажмите кнопку &quot;Add Dependency&quot;.</li>
<li>
Добавьте следующие интерфейсы API:
<pre class="examplecode">
Actions API
Datasystems API
Dialogs API
Explorer and Property Sheet API
File System API
Nodes API
rome
rome-fetcher</pre>
<p>Экран должен выглядеть следующим образом:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-add-lib2.png" border="1">
</div>
<p></p><p>Нажмите кнопку &quot;OK&quot; для закрытия диалогового окна &quot;Project Properties&quot;. </p></li>
<li>Разверните узел &quot;Libraries&quot; проекта <tt>FeedReader</tt> и обратите внимание на список модулей, доступных в этом проекте:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-add-lib5.png" border="1">
</div>
</li></ol>
<h3>
Установка зависимостей между модулями-обертками библиотек</h3>
<p>После определения используемых зависимостей модулей интерфейсов API среды NetBeans можно установить зависимости между модулями-обертками библиотек. Например, в файле JAR библиотеки Rome используются классы из файла JAR библиотеки JDom. Теперь, когда они обернуты в отдельных модулях-обертках библиотек, необходимо определить связь между файлами JAR в диалоговом окне &quot;Project Properties&quot; модуля-обертки библиотеки.</p>
<ol>
<li>
Сначала установите зависимость библиотеки Rome от библиотеки JDom. Щелкните правой кнопкой мыши проект модуля-обертки библиотеки Rome в окне &quot;Projects&quot; и выберите &quot;Properties&quot;. В диалоговом окне &quot;Project Properties&quot; выберите &quot;Libraries&quot; и затем &quot;Add Dependency&quot;. Добавьте зависимости <tt>jdom</tt>. Экран должен выглядеть следующим образом:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-add-lib3.png" border="1">
</div>
<p></p><p>Нажмите кнопку &quot;OK&quot; для закрытия диалогового окна &quot;Project Properties&quot;.</p></li>
<li>
Теперь, после установки зависимости библиотеки Rome Fetcher от библиотек Rome и JDom одновременно, необходимо создать зависимость Rome Fetcher от Rome, показанную ниже:</p>
<div>
<IMG SRC="../../images/tutorials/feedreader/60-add-lib4.png" border="1">
</div>
<p></p><p>Поскольку библиотека Rome уже зависит от JDom, определять зависимость библиотеки Rome Fetcher от JDom не требуется. </p></li>
</ol>
<h3>
Создание папки &quot;RssFeeds&quot;</H3>
<p>Для добавления папки в файл <tt>layer.xml</tt> будет использоваться интерфейс пользователя среды IDE. Папка будет содержать объекты канала RSS. Затем к объекту <tt> FeedTopComponent.java</tt>, созданному в мастере оконных элементов, будет добавлен код для просмотра содержимого этой папки.</P>
<ol>
<li>
В окне &quot;Projects&quot; разверните узел проекта <tt> FeedReader</tt>, а затем разверните узлы &quot;Important Files&quot; и &quot;XML Layer&quot;. На экране должны быть представлены следующие узлы:<p></p><p>
</p><ul><li><tt> &lt;this layer&gt;.</tt> Используется для вывода на экран папок, содержащихся в текущем модуле. Например, как видно на приведенном ниже рисунке, модуль &quot;FeedReader&quot; содержит папки с именами &quot;Actions&quot;, &quot;Menu&quot; и &quot;Windows2&quot;, ранее описанные в данном руководстве:
<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> Используется для вывода на экран всех папок, доступных во всем приложении. Этот узел будет рассматриваться далее в настоящем руководстве.<br>
<br></li></ul>
</li>
<li>
Щелкните правой кнопкой мыши узел <tt> &lt;this layer&gt;</tt> и выберите &quot;New &gt; Folder&quot;, как показано ниже:
<p></p><div>
<IMG SRC="../../images/tutorials/feedreader/60-feedfolder-2.png" border="1">
</div>
</li>
<li>
Введите <tt> RssFeeds</tt> в диалоговом окне &quot;New Folder&quot;. Нажмите кнопку &quot;OK&quot;. Таким образом, была создана новая папка, показанная ниже:
<p></p><div>
<IMG SRC="../../images/tutorials/feedreader/60-feedfolder-3.png" border="1">
</div>
</li><li>Дважды щелкните узел файла <tt> layer.xml</tt> для его открытия в редакторе исходного кода. Обратите внимание на добавление следующей записи:<br>
<tt>
<br>
&lt;folder name=&quot;RssFeeds&quot;/&gt;</tt>
</li>
</ol>
<h3>
Создание объекта канала </H3>
<p>Затем создайте простой элемент POJO, инкапсулирующий URL-адрес и связанный с ним канал Rome.</p>
<ol>
<li>
Щелкните правой кнопкой мыши узел проекта <tt> FeedReader</tt> и выберите &quot;New &gt; Java Class&quot;. Нажмите кнопку &quot;Next&quot;. </li>
<li>
Присвойте классу имя <tt> Feed</tt> и выберите <tt> org.myorg.feedreader</tt> в раскрывающемся списке &quot;Package&quot;. Нажмите кнопку &quot;Finish&quot;.</li>
<li>
В редакторе исходного кода замените класс <tt> Feed</tt>, установленный по умолчанию, на следующий:</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>
Значительная часть кода подчеркнута, поскольку многие пакеты не были объявлены. Это будет выполнено в дальнейшем. </P>
Для переформатирования файла и объявления его зависимостей выполните следующие действия:</P>
<ol>
<li>
Нажмите Alt-Shift-F для форматирования кода. </li>
<li>
Нажмите Ctrl-Shift-I и проверьте, что выбраны следующие операторы импорта:
<p></p><div>
<IMG SRC="../../images/tutorials/feedreader/60-imports.png" border="1">
</div>
<p></p><p>Нажмите кнопку &quot;OK&quot;, после чего в класс будут добавлены следующие операторы импорта:
</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>
Красное подчеркивание должно исчезнуть. В противном случае не выполняйте следующие действия, указанные в этом руководстве, до разрешения проблемы.</P>
<h3>
Добавление окна &quot;Feed Window&quot;</H3>
<ol>
<li>
Дважды щелкните элемент <tt> FeedTopComponent.java</tt> для его открытия в редакторе исходного кода.</li>
<li>
Введите строку <tt> implements ExplorerManager.Provider</tt> в конце объявления класса.</li>
<li>
Нажмите Alt-Enter, установив курсор на строке, и щелкните предложенное значение. Средой IDE будет добавлен оператор импорта для требуемого пакета <tt> org.openide.explorer.ExplorerManager</tt>.</li>
<li>
Снова нажмите Alt-Enter и щелкните предложенное значение. При этом будет реализован абстрактный метод <tt> getExplorerManager()</tt>. </li>
<li>
Введите <tt> return manager;</tt> в теле нового метода <tt> getExplorerManager() </tt>. Нажмите Alt-Enter, установив курсор на строку, после чего будет создано поле под названием <tt> manager</tt>. Замените определение по умолчанию на следующее:
<pre class="examplecode">private final ExplorerManager manager = new ExplorerManager();</pre>
</li>
<li>
Сразу после объявления поля на предыдущем этапе объявите этот класс:<br>
<pre class="examplecode">private final BeanTreeView view = new BeanTreeView();</pre>
</li>
<li>
После этого добавьте следующий код в конце конструктора:<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>
В настоящее время большая часть кода подчеркнута, поскольку соответствующие пакеты не были объявлены. Это будет выполнено в дальнейшем. </P>
<p>
Для переформатирования файла и объявления его зависимостей выполните следующие действия:</P>
<ol>
<li>
Нажмите Alt-Shift-F для форматирования кода. </li>
<li>
Нажмите Ctrl-Shift-I, выберите <tt>org.openide.ErrorManager</tt>, нажмите кнопку &quot;OK&quot;, после чего под оператором пакета будет создано несколько операторов импорта. Теперь полный список операторов импорта должен выглядеть следующим образом:
<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>
Следует отметить, что строка <tt> manager.setRootContext(new RssNode.RootRssNode());</tt> по-прежнему подчеркнута красным цветом, поскольку элемент <tt> RssNode.java </tt> до сих пор не создан. Это будет выполнено в следующем подразделе. Прочие красные линии должны исчезнуть. В противном случае не выполняйте следующие действия, указанные в этом руководстве, до разрешения проблемы.</li>
</ol>
<h3>
Создание класса &quot;RssNode&quot;</H3>
<p></p><p>Верхний узел приложения для чтения каналов обеспечивается классом &quot;RssNode&quot;. Этот класс расширяет <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/FilterNode.html">FilterNode</a></tt>, используемый в качестве прокси для узла &quot;RssFeeds&quot;. На этом этапе будет определено отображаемое имя и объявлены два пункта меню &quot;Add&quot; и &quot;Add Folder&quot;, показанные ниже:
</p><p></p><div>
<IMG SRC="../../images/tutorials/feedreader/60-actions.png" border="1">
</div></p>
<p>Для создания этого класса выполните следующие действия:
</p><ol>
<li>
Создайте элемент <tt> RssNode.java</tt> в пакете <tt> org.myorg.feedreader</tt>.</li>
<li>
Замените класс по умолчанию на следующий:</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>//Объявление действий и переход к папке данных узла:</b>
DataFolder df = getLookup().lookup(DataFolder.class);
return new Action[]{
new AddRssAction(df),
new AddFolderAction(df)
};
}
public static class RootRssNode extends RssNode {
<b>//Узел фильтра будет служить в качестве прокси для узла &quot;RssFeeds&quot;, который здесь будет получен из пользовательского каталога NetBeans:</b>
public RootRssNode() throws DataObjectNotFoundException {
super(DataObject.find(Repository.getDefault().getDefaultFileSystem().
getRoot().getFileObject(&quot;RssFeeds&quot;)).getNodeDelegate());
}
<b>//Определение отображаемого имени узла, относящегося к объединенному файлу, и ключа, который будет определен позже:</b>
@Override
public String getDisplayName() {
return NbBundle.getMessage(RssNode.class, &quot;FN_title&quot;);
}
}
}</pre>
</ol>
<p>Некоторые строки кода, относящиеся к классу, по-прежнему подчеркиваются красным цветом, поскольку не были созданы действия и класс, определяющий нижестоящие узлы.
</p><h3>
Создание класса &quot;RssFolderChildren&quot;</H3>
<p>Теперь обратимся к дочерним узлам узла &quot;RSS/Atom Feeds&quot;. Дочерние элементы являются папками или каналами. Все это реализуется посредством кода, приведенного ниже.
</p><p>Для создания этого класса выполните следующие действия:
</p><ol>
<li>
Создайте элемент <tt> RssFolderChildren.java</tt> в пакете <tt> org.myorg.feedreader</tt>.</li>
<li>
Замените класс по умолчанию на следующий:</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>//При нахождении папки данных создается узел &quot;RssNode&quot;, в противном случае осуществляется поиск канала и создание узла &quot;OneFeedNode&quot;:</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 {
// Лучшее из возможного
return new Node[]{new FilterNode(n)};
}
}
} catch (IOException ioe) {
Exceptions.printStackTrace(ioe);
} catch (IntrospectionException exc) {
Exceptions.printStackTrace(exc);
}
// Другой тип узла (требует какой-то обработки)
return new Node[]{new FilterNode(n)};
}
/** Поиск канала */
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>Некоторые строки кода, относящегося к классу, подчеркнуты красным цветом, поскольку класс <tt>OneFeedNode</tt> до сих пор не создан.
</p><h3>
Создание класса &quot;OneFeedNode&quot;</H3>
<p>В этом разделе рассматривается контейнер узлов статьей, проиллюстрированный ниже на примере узла &quot;NetBeans Highlights&quot;:
</p><p></p><div>
<IMG SRC="../../images/tutorials/feedreader/60-actions2.png" border="1">
</div></p>
<p>Можно отметить, что каждый из этих узлов имеет отображаемое имя, получаемое из канала, значок и пункт меню &quot;Delete&quot;.
</p><p>Для создания этого класса выполните следующие действия:
</p><ol>
<li>
Создайте элемент <tt> OneFeedNode.java</tt> в пакете <tt> org.myorg.feedreader</tt>.</li>
<li>
Замените класс по умолчанию на следующий:</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>Некоторые строки кода, относящегося к классу, подчеркнуты красным цветом, поскольку <tt>FeedChildren</tt> до сих пор не создан.
</p><h3>
Создание класса &quot;FeedChildren&quot;</H3>
<p>В этом разделе будет добавлена часть кода, необходимого для представления узлов для каждой из статей, содержащихся в канале.
</p><p>Для создания этого класса выполните следующие действия:
</p><ol>
<li>
Создайте элемент <tt> FeedChildren.java</tt> в пакете <tt> org.myorg.feedreader</tt>.</li>
<li>
Замените класс по умолчанию на следующий:</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>//Возвращение новых узлов на уровне статьи:</b>
try {
return new Node[]{
new EntryBeanNode((SyndEntry) key)
};
} catch (final IntrospectionException ex) {
Exceptions.printStackTrace(ex);
<b>//Это не должно происходить, причины для сбоя отсутствуют:</b>
return new Node[]{new AbstractNode(Children.LEAF) {
@Override
public String getHtmlDisplayName() {
return &quot;&quot; + ex.getMessage() + &quot;&quot;;
}
}};
}
}
}</pre>
</ol>
<p>Некоторые строки кода, относящегося к классу, подчеркнуты красным цветом, поскольку <tt>EntryBeanNode</tt> до сих пор не создан.
</p><h3>
Создание класса &quot;EntryBeanNode&quot;</H3>
<p>Теперь рассмотрим узлы самых нижних уровней, отражающие статьи, содержащиеся в канале.
</p><p>Для создания этого класса выполните следующие действия:
</p><ol>
<li>
Создайте элемент <tt> EntryBeanNode.java</tt> в пакете <tt> org.myorg.feedreader</tt>.</li>
<li>
Замените класс по умолчанию на следующий:</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>/** Использование &quot;HtmlDisplayName&quot; обеспечивает правильность обработки, выхода, получения объектов и т.д. для любого кода HTML в заголовках сообщений RSS. */</b>
@Override
public String getHtmlDisplayName() {
return entry.getTitle();
}
<b>/** Создание всплывающей подсказки к описанию сообщения */</b>
@Override
public String getShortDescription() {
return entry.getDescription().getValue();
}
<b>/** Ввод действия &quot;Open&quot; для сообщения канала */</b>
@Override
public Action[] getActions(boolean popup) {
return new Action[]{SystemAction.get(OpenAction.class)};
}
@Override
public Action getPreferredAction() {
return (SystemAction) getActions(false) [0];
}
<b>/** Указание на операцию, выполняемую после вызова пользователем действия &quot;Open&quot; */</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>
Создание пункта меню &quot;Add Folder&quot;</H3>
<p>В этом разделе создается пункт меню, предназначенный для создания объявленных ранее папок.
</p><p>Для создания этого класса выполните следующие действия:
</p><ol>
<li>
Создайте элемент <tt> AddFolderAction.java</tt> в пакете <tt> org.myorg.feedreader</tt>.</li>
<li>
Замените класс по умолчанию на следующий:</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>
Создание пункта меню &quot;Add RSS&quot;</H3>
<p>В этом разделе рассматривается создание пункта меню для добавления новых каналов.
</p><p>Для создания этого класса выполните следующие действия:
</p><ol>
<li>
Создайте элемент <tt> AddRssAction.java</tt> в пакете <tt> org.myorg.feedreader</tt>.</li>
<li>
Замените класс по умолчанию на следующий:</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>
Локализация класса &quot;RssNode&quot;</H3>
<ol>
<li>
Откройте файл <tt> Bundle.properties</tt> модуля <tt> FeedReader</tt>.</li>
<li>
Добавьте следующие пары &quot;ключ-значение&quot;:<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>
Ниже приведено пояснение новых пар &quot;ключ-значение&quot;, локализующих строки, определенные в элементе <tt> RssNode.java</tt>:</P>
<UL>
<li>
<b>FN_title.</b> Локализует текст верхнего узла в окне &quot;Feed Window&quot;.</li>
</UL>
Локализация интерфейса пользователя для добавления канала:</P>
<UL>
<li>
<b>FN_addbutton.</b> Локализует текст пункта меню &quot;Add&quot; в контекстном меню верхнего узла.</li>
<li>
<b>FN_askurl_title.</b> Локализует заголовок диалогового окна &quot;New Feed&quot;.</li>
<li>
<b>FN_askurl_msg.</b> Локализует сообщение, появляющееся в диалоговом окне &quot;New Feed&quot;.</li>
<li>
<b>FN_askurl_err.</b> Локализует строку ошибки, отображаемую в случае недействительности URL-адреса.</li>
</UL>
Локализация интерфейса пользователя для добавления папки:</P>
<UL>
<li>
<b>FN_addfolderbutton.</b> Локализует текст пункта меню &quot;Add Folder&quot; в контекстном меню верхнего узла.</li>
<li>
<b>FN_askfolder_msg.</b> Локализует сообщение, появляющееся в диалоговом окне &quot;Add Folder&quot;.</li>
<li>
<b>FN_askfolder_title. </b> Локализует заголовок диалогового окна &quot;Add Folder&quot;.</li>
</UL>
<h2><a name="branding"></a> Выбор стиля для приложения</H2>
<p>
В конце цикла разработки, на этапе заключительной подготовки приложения, необходимо рассмотреть следующие вопросы:</P>
<UL>
<li>
Каким должно быть имя исполняемого файла приложения?</li>
<li>
Что должен увидеть пользователь после запуска приложения? Индикатор хода выполнения? Экран заставки? И то, и другое?</li>
<li>
Что должно отображаться в строке заголовка при запуске приложения?</li>
<li>
Являются ли все меню и кнопки панелей инструментов, предоставляемые платформой NetBeans по умолчанию, действительно необходимыми?</li>
</UL>
<p>
Эти вопросы относятся к сфере выбора стиля, персонализации приложения, построенного на базе платформы NetBeans. В среде IDE в диалоговом окне &quot;Project Properties&quot; проектов пакетов модулей предусмотрена специальная панель, упрощающая выбор стиля.</P>
<ol>
<li>
Щелкните правой кнопкой мыши узел проекта <tt> feedreader-suite</tt> (а не узел проекта <tt> FeedReader</tt>) и выберите &quot;Properties&quot;. В диалоговом окне &quot;Project Properties&quot; выберите &quot;Build&quot;. </li>
<li>
На экране &quot;Build&quot; введите значение <tt> feedreader</tt> в поле &quot;Branding Name&quot;. Введите <tt> Feed Reader Application</tt> в поле &quot;Application Title&quot;. Значение поля &quot;Branding Name&quot; определяет имя исполняемой программы, а значение поля &quot;Application Title&quot; &ndash; строку заголовка приложения. </li>
<li>
Нажмите кнопку &quot;Browse&quot; и найдите значок <tt> rss16.gif</tt> (<IMG SRC="../../images/tutorials/feedreader/rss16.gif" />). Значок будет отображаться в диалоговом окне &quot;Help &gt; About&quot;.</li>
<p>Экран должен выглядеть следующим образом:</p>
<IMG SRC="../../images/tutorials/feedreader/60-brand1.png" border="1"/>
<li>
На экране &quot;Splash Screen&quot; нажмите кнопку &quot;Browse&quot; и найдите файл <tt> splash.gif</tt> . Кроме того, можно изменить цвет и размер текста индикатора хода выполнения. Если индикатор хода выполнения не требуется, снимите флажок &quot;Enabled&quot;.</li>
<p>Экран должен выглядеть следующим образом:</p>
<IMG SRC="../../images/tutorials/feedreader/60-brand2.png" border="1"/>
<li>
Нажмите кнопку &quot;OK&quot;.<br>
В проекте <tt> FeedReader Application</tt> будет создана папка <tt> branding</tt>. Она будет отображена в окне &quot;Files&quot; (Ctrl-2).</li>
<li>
В окне &quot;Files&quot; разверните узел проекта <tt> FeedReader Application</tt>. После этого продолжайте разворачивать узлы до тех пор, пока не найдете следующий узел:<br>
<tt> branding/modules/org-netbeans-core-window.jar/org/netbeans/core/windows</tt>
</li>
<li>
Щелкните правой кнопкой мыши этот узел, выберите &quot;New &gt; Other&quot;, а затем пункт &quot;Folder&quot; в категории &quot;Other&quot;. Нажмите кнопку &quot;Next&quot; и присвойте папке имя <tt> resources</tt> . Нажмите кнопку &quot;Finish&quot;. </li>
<li>
Щелкните правой кнопкой мыши новый узел <tt> resources</tt>, выберите &quot;New &gt; Other&quot;, а затем &quot;XML Document&quot; в категории XML. Нажмите кнопку &quot;Next&quot;. Присвойте файлу имя <tt> layer</tt> . Нажмите кнопку &quot;Next&quot;, а затем кнопку &quot;Finish&quot;. Замените содержимое нового файла <tt> layer.xml</tt> на следующий текст:</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;!--
Это уровень &quot;стиля&quot;. Он объединяется с файлом layer.xml, для настройки которого используется.
В данном случае осуществляется скрытие нежелательных пунктов меню и панелей инструментов.
--&gt;
&lt;filesystem&gt;
&lt;!-- Скрытие неиспользуемых панелей инструментов --&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> Подготовка дистрибутива приложения</H2>
<p>
Для создания дистрибутива приложения в среде IDE используется сценарий сборки Ant. Сценарий сборки создается при создании проекта.</P>
<ol>
<li>
В окне &quot;Projects&quot; щелкните правой кнопкой мыши узел проекта <tt> FeedReader Application</tt> и выберите &quot;Build ZIP Distribution&quot;. В окне &quot;Output&quot; отображается местоположение созданного ZIP-файла дистрибутива. </li>
<li>
В файловой системе найдите дистрибутив <tt> feedreader.zip</tt> в папке <tt> dist</tt> каталога проекта. Разархивируйте его. Запустите приложение, находящееся в папке <tt> bin</tt>. При запуске на экране отобразится заставка. После запуска приложения вызовите диалоговое окно &quot;Help &gt; About&quot; и обратите внимание на значок и экран заставки, которые были настроены в разделе <A HREF="#branding" CLASS="XRef">Выбор стиля для приложения</A>.</li>
</ol>
<p>
После запуска и в ходе работы в приложении для чтения каналов отображается окно &quot;RSS/Atom Feeds&quot;, содержащее узел под названием &quot;RSS/Atom Feeds&quot;. </P>
<p>
Поздравляем! Изучение руководства по созданию приложения для чтения каналов завершено.</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">Мы ждем ваших отзывов</a></div>
<br style="clear:both;" />
<hr>
</BODY>
</HTML>