| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| |
| = Руководство по созданию приложения для чтения каналов на платформе NetBeans |
| :jbake-type: platform_tutorial |
| :jbake-tags: tutorials |
| :jbake-status: published |
| :syntax: true |
| :source-highlighter: pygments |
| :toc: left |
| :toc-title: |
| :icons: font |
| :experimental: |
| :description: Руководство по созданию приложения для чтения каналов на платформе NetBeans - Apache NetBeans |
| :keywords: Apache NetBeans Platform, Platform Tutorials, Руководство по созданию приложения для чтения каналов на платформе NetBeans |
| |
| Добро пожаловать в руководство по разработке приложений для чтения каналов на платформе NetBeans. Приложение для чтения каналов, создаваемое в настоящем руководстве, является простейшим обозревателем каналов RSS/Atom, моделируемых после запуска подключаемого модуля Sage для Mozilla Firefox. Он представляет собой дерево каналов с подузлами, отражающими отдельные сообщения каналов, которые могут быть открыты в обозревателе. |
| |
| Для иллюстрации конечного результата на рисунке показано приложение для чтения каналов, которое будет создано в этом руководстве, с сообщением из канала link:https://netbeans.org/rss-091.xml[NetBeans Highlights]: |
| |
| |
| image::images/feedreader_60-result.png[] |
| |
| |
| |
| |
| |
| |
| |
| |
| == Необходимые предварительные знания |
| |
| Для работы с настоящим руководством не требуются знания в области разработки на платформе NetBeans. Опыт программирования на Java может быть полезен, но его наличие не является обязательным условием. Тем не менее, перед работой с руководством желательно ознакомиться со следующими документами, содержащими рекомендуемую базовую информацию: |
| |
| * link:https://netbeans.apache.org/tutorials/60/nbm-feedreader_background.html[Подготовка к созданию приложения для чтения каналов]. Этот документ содержит базовую информацию, с которой рекомендуется ознакомиться перед началом работы с данным руководством. В нем представлены концептуальные основы всех операций, описываемых в руководстве. В этом документе также приведены указания по получению исходного кода примера, который будет разработан по мере изучения настоящего руководства. |
| * link:../61/nbm-htmleditor_ru.html[Руководство по началу работы с платформой NetBeans]. Это краткое руководство содержит описание всего процесса создания функционально насыщенного клиентского приложения на платформе NetBeans. В нем рассматриваются основные этапы и средства разработки, при помощи которых в руководстве создается редактор HTML. |
| |
| |
| == Создание приложения |
| |
| Создание приложения в среде IDE NetBeans начинается с создания большого количества файлов, используемых в качестве основы для приложения. Например, в среду IDE входит мастер проектов модулей, мастер проектов пакетов модулей и мастер модулей-оберток библиотек, применяемые для создания всех базовых файлов, необходимых для модулей и приложений, основанных на платформе NetBeans. |
| |
| * *Проект пакета модулей.* Проект, в рамках которого группируются проекты модулей и проекты модулей-оберток библиотек, зависящие друг от друга, которые могут развертываться совместно одним блоком. |
| * *Проект модуля-обертки библиотеки.* Проект, устанавливающий путь к классам для архива JAR библиотеки и экспортирующий некоторые или все пакеты архива JAR из модуля в виде общедоступных пакетов. |
| * *Проект модуля.* Проект, используемый для внедрения функциональных возможностей, бизнес-логики и интерфейса пользователя модуля или приложения на базе платформы NetBeans. |
| |
| |
| === Создание проекта пакета модулей |
| |
| |
| [start=1] |
| 1. Выберите "File > New Project" (Ctrl-Shift-N). В области "Categories" выберите "NetBeans Modules". В области "Projects" выберите "Module Suite Project". Экран должен выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-suite-wiz.png[] |
| |
| Нажмите кнопку "Next". |
| |
| |
| [start=2] |
| 1. На экране "Name and Location" введите `` feedreader-suite`` в поле "Project Name". В поле "Project Location" укажите любой каталог на компьютере. Экран должен выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-suite-wiz2.png[] |
| |
| Нажмите кнопку "Finish". |
| |
| В среде IDE создается проект `` feedreader-suite`` , который отображается в окне "Projects": |
| |
| |
| image::images/feedreader_60-suite.png[] |
| |
| Этот проект будет содержать проект модуля и проекты модулей-оберток библиотек, которые будут созданы в следующих подразделах. |
| |
| |
| === Обертывание библиотек |
| |
| Все приложение для чтения каналов может быть выполнено как отдельный модуль. Однако этому приложению требуются библиотеки Rome, Rome Fetcher и JDom: |
| |
| * *Rome.* Используется для чтения каналов RSS и Atom при помощи очень простого интерфейса API. |
| * *Rome Fetcher.* Позволяет получать каналы посредством HTTP. |
| * *JDom.* Представляет собой интерфейс API для синтаксического анализа XML. Необходимость наличия этой библиотеки для приложения для чтения каналов обусловлена лишь тем, что она используется библиотекой Rome. |
| |
| Позднее при необходимости расширить приложение для чтения каналов путем добавления большего числа модулей, которые могут использовать эти библиотеки, целесообразно установить их зависимость от модулей библиотек, а не от всего приложения для чтения каналов. Кроме того, библиотечные модули могут быть "автоматически загружаемыми", т.е. их загрузка будет осуществляться средой NetBeans только в случае необходимости. До этого момента ресурсы памяти на этапе выполнения расходоваться не будут. |
| |
| |
| [start=1] |
| 1. Щелкните правой кнопкой мыши узел "Modules" в проекте пакета модулей в окне "Projects", как показано ниже, и выберите пункт "Add New Library": |
| |
| |
| image::images/feedreader_60-add-lib0.png[] |
| |
| После этого на экране должно отображаться следующее: |
| |
| |
| image::images/feedreader_60-lib-wiz.png[] |
| |
| |
| [start=2] |
| 1. На экране "Select Library", показанном выше, найдите папку, в которую была загружена библиотека JDom, и затем выберите `` jdom.jar`` и `` LICENSE.txt`` . Нажмите кнопку "Next". |
| |
| [start=3] |
| 1. На экране "Name and Location" примите все значения по умолчанию. Экран должен выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-lib-wiz3.png[] |
| |
| NOTE: Модуль-обертка библиотеки будет сохранен в проекте пакета модулей. Он также может быть сохранен в другом месте, однако в целях управления версиями рекомендуется разместить его в проекте пакета модулей. Поэтому в раскрывающемся списке "Add to Module Suite" выбирается проект пакета модулей `` feedreader-suite`` . |
| |
| Нажмите кнопку "Next". |
| |
| |
| [start=4] |
| 1. На экране "Basic Module Configuration" примите все значения по умолчанию. Экран должен выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-lib-wiz2.png[] |
| |
| Нажмите кнопку "Finish". |
| |
| Новый модуль-обертка библиотеки открывается в среде IDE и будет отображен в окне "Projects". Окно "Projects" должно выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-lib-wiz4.png[] |
| |
| [start=5] |
| 1. Вернитесь к действию 1 этого раздела и создайте модуль-обертку для библиотеки Rome. Примите все значения по умолчанию. |
| |
| [start=6] |
| 1. Вернитесь к действию 1 этого раздела и создайте модуль-обертку для библиотеки Rome Fetcher. Примите все значения по умолчанию. |
| |
| В этом разделе был создан проект пакета модулей с тремя модулями-обертками библиотек, содержащий большое количество удобных классов Java, которые могут использоваться по мере изучения руководства. |
| |
| |
| === Создание проекта модуля |
| |
| В этом разделе создается проект для реализации функциональных возможностей, которые должны предоставляться приложением. В проекте будут использоваться классы, доступные благодаря применению модулей-оберток библиотек, созданных в предыдущем разделе. |
| |
| |
| [start=1] |
| 1. Щелкните правой кнопкой мыши узел "Modules" в проекте пакета модулей в окне "Projects", как показано ниже, и выберите "Add New": |
| |
| |
| image::images/feedreader_60-module-project.png[] |
| |
| После этого на экране должно отображаться следующее: |
| |
| |
| image::images/feedreader_60-module-wiz.png[] |
| |
| |
| [start=2] |
| 1. На экране "Name and Location", показанном выше, введите `` FeedReader`` в поле "Project Name". Примите все значения по умолчанию. Нажмите кнопку "Next". |
| |
| [start=3] |
| 1. На экране "Basic Module Configuration" замените значение `` yourorghere`` в поле "Code Name Base" на `` myorg`` , чтобы основа названия кода выглядела как `` org.myorg.feedreader.`` Введите ``FeedReader`` в поле "Module Display Name". Не изменяйте местоположение пакета локализации и файла layer.xml для их сохранения в пакете с именем `` org/myorg/feedreader.`` Экран должен выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-module-wiz2.png[] |
| |
| Нажмите кнопку "Finish". |
| |
| Средой IDE будет создан проект "FeedReader". Проект содержит все исходные файлы модуля и метаданные проекта, например, сценарий сборки Ant. Проект открывается в среде IDE. Логическую структуру проекта можно просмотреть в окне "Projects" (Ctrl-1), а структуру файлов – в окне "Files" (Ctrl-2). Теперь окно "Projects" должно выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-module.png[] |
| |
| Создана структура исходных файлов нового приложения. В следующем разделе мы приступим к добавлению кода. |
| |
| |
| == Создание окна приложения для чтения каналов |
| |
| В этом разделе при помощи мастера оконных элементов генерируются файлы, необходимые для создания пользовательского элемента, а также действия для его вызова. Мастер также регистрирует действие как пункт меню в файле настройки `` layer.xml `` и добавляет значения, необходимые для многократного использования оконного элемента. После завершения этого раздела демонстрируется процесс использования некоторых файлов, созданных мастером оконных элементов. |
| |
| |
| [start=1] |
| 1. Щелкните правой кнопкой мыши узел проекта `` FeedReader`` и выберите "New > Other". В области "Categories" выберите "Module Development". В области "File Types" выберите "Window Component", как показано ниже: |
| |
| |
| image::images/feedreader_60-windowcomp-wiz.png[] |
| |
| Нажмите кнопку "Next". |
| |
| |
| [start=2] |
| 1. На экране "Basic Settings" выберите `` explorer`` в раскрывающемся списке и установите флажок "Open on Application Start", как показано ниже: |
| |
| |
| image::images/feedreader_60-windowcomp-wiz2.png[] |
| |
| Нажмите кнопку "Next". |
| |
| |
| [start=3] |
| 1. На экране "Name and Location" введите "Feed" в поле "Class Name Prefix" и укажите местоположение сохраненного файла `` rss16.gif ( |
| image::images/feedreader_rss16.gif[]).`` Файл GIF будет показан в пункте меню, инициирующем действие. Экран должен выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-windowcomp-wiz3.png[] |
| |
| Нажмите кнопку "Finish". |
| |
| Окно "Projects" должно выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-windowcomp.png[] |
| |
| В среде IDE созданы следующие новые файлы: |
| |
| * `` FeedAction.java.`` Определяет действие, отображаемое в меню "Window" с текстом "Open Feed Window" и изображением `` rss16.gif`` ( |
| image::images/feedreader_rss16.gif[]). Оно используется для открытия окна "Feed Window". |
| * `` FeedTopComponent.java.`` Определяет окно "Feed Window". |
| * `` FeedTopComponentSettings.xml.`` Используется для определения всех интерфейсов функционально насыщенного клиентского приложения `` org.myorg.feedreader`` . Обеспечивает простой поиск экземпляров без необходимости создания каждого из них; позволяет избежать необходимости в загрузке классов или создании объектов и, тем самым, повышает производительность. Регистрируется в папке `` Windows2/Components`` файла `` layer.xml`` . |
| * `` FeedTopComponentWstcref.xml.`` Используется для определения ссылки на элемент; дает возможность присвоения элемента более чем одному режиму и регистрируется в папке ``Windows2/Modes`` файла `` layer.xml`` . |
| |
| Средой IDE были изменены следующие существующие файлы: |
| |
| * |
| `` project.xml.`` Добавлены две зависимости модулей, `` Utilities API `` (щелкните link:http://bits.netbeans.org/dev/javadoc/org-openide-util/overview-summary.html[здесь] для просмотра документации Javadoc) и `` Window System API `` (щелкните link:http://bits.netbeans.org/dev/javadoc/org-openide-windows/overview-summary.html[здесь] для просмотра документации Javadoc). |
| * `` Bundle.properties.`` |
| Добавлены три пары "ключ-значение": |
| * ``CTL_FeedAction.`` Позволяет локализовать текст пункта меню, определенного в ``FeedAction.java`` . |
| * ``CTL_FeedTopComponent.`` Позволяет локализовать текст ``FeedTopComponent.java`` . |
| * ``HINT_FeedTopComponent.`` Позволяет локализовать всплывающую подсказку ``FeedTopComponent.java`` . |
| |
| Итак, в файл ``layer.xml`` добавлены три регистрационных записи. |
| |
| Эти записи в файле `` layer.xml`` предназначены для следующего: |
| |
| * `` <Actions>`` |
| Регистрирует действие в качестве действия в папке "Window". |
| * `` <Menu>`` |
| Регистрирует действие в качестве пункта в меню "Window". |
| * `` <Windows2> `` Регистрирует файл ``FeedTopComponentSettings.xml`` , используемый для поиска оконного элемента. Регистрирует ссылочный файл элемента ``FeedTopComponentWstcref.xml`` в области "explorer". |
| |
| |
| == Выполнение приложения |
| |
| Приложение, для которого не была написана ни одна строка кода, уже может быть запущено. Попытка его использования приведет к развертыванию модулей на платформе NetBeans и к последующей проверки корректности отображения пустого окна "Feed Window". |
| |
| |
| [start=1] |
| 1. Сначала удалим все модули, определяющие среду IDE NetBeans, которые не потребуются в приложении для чтения каналов. Щелкните правой кнопкой мыши проект ``feedreader-suite`` , выберите "Properties", а затем щелкните пункт "Libraries" в диалоговом окне "Project Properties". |
| |
| Появится список "кластеров". Каждый кластер представляет собой ряд связанных модулей. Единственным необходимым кластером является кластер "platform", поэтому отмените выбор всех других кластеров и оставьте только один флажок напротив кластера "platform": |
| |
| |
| image::images/feedreader_60-runapp4.png[] |
| |
| Разверните кластер "platform" и просмотрите содержащиеся в нем модули: |
| |
| |
| image::images/feedreader_60-runapp5.png[] |
| |
| Модули платформы обеспечивают общую платформу приложений Swing. Так как был выбран кластер "platform", создавать "технический" код для инфраструктуры приложения, например, строки меню, системы управления окнами и функциональности для начальной загрузки, не потребуется. |
| |
| Нажмите кнопку "OK". |
| |
| |
| [start=2] |
| 1. В окне "Projects" щелкните правой кнопкой мыши проект `` feedreader-suite`` и выберите "Clean and Build All". |
| |
| [start=3] |
| 1. В окне "Projects" щелкните правой кнопкой мыши проект `` feedreader-suite`` и выберите "Run", как показано ниже: |
| |
| |
| image::images/feedreader_60-runapp.png[] |
| |
| Приложение будет запущено. На экране появится заставка. После этого будет открыто приложение и появится новое окно "Feed Window", представляющее собой окно обозревателя, показанное ниже: |
| |
| |
| image::images/feedreader_60-runapp2.png[] |
| |
| NOTE: В настоящий момент в состав приложения входят следующие модули: |
| |
| * Модули, поставляемые с платформой NetBeans и предназначенные для загрузки приложения, управления жизненным циклом и выполнения других операций, связанных с инфраструктурой. |
| * Три модуля-обертки библиотек, созданные в рамках этого руководства. |
| * Модуль функциональных возможностей чтения каналов, созданный в рамках этого руководства и предназначенный для вывода окна "Feed Window". |
| |
| В меню "Window" приложения должен появиться новый пункт (см. ниже), используемый для открытия окна "Feed Window" в случае, если оно закрыто: |
| |
| |
| image::images/feedreader_60-runapp3.png[] |
| |
| Итак, нами было создано готовое приложение без написания какого-либо кода. Оно не содержит множества возможностей, однако его инфраструктура существует и функционирует так, как ожидалось. В следующих разделах мы приступим к добавлению кода в приложение при помощи интерфейсов API среды NetBeans. |
| |
| |
| == Добавление кода к приложению |
| |
| После создания основы для приложения можно приступить к добавлению собственного кода. Перед этим для приложения необходимо определить зависимости. Зависимости – это модули, предоставляющие интерфейсы API NetBeans, которые будут расширены или реализованы. После этого при помощи мастера создания файла и редактора исходного кода будут созданы и закодированы классы, добавляемые в приложение для чтения каналов. |
| |
| |
| === Определение зависимостей для приложения |
| |
| Необходимо создать подклассы нескольких классов, принадлежащих интерфейсам API среды NetBeans. Классы относятся к модулям, которые должны быть объявлены как зависимости приложения для чтения каналов. Для этой цели используйте диалоговое окно "Project Properties", как показано ниже. |
| |
| |
| [start=1] |
| 1. В окне "Projects" щелкните правой кнопкой мыши проект `` FeedReader`` и выберите "Properties". В диалоговом окне "Project Properties" выберите "Libraries". Обратите внимание, что некоторые показанные ниже интерфейсы API уже были объявлены в качестве зависимостей (область "Module Dependencies"): |
| |
| |
| image::images/feedreader_60-add-lib1.png[] |
| |
| Показанные выше регистрационные записи библиотек были созданы ранее при работе с данным руководством с использованием мастера оконных элементов. |
| |
| |
| [start=2] |
| 1. Нажмите кнопку "Add Dependency". |
| |
| [start=3] |
| 1. Добавьте следующие интерфейсы API: |
| |
| [source,java] |
| ---- |
| |
| Actions API |
| Datasystems API |
| Dialogs API |
| Explorer and Property Sheet API |
| File System API |
| Nodes API |
| rome |
| rome-fetcher |
| ---- |
| |
| Экран должен выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-add-lib2.png[] |
| |
| Нажмите кнопку "OK" для закрытия диалогового окна "Project Properties". |
| |
| |
| [start=4] |
| 1. Разверните узел "Libraries" проекта ``FeedReader`` и обратите внимание на список модулей, доступных в этом проекте: |
| |
| |
| image::images/feedreader_60-add-lib5.png[] |
| |
| |
| === Установка зависимостей между модулями-обертками библиотек |
| |
| После определения используемых зависимостей модулей интерфейсов API среды NetBeans можно установить зависимости между модулями-обертками библиотек. Например, в файле JAR библиотеки Rome используются классы из файла JAR библиотеки JDom. Теперь, когда они обернуты в отдельных модулях-обертках библиотек, необходимо определить связь между файлами JAR в диалоговом окне "Project Properties" модуля-обертки библиотеки. |
| |
| |
| [start=1] |
| 1. Сначала установите зависимость библиотеки Rome от библиотеки JDom. Щелкните правой кнопкой мыши проект модуля-обертки библиотеки Rome в окне "Projects" и выберите "Properties". В диалоговом окне "Project Properties" выберите "Libraries" и затем "Add Dependency". Добавьте зависимости ``jdom`` . Экран должен выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-add-lib3.png[] |
| |
| Нажмите кнопку "OK" для закрытия диалогового окна "Project Properties". |
| |
| |
| [start=2] |
| 1. Теперь, после установки зависимости библиотеки Rome Fetcher от библиотек Rome и JDom одновременно, необходимо создать зависимость Rome Fetcher от Rome, показанную ниже: |
| |
| |
| image::images/feedreader_60-add-lib4.png[] |
| |
| Поскольку библиотека Rome уже зависит от JDom, определять зависимость библиотеки Rome Fetcher от JDom не требуется. |
| |
| |
| === Создание папки "RssFeeds" |
| |
| Для добавления папки в файл ``layer.xml`` будет использоваться интерфейс пользователя среды IDE. Папка будет содержать объекты канала RSS. Затем к объекту `` FeedTopComponent.java`` , созданному в мастере оконных элементов, будет добавлен код для просмотра содержимого этой папки. |
| |
| |
| [start=1] |
| 1. В окне "Projects" разверните узел проекта `` FeedReader`` , а затем разверните узлы "Important Files" и "XML Layer". На экране должны быть представлены следующие узлы: |
| |
| * `` <this layer>.`` Используется для вывода на экран папок, содержащихся в текущем модуле. Например, как видно на приведенном ниже рисунке, модуль "FeedReader" содержит папки с именами "Actions", "Menu" и "Windows2", ранее описанные в данном руководстве: |
| |
| |
| image::images/feedreader_60-feedfolder-1.png[] |
| |
| * `` <this layer in context>. `` Используется для вывода на экран всех папок, доступных во всем приложении. Этот узел будет рассматриваться далее в настоящем руководстве. |
| |
| |
| [start=2] |
| 1. Щелкните правой кнопкой мыши узел `` <this layer>`` и выберите "New > Folder", как показано ниже: |
| |
| |
| image::images/feedreader_60-feedfolder-2.png[] |
| |
| [start=3] |
| 1. Введите `` RssFeeds`` в диалоговом окне "New Folder". Нажмите кнопку "OK". Таким образом, была создана новая папка, показанная ниже: |
| |
| |
| image::images/feedreader_60-feedfolder-3.png[] |
| |
| [start=4] |
| 1. Дважды щелкните узел файла `` layer.xml`` для его открытия в редакторе исходного кода. Обратите внимание на добавление следующей записи: `` <folder name="RssFeeds"/>`` |
| |
| |
| === Создание объекта канала |
| |
| Затем создайте простой элемент POJO, инкапсулирующий URL-адрес и связанный с ним канал Rome. |
| |
| |
| [start=1] |
| 1. Щелкните правой кнопкой мыши узел проекта `` FeedReader`` и выберите "New > Java Class". Нажмите кнопку "Next". |
| |
| [start=2] |
| 1. Присвойте классу имя `` Feed`` и выберите `` org.myorg.feedreader`` в раскрывающемся списке "Package". Нажмите кнопку "Finish". |
| |
| [start=3] |
| 1. В редакторе исходного кода замените класс `` Feed`` , установленный по умолчанию, на следующий: |
| |
| [source,java] |
| ---- |
| |
| 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; |
| } |
| |
| } |
| ---- |
| |
| Значительная часть кода подчеркнута, поскольку многие пакеты не были объявлены. Это будет выполнено в дальнейшем. |
| |
| Для переформатирования файла и объявления его зависимостей выполните следующие действия: |
| |
| |
| [start=1] |
| 1. Нажмите Alt-Shift-F для форматирования кода. |
| |
| [start=2] |
| 1. Нажмите Ctrl-Shift-I и проверьте, что выбраны следующие операторы импорта: |
| |
| |
| image::images/feedreader_60-imports.png[] |
| |
| Нажмите кнопку "OK", после чего в класс будут добавлены следующие операторы импорта: |
| |
| |
| [source,java] |
| ---- |
| |
| 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; |
| ---- |
| |
| Красное подчеркивание должно исчезнуть. В противном случае не выполняйте следующие действия, указанные в этом руководстве, до разрешения проблемы. |
| |
| |
| === Добавление окна "Feed Window" |
| |
| |
| [start=1] |
| 1. Дважды щелкните элемент `` FeedTopComponent.java`` для его открытия в редакторе исходного кода. |
| |
| [start=2] |
| 1. Введите строку `` implements ExplorerManager.Provider`` в конце объявления класса. |
| |
| [start=3] |
| 1. Нажмите Alt-Enter, установив курсор на строке, и щелкните предложенное значение. Средой IDE будет добавлен оператор импорта для требуемого пакета `` org.openide.explorer.ExplorerManager`` . |
| |
| [start=4] |
| 1. Снова нажмите Alt-Enter и щелкните предложенное значение. При этом будет реализован абстрактный метод `` getExplorerManager()`` . |
| |
| [start=5] |
| 1. Введите `` return manager;`` в теле нового метода `` getExplorerManager() `` . Нажмите Alt-Enter, установив курсор на строку, после чего будет создано поле под названием `` manager`` . Замените определение по умолчанию на следующее: |
| |
| [source,java] |
| ---- |
| |
| private final ExplorerManager manager = new ExplorerManager(); |
| ---- |
| |
| |
| [start=6] |
| 1. Сразу после объявления поля на предыдущем этапе объявите этот класс: |
| |
| [source,java] |
| ---- |
| |
| private final BeanTreeView view = new BeanTreeView(); |
| ---- |
| |
| |
| [start=7] |
| 1. После этого добавьте следующий код в конце конструктора: |
| |
| [source,java] |
| ---- |
| |
| setLayout(new BorderLayout()); |
| add(view, BorderLayout.CENTER); |
| view.setRootVisible(true); |
| try { |
| manager.setRootContext(new RssNode.RootRssNode()); |
| } catch (DataObjectNotFoundException ex) { |
| ErrorManager.getDefault().notify(ex); |
| } |
| ActionMap map = getActionMap(); |
| map.put("delete", ExplorerUtils.actionDelete(manager, true)); |
| associateLookup(ExplorerUtils.createLookup(manager, map)); |
| ---- |
| |
| В настоящее время большая часть кода подчеркнута, поскольку соответствующие пакеты не были объявлены. Это будет выполнено в дальнейшем. |
| |
| Для переформатирования файла и объявления его зависимостей выполните следующие действия: |
| |
| |
| [start=1] |
| 1. Нажмите Alt-Shift-F для форматирования кода. |
| |
| [start=2] |
| 1. Нажмите Ctrl-Shift-I, выберите ``org.openide.ErrorManager`` , нажмите кнопку "OK", после чего под оператором пакета будет создано несколько операторов импорта. Теперь полный список операторов импорта должен выглядеть следующим образом: |
| |
| [source,java] |
| ---- |
| |
| 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; |
| ---- |
| |
| |
| [start=3] |
| 1. Следует отметить, что строка `` manager.setRootContext(new RssNode.RootRssNode());`` по-прежнему подчеркнута красным цветом, поскольку элемент `` RssNode.java `` до сих пор не создан. Это будет выполнено в следующем подразделе. Прочие красные линии должны исчезнуть. В противном случае не выполняйте следующие действия, указанные в этом руководстве, до разрешения проблемы. |
| |
| |
| === Создание класса "RssNode" |
| |
| Верхний узел приложения для чтения каналов обеспечивается классом "RssNode". Этот класс расширяет `` link:http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/FilterNode.html[FilterNode]`` , используемый в качестве прокси для узла "RssFeeds". На этом этапе будет определено отображаемое имя и объявлены два пункта меню "Add" и "Add Folder", показанные ниже: |
| |
| |
| image::images/feedreader_60-actions.png[] |
| |
| Для создания этого класса выполните следующие действия: |
| |
| |
| [start=1] |
| 1. Создайте элемент `` RssNode.java`` в пакете `` org.myorg.feedreader`` . |
| |
| [start=2] |
| 1. Замените класс по умолчанию на следующий: |
| |
| [source,java] |
| ---- |
| |
| public class RssNode extends FilterNode { |
| |
| public RssNode(Node folderNode) throws DataObjectNotFoundException { |
| super(folderNode, new RssFolderChildren(folderNode)); |
| } |
| |
| @Override |
| public Action[] getActions(boolean popup) { |
| |
| *//Объявление действий и переход к папке данных узла:* |
| DataFolder df = getLookup().lookup(DataFolder.class); |
| return new Action[]{ |
| new AddRssAction(df), |
| new AddFolderAction(df) |
| }; |
| |
| } |
| |
| public static class RootRssNode extends RssNode { |
| |
| *//Узел фильтра будет служить в качестве прокси для узла "RssFeeds", который здесь будет получен из пользовательского каталога NetBeans:* |
| public RootRssNode() throws DataObjectNotFoundException { |
| super(DataObject.find(Repository.getDefault().getDefaultFileSystem(). |
| getRoot().getFileObject("RssFeeds")).getNodeDelegate()); |
| } |
| |
| *//Определение отображаемого имени узла, относящегося к объединенному файлу, и ключа, который будет определен позже:* |
| @Override |
| public String getDisplayName() { |
| return NbBundle.getMessage(RssNode.class, "FN_title"); |
| } |
| |
| } |
| |
| } |
| ---- |
| |
| Некоторые строки кода, относящиеся к классу, по-прежнему подчеркиваются красным цветом, поскольку не были созданы действия и класс, определяющий нижестоящие узлы. |
| |
| |
| === Создание класса "RssFolderChildren" |
| |
| Теперь обратимся к дочерним узлам узла "RSS/Atom Feeds". Дочерние элементы являются папками или каналами. Все это реализуется посредством кода, приведенного ниже. |
| |
| Для создания этого класса выполните следующие действия: |
| |
| |
| [start=1] |
| 1. Создайте элемент `` RssFolderChildren.java`` в пакете `` org.myorg.feedreader`` . |
| |
| [start=2] |
| 1. Замените класс по умолчанию на следующий: |
| |
| [source,java] |
| ---- |
| |
| public class RssFolderChildren extends FilterNode.Children { |
| |
| RssFolderChildren(Node rssFolderNode) { |
| super(rssFolderNode); |
| } |
| |
| @Override |
| protected Node[] createNodes(Node key) { |
| Node n = key; |
| |
| *//При нахождении папки данных создается узел "RssNode", в противном случае осуществляется поиск канала и создание узла "OneFeedNode":* |
| 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("Bogus file in feeds folder: " + node.getLookup().lookup(FileObject.class)); |
| } |
| try { |
| return (Feed) ck.instanceCreate(); |
| } catch (ClassNotFoundException ex) { |
| Exceptions.printStackTrace(ex); |
| } catch (IOException ex) { |
| Exceptions.printStackTrace(ex); |
| } |
| return null; |
| } |
| |
| } |
| ---- |
| |
| Некоторые строки кода, относящегося к классу, подчеркнуты красным цветом, поскольку класс ``OneFeedNode`` до сих пор не создан. |
| |
| |
| === Создание класса "OneFeedNode" |
| |
| В этом разделе рассматривается контейнер узлов статьей, проиллюстрированный ниже на примере узла "NetBeans Highlights": |
| |
| |
| image::images/feedreader_60-actions2.png[] |
| |
| Можно отметить, что каждый из этих узлов имеет отображаемое имя, получаемое из канала, значок и пункт меню "Delete". |
| |
| Для создания этого класса выполните следующие действия: |
| |
| |
| [start=1] |
| 1. Создайте элемент `` OneFeedNode.java`` в пакете `` org.myorg.feedreader`` . |
| |
| [start=2] |
| 1. Замените класс по умолчанию на следующий: |
| |
| [source,java] |
| ---- |
| |
| public class OneFeedNode extends FilterNode { |
| |
| OneFeedNode(Node feedFileNode, SyndFeed feed) throws IOException, IntrospectionException { |
| super(feedFileNode, |
| new FeedChildren(feed), |
| new ProxyLookup( |
| new Lookup[]{Lookups.fixed( |
| new Object[]{feed}), |
| feedFileNode.getLookup() |
| })); |
| } |
| |
| @Override |
| public String getDisplayName() { |
| SyndFeed feed = getLookup().lookup(SyndFeed.class); |
| return feed.getTitle(); |
| } |
| |
| @Override |
| public Image getIcon(int type) { |
| return Utilities.loadImage("org/myorg/feedreader/rss16.gif"); |
| } |
| |
| @Override |
| public Image getOpenedIcon(int type) { |
| return getIcon(0); |
| } |
| |
| @Override |
| public Action[] getActions(boolean context) { |
| return new Action[]{SystemAction.get(DeleteAction.class)}; |
| } |
| |
| } |
| ---- |
| |
| Некоторые строки кода, относящегося к классу, подчеркнуты красным цветом, поскольку ``FeedChildren`` до сих пор не создан. |
| |
| |
| === Создание класса "FeedChildren" |
| |
| В этом разделе будет добавлена часть кода, необходимого для представления узлов для каждой из статей, содержащихся в канале. |
| |
| Для создания этого класса выполните следующие действия: |
| |
| |
| [start=1] |
| 1. Создайте элемент `` FeedChildren.java`` в пакете `` org.myorg.feedreader`` . |
| |
| [start=2] |
| 1. Замените класс по умолчанию на следующий: |
| |
| [source,java] |
| ---- |
| |
| public class FeedChildren extends Children.Keys { |
| |
| private final SyndFeed feed; |
| |
| public FeedChildren(SyndFeed feed) { |
| this.feed = feed; |
| } |
| |
| @SuppressWarnings(value = "unchecked") |
| @Override |
| protected void addNotify() { |
| setKeys(feed.getEntries()); |
| } |
| |
| public Node[] createNodes(Object key) { |
| |
| *//Возвращение новых узлов на уровне статьи:* |
| try { |
| return new Node[]{ |
| new EntryBeanNode((SyndEntry) key) |
| }; |
| |
| } catch (final IntrospectionException ex) { |
| Exceptions.printStackTrace(ex); |
| *//Это не должно происходить, причины для сбоя отсутствуют:* |
| return new Node[]{new AbstractNode(Children.LEAF) { |
| @Override |
| public String getHtmlDisplayName() { |
| return "" + ex.getMessage() + ""; |
| } |
| }}; |
| } |
| } |
| } |
| ---- |
| |
| Некоторые строки кода, относящегося к классу, подчеркнуты красным цветом, поскольку ``EntryBeanNode`` до сих пор не создан. |
| |
| |
| === Создание класса "EntryBeanNode" |
| |
| Теперь рассмотрим узлы самых нижних уровней, отражающие статьи, содержащиеся в канале. |
| |
| Для создания этого класса выполните следующие действия: |
| |
| |
| [start=1] |
| 1. Создайте элемент `` EntryBeanNode.java`` в пакете `` org.myorg.feedreader`` . |
| |
| [start=2] |
| 1. Замените класс по умолчанию на следующий: |
| |
| [source,java] |
| ---- |
| |
| public class EntryBeanNode extends FilterNode { |
| |
| private SyndEntry entry; |
| |
| @SuppressWarnings(value = "unchecked") |
| public EntryBeanNode(SyndEntry entry) throws IntrospectionException { |
| super(new BeanNode(entry), Children.LEAF, |
| Lookups.fixed(new Object[]{ |
| entry, |
| new EntryOpenCookie(entry) |
| })); |
| this.entry = entry; |
| } |
| |
| */** Использование "HtmlDisplayName" обеспечивает правильность обработки, выхода, получения объектов и т.д. для любого кода HTML в заголовках сообщений RSS. */* |
| @Override |
| public String getHtmlDisplayName() { |
| return entry.getTitle(); |
| } |
| |
| */** Создание всплывающей подсказки к описанию сообщения */* |
| @Override |
| public String getShortDescription() { |
| return entry.getDescription().getValue(); |
| } |
| |
| */** Ввод действия "Open" для сообщения канала */* |
| @Override |
| public Action[] getActions(boolean popup) { |
| return new Action[]{SystemAction.get(OpenAction.class)}; |
| } |
| |
| @Override |
| public Action getPreferredAction() { |
| return (SystemAction) getActions(false) [0]; |
| } |
| |
| */** Указание на операцию, выполняемую после вызова пользователем действия "Open" */* |
| 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); |
| } |
| } |
| |
| } |
| |
| } |
| ---- |
| |
| |
| === Создание пункта меню "Add Folder" |
| |
| В этом разделе создается пункт меню, предназначенный для создания объявленных ранее папок. |
| |
| Для создания этого класса выполните следующие действия: |
| |
| |
| [start=1] |
| 1. Создайте элемент `` AddFolderAction.java`` в пакете `` org.myorg.feedreader`` . |
| |
| [start=2] |
| 1. Замените класс по умолчанию на следующий: |
| |
| [source,java] |
| ---- |
| |
| public class AddFolderAction extends AbstractAction { |
| |
| private DataFolder folder; |
| |
| public AddFolderAction(DataFolder df) { |
| folder = df; |
| putValue(Action.NAME, NbBundle.getMessage(RssNode.class, "FN_addfolderbutton")); |
| } |
| |
| public void actionPerformed(ActionEvent ae) { |
| NotifyDescriptor.InputLine nd = |
| new NotifyDescriptor.InputLine( |
| NbBundle.getMessage(RssNode.class, "FN_askfolder_msg"), |
| NbBundle.getMessage(RssNode.class, "FN_askfolder_title"), |
| NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.PLAIN_MESSAGE); |
| Object result = DialogDisplayer.getDefault().notify(nd); |
| if (result.equals(NotifyDescriptor.OK_OPTION)) { |
| final String folderString = nd.getInputText(); |
| try { |
| DataFolder.create(folder, folderString); |
| } catch (IOException ex) { |
| Exceptions.printStackTrace(ex); |
| } |
| } |
| } |
| } |
| ---- |
| |
| |
| === Создание пункта меню "Add RSS" |
| |
| В этом разделе рассматривается создание пункта меню для добавления новых каналов. |
| |
| Для создания этого класса выполните следующие действия: |
| |
| |
| [start=1] |
| 1. Создайте элемент `` AddRssAction.java`` в пакете `` org.myorg.feedreader`` . |
| |
| [start=2] |
| 1. Замените класс по умолчанию на следующий: |
| |
| [source,java] |
| ---- |
| |
| public class AddRssAction extends AbstractAction { |
| |
| private DataFolder folder; |
| |
| public AddRssAction(DataFolder df) { |
| folder = df; |
| putValue(Action.NAME, NbBundle.getMessage(RssNode.class, "FN_addbutton")); |
| } |
| |
| public void actionPerformed(ActionEvent ae) { |
| |
| NotifyDescriptor.InputLine nd = new NotifyDescriptor.InputLine( |
| NbBundle.getMessage(RssNode.class, "FN_askurl_msg"), |
| NbBundle.getMessage(RssNode.class, "FN_askurl_title"), |
| NotifyDescriptor.OK_CANCEL_OPTION, |
| NotifyDescriptor.PLAIN_MESSAGE); |
| |
| Object result = DialogDisplayer.getDefault().notify(nd); |
| |
| if (result.equals(NotifyDescriptor.OK_OPTION)) { |
| String urlString = nd.getInputText(); |
| URL url; |
| try { |
| url = new URL(urlString); |
| } catch (MalformedURLException e) { |
| String message = NbBundle.getMessage(RssNode.class, "FN_askurl_err", urlString); |
| Exceptions.attachLocalizedMessage(e, message); |
| Exceptions.printStackTrace(e); |
| return; |
| } |
| try { |
| checkConnection(url); |
| } catch (IOException e) { |
| String message = NbBundle.getMessage(RssNode.class, "FN_cannotConnect_err", urlString); |
| Exceptions.attachLocalizedMessage(e, message); |
| Exceptions.printStackTrace(e); |
| return; |
| } |
| Feed f = new Feed(url); |
| FileObject fld = folder.getPrimaryFile(); |
| String baseName = "RssFeed"; |
| int ix = 1; |
| while (fld.getFileObject(baseName + ix, "ser") != null) { |
| ix++; |
| } |
| try { |
| FileObject writeTo = fld.createData(baseName + ix, "ser"); |
| FileLock lock = writeTo.lock(); |
| try { |
| ObjectOutputStream str = new ObjectOutputStream(writeTo.getOutputStream(lock)); |
| try { |
| str.writeObject(f); |
| } finally { |
| str.close(); |
| } |
| } finally { |
| lock.releaseLock(); |
| } |
| } catch (IOException ioe) { |
| Exceptions.printStackTrace(ioe); |
| } |
| } |
| |
| private static void checkConnection(final URL url) throws IOException { |
| InputStream is = url.openStream(); |
| is.close(); |
| } |
| |
| } |
| ---- |
| |
| |
| === Локализация класса "RssNode" |
| |
| |
| [start=1] |
| 1. Откройте файл `` Bundle.properties`` модуля `` FeedReader`` . |
| |
| [start=2] |
| 1. Добавьте следующие пары "ключ-значение": |
| |
| [source,java] |
| ---- |
| |
| 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 |
| ---- |
| |
| Ниже приведено пояснение новых пар "ключ-значение", локализующих строки, определенные в элементе `` RssNode.java`` : |
| |
| * *FN_title.* Локализует текст верхнего узла в окне "Feed Window". |
| |
| Локализация интерфейса пользователя для добавления канала: |
| |
| * *FN_addbutton.* Локализует текст пункта меню "Add" в контекстном меню верхнего узла. |
| * *FN_askurl_title.* Локализует заголовок диалогового окна "New Feed". |
| * *FN_askurl_msg.* Локализует сообщение, появляющееся в диалоговом окне "New Feed". |
| * *FN_askurl_err.* Локализует строку ошибки, отображаемую в случае недействительности URL-адреса. |
| |
| Локализация интерфейса пользователя для добавления папки: |
| |
| * *FN_addfolderbutton.* Локализует текст пункта меню "Add Folder" в контекстном меню верхнего узла. |
| * *FN_askfolder_msg.* Локализует сообщение, появляющееся в диалоговом окне "Add Folder". |
| * *FN_askfolder_title. * Локализует заголовок диалогового окна "Add Folder". |
| |
| |
| == Выбор стиля для приложения |
| |
| В конце цикла разработки, на этапе заключительной подготовки приложения, необходимо рассмотреть следующие вопросы: |
| |
| * Каким должно быть имя исполняемого файла приложения? |
| * Что должен увидеть пользователь после запуска приложения? Индикатор хода выполнения? Экран заставки? И то, и другое? |
| * Что должно отображаться в строке заголовка при запуске приложения? |
| * Являются ли все меню и кнопки панелей инструментов, предоставляемые платформой NetBeans по умолчанию, действительно необходимыми? |
| |
| Эти вопросы относятся к сфере выбора стиля, персонализации приложения, построенного на базе платформы NetBeans. В среде IDE в диалоговом окне "Project Properties" проектов пакетов модулей предусмотрена специальная панель, упрощающая выбор стиля. |
| |
| |
| [start=1] |
| 1. Щелкните правой кнопкой мыши узел проекта `` feedreader-suite`` (а не узел проекта `` FeedReader`` ) и выберите "Properties". В диалоговом окне "Project Properties" выберите "Build". |
| |
| [start=2] |
| 1. На экране "Build" введите значение `` feedreader`` в поле "Branding Name". Введите `` Feed Reader Application`` в поле "Application Title". Значение поля "Branding Name" определяет имя исполняемой программы, а значение поля "Application Title" – строку заголовка приложения. |
| |
| [start=3] |
| 1. Нажмите кнопку "Browse" и найдите значок `` rss16.gif`` ( |
| image::images/feedreader_rss16.gif[]). Значок будет отображаться в диалоговом окне "Help > About". |
| |
| Экран должен выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-brand1.png[] |
| |
| [start=4] |
| 1. На экране "Splash Screen" нажмите кнопку "Browse" и найдите файл `` splash.gif`` . Кроме того, можно изменить цвет и размер текста индикатора хода выполнения. Если индикатор хода выполнения не требуется, снимите флажок "Enabled". |
| |
| Экран должен выглядеть следующим образом: |
| |
| |
| image::images/feedreader_60-brand2.png[] |
| |
| [start=5] |
| 1. Нажмите кнопку "OK".В проекте `` FeedReader Application`` будет создана папка `` branding`` . Она будет отображена в окне "Files" (Ctrl-2). |
| |
| [start=6] |
| 1. В окне "Files" разверните узел проекта `` FeedReader Application`` . После этого продолжайте разворачивать узлы до тех пор, пока не найдете следующий узел: `` branding/modules/org-netbeans-core-window.jar/org/netbeans/core/windows`` |
| |
| [start=7] |
| 1. Щелкните правой кнопкой мыши этот узел, выберите "New > Other", а затем пункт "Folder" в категории "Other". Нажмите кнопку "Next" и присвойте папке имя `` resources`` . Нажмите кнопку "Finish". |
| |
| [start=8] |
| 1. Щелкните правой кнопкой мыши новый узел `` resources`` , выберите "New > Other", а затем "XML Document" в категории XML. Нажмите кнопку "Next". Присвойте файлу имя `` layer`` . Нажмите кнопку "Next", а затем кнопку "Finish". Замените содержимое нового файла `` layer.xml`` на следующий текст: |
| |
| [source,xml] |
| ---- |
| |
| <?xml version="1.0" encoding="UTF-8"? > |
| <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "https://netbeans.org/dtds/filesystem-1_1.dtd"> |
| <!-- |
| Это уровень "стиля". Он объединяется с файлом layer.xml, для настройки которого используется. |
| В данном случае осуществляется скрытие нежелательных пунктов меню и панелей инструментов. |
| --> |
| <filesystem> |
| |
| <!-- Скрытие неиспользуемых панелей инструментов --> |
| <folder name="Toolbars"> |
| <folder name="File_hidden"/> |
| <folder name="Edit_hidden"/> |
| </folder> |
| |
| <folder name="Menu"> |
| <folder name="File"> |
| <file name="org-openide-actions-SaveAction.instance_hidden"/> |
| <file name="org-openide-actions-SaveAllAction.instance_hidden"/> |
| <file name="org-netbeans-core-actions-RefreshAllFilesystemsAction.instance_hidden"/> |
| <file name="org-openide-actions-PageSetupAction.instance_hidden"/> |
| <file name="org-openide-actions-PrintAction.instance_hidden"/> |
| </folder> |
| <folder name="Edit_hidden"/> |
| <folder name="Tools_hidden"/> |
| </folder> |
| |
| </filesystem> |
| ---- |
| |
| |
| == Подготовка дистрибутива приложения |
| |
| Для создания дистрибутива приложения в среде IDE используется сценарий сборки Ant. Сценарий сборки создается при создании проекта. |
| |
| |
| [start=1] |
| 1. В окне "Projects" щелкните правой кнопкой мыши узел проекта `` FeedReader Application`` и выберите "Build ZIP Distribution". В окне "Output" отображается местоположение созданного ZIP-файла дистрибутива. |
| |
| [start=2] |
| 1. В файловой системе найдите дистрибутив `` feedreader.zip`` в папке `` dist`` каталога проекта. Разархивируйте его. Запустите приложение, находящееся в папке `` bin`` . При запуске на экране отобразится заставка. После запуска приложения вызовите диалоговое окно "Help > About" и обратите внимание на значок и экран заставки, которые были настроены в разделе <<branding,Выбор стиля для приложения>>. |
| |
| После запуска и в ходе работы в приложении для чтения каналов отображается окно "RSS/Atom Feeds", содержащее узел под названием "RSS/Atom Feeds". |
| |
| Поздравляем! Изучение руководства по созданию приложения для чтения каналов завершено. |
| |
| |
| link:http://netbeans.apache.org/community/mailing-lists.html[Мы ждем ваших отзывов] |
| |
| |