blob: fd01bb10829ec9712d06ca5ad3a7d2fd0d239da5 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--Attention: No screenshots have been added yet. JB -->
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="../../../netbeans.css">
<title>
Руководство по разработке приложений для рисования на платформе NetBeans 6.0
</title>
<link rel="shortcut icon" href="https://netbeans.org/favicon.ico" type="image/x-icon" >
<meta name="keywords" content="NetBeans, IDE, Platform, free, open source, developer" >
<h1>Руководство по разработке приложений для рисования на платформе NetBeans</h1>
<p>В этом руководстве представлены базовые аспекты разработки функционально насыщенных клиентских приложений на платформе NetBeans. Разработка приложений на платформе NetBeans подразумевает использование при разработке возможностей ядра среды IDE NetBeans. Все модули среды IDE, которые не требуются для разрабатываемого приложения, будут исключены, тогда как необходимые модули будут использоваться. Использование уже готовых компонентов ядра среды IDE экономит значительное количество времени и сил.
</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="#intro">Введение в разработку приложения для рисования</a></li>
<li><a href="#setup">Создание приложения для рисования</a></li>
<ul>
<li><a href="#creatingModuleSuite">Создание пакета модулей</a></li>
<li><a href="#creatingLibWrapModule">Создание проекта модуля-обертки библиотеки</a></li>
<li><a href="#creatingModProj">Создание проекта модуля</a></li>
<li><a href="#specifyingModProjDep">Определение зависимостей проекта модуля</a></li>
</ul>
<li><a href="#impMod">Создание и внедрение элемента &quot;Paint Canvas&quot;</a></li>
<ul>
<li><a href="#creatingCanv">Создание элемента &quot;Canvas&quot;</a></li>
<li><a href="#prepTopComp">Подготовка класса &quot;TopComponent&quot;</a></li>
<li><a href="#initTopComp">Инициализация класса &quot;TopComponent&quot;</a></li>
<li><a href="#fillSkelMeth">Заполнение кодом скелетных методов</a></li>
<li><a href="#savingImage">Функция сохранения изображения на диске</a></li>
</ul>
<li><a href="#defNew">Создание пункта меню для создания нового холста &quot;New Canvas&quot;</a></li>
<li><a href="#defSave">Создание пункта меню для сохранения холста &quot;Save Canvas&quot;</a></li>
<li><a href="#wrappingUp">Заключительная подготовка</a></li>
<li><a href="#creatingDist">Создание дистрибутива</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>
</tbody>
</table>
<p><a name="intro"></a></p><h2>Введение в разработку приложения для рисования</h2>
<p>Целью этого руководства является быстрая подготовка читателя к практической работе. Необходимо будет создать и установить простое приложение на платформе NetBeans. Это приложение позволит пользователю рисовать на экране и сохранять результаты:<br>
</p><p><a name="sampleImage"></a><img border="1" src="../../images/tutorials/paintapp/result-without-menus-60.png" alt="Вид законченного приложения">
</p><p>Такая начальная версия далека от полнофункционального приложения для рисования, но, тем не менее, она иллюстрирует самый простой вариант создания приложения на базе платформы NetBeans.
</p><p><b class="notes">Примечание: Если необходимо получить дополнительные сведения о модулях NetBeans, а не о функционально насыщенных клиентских приложениях, рекомендуется обратиться к руководству </b> <a href="nbm-google_ru.html">Быстрое начало работы с подключаемыми модулями в среде NetBeans</a>.
</p><p>В настоящем руководстве создается приложение на основе шаблона, поставляемого со средой IDE. Для просмотра готового приложения или разрешения проблем, возникающих при работе с этим руководством, в окне мастера создания проекта можно открыть шаблон по пути, указанному ниже:</p>
<p align="left"><img border="1" src="../../images/tutorials/paintapp/sample-in-new-project-60.png" alt="Экран &quot;Name and Location&quot;">
</p><p><a name="setup"></a></p><h2>Создание приложения для рисования</h2>
<p>В этом разделе необходимо будет создать структуру будущего приложения. Для начала потребуется создать проект пакета модулей, представляющий собой приложение. Приложение зависит от библиотеки, поэтому необходимо будет создать проект для модуля-обертки библиотеки, содержащего соответствующий файл JAR. В завершение будет создан проект модуля, содержащий код.
</p><div class="indent">
<p><a name="creatingModuleSuite"></a></p><h3 class="tutorial">Создание пакета модулей</h3>
<p>Пакет модулей является эквивалентом приложения и представляет собой ряд модулей, используемых совместно в целях достижения определенных результатов. Кроме того, он позволяет назначать собственный экран заставки (стиль), имя приложения, а также тип и количество необходимых модулей NetBeans. Можно также воспользоваться такими возможностями, как создание дистрибутива в формате ZIP и построение приложения на базе Java WebStart (JNLP), являющимися важными средствами распространения приложения среди других пользователей.
</p><ol>
<li>Выберите &quot;File &gt; New Project&quot;. В области &quot;Categories&quot; выберите &quot;NetBeans Modules&quot;. В области &quot;Projects&quot; выберите &quot;Module Suite Project&quot; и нажмите кнопку &quot;Next&quot;.</li>
<li>На экране &quot;Name and Location&quot; введите <tt>PaintApp</tt> в поле &quot;Project Name&quot;. В поле &quot;Project Location&quot; укажите любой каталог на компьютере. Не снимайте флажок &quot;Set as Main Project&quot;:<br><br>
<p align="left"><img border="1" src="../../images/tutorials/paintapp/newmodulesuite-60.png" alt="Экран &quot;Name and Location&quot;">
</p><p>Нажмите кнопку &quot;Finish&quot;.
</p></li>
<p>В среде IDE откроется новый проект пакета модулей. Он содержит один узел в окне &quot;Project&quot;. Этот узел &quot;Modules&quot; предназначен для добавления проектов модуля и проектов для модуля-обертки библиотеки к проекту пакета модулей вручную. При помощи мастера создания проектов модулей или мастера создания модулей-оберток библиотек созданный модуль может быть автоматически добавлен к проекту пакета модулей.
</p><p></p><h3 class="tutorial"><a name="creatingLibWrapModule"></a>Создание проекта модуля-обертки библиотеки</h3>
<p>Модуль-обертка библиотеки &ndash; это модуль, файл JAR которого содержит не код, а только указатель на библиотеку. Благодаря этому библиотека становится модулем NetBeans; поэтому к ней применяются все защитные функции системы загрузчика классов NetBeans без изменения первоначального файла JAR. В дальнейшем создаваемое приложение зависит от библиотеки так же, как если бы библиотека была обычным модулем NetBeans. При появлении новых версий библиотеки в дистрибутиве изменяется только единственный файл модуля NetBeans (NBM) для библиотеки оберток.
</p><p><b class="notes">Примечание:</b> К преимуществам построения приложений на платформе NetBeans относится интерфейс пользователя на базе стандартного инструментария для разработки интерфейса пользователя для Java &ndash; Swing. Так как Swing используется в течение долгого времени, существует множество компонентов, которые можно использовать в создаваемом приложении. В этом руководстве применяется существующий компонент JavaBean для выбора цветов (исходный код приведен в CVS NetBeans, в области <tt>contrib/coloreditor</tt>). Имя файла JAR &ndash; <tt>ColorChooser.jar</tt>. Библиотеку можно загрузить <a href="https://colorchooser.dev.java.net/">здесь</a>. Сохраните ее в любом месте файловой системы. Для создания модуля-обертки библиотеки для файла <tt>ColorChooser.jar</tt> выполните следующие действия:
</p><ol>
<li>Выберите &quot;File &gt; New Project&quot;. В области &quot;Categories&quot; выберите &quot;NetBeans Modules&quot;. В области &quot;Projects&quot; выберите &quot;Library Wrapper Module Project&quot; и нажмите кнопку &quot;Next&quot;.</li>
<li>На экране &quot;Name and Location&quot; в текстовом поле &quot;Library&quot; либо укажите путь к <tt>ColorChooser.jar</tt>, либо перейдите к этому файлу путем поиска.
</li><li>Текстовое поле &quot;License&quot; оставьте пустым. Если предполагается создание дистрибутива готового продукта, необходимо включить лицензионный файл внешней библиотеки.
</li><li>Нажмите кнопку &quot;Next&quot;, после чего на экране должно появиться следующее:</p>
<p align="left"><img border="1" src="../../images/tutorials/paintapp/newmodulesuite-library-60.png" alt="Экран &quot;Name and Location&quot;">
</p><p>Снова нажмите кнопку &quot;Next&quot;, а затем кнопку &quot;Finish&quot;.</p></li>
<h3 class="tutorial"><a name="creatingModProj"></a>Создание проекта модуля</h3>
<p>Теперь необходимо создать модуль для будущего фактического кода.
</p><ol>
<li>Выберите &quot;File &gt; New Project&quot;. В области &quot;Categories&quot; выберите &quot;NetBeans Modules&quot;. В области &quot;Projects&quot; выберите &quot;Module Project&quot; и нажмите кнопку &quot;Next&quot;.</li>
<li>На экране &quot;Name and Location&quot; введите <tt>Paint</tt> в поле &quot;Project Name&quot;. В поле &quot;Project Location&quot; укажите любой каталог на компьютере. Убедитесь, что выбран переключатель &quot;Add to Module Suite&quot;, а в раскрывающемся списке &quot;Module Suite&quot; выбран пакет модулей <tt>PaintApp</tt>. Установите флажок &quot;Set as Main Project&quot;. Нажмите кнопку &quot;Next&quot;.
</li><li>На экране &quot;Basic Module Configuration&quot; замените <tt>yourorghere</tt> в поле &quot;Code Name Base&quot; на <tt>netbeans</tt>, чтобы получилось имя <tt>org.netbeans.paint</tt>. В поле &quot;Module Display Name&quot; оставьте имя <tt>Paint</tt>. Не изменяйте местоположение пакета локализации и файла layer.xml для их сохранения в пакете с именем <tt>org.netbeans.paint</tt>. Эти файлы предназначены для следующего:
<ul>
<li><b>Пакет локализации.</b> Указывает строки на конкретном языке в целях интернационализации.</li>
<li><b>Файл &quot;layer.xml&quot;.</b> Регистрирует элементы, такие как меню и кнопки панели инструментов, в системе NetBeans.
</li>
</ul>
<p>Нажмите кнопку &quot;Finish&quot;.</p></li>
<p> Средой IDE будет создан проект <tt>Paint</tt>. Проект содержит все исходные файлы и метаданные проекта, например, сценарий сборки Ant. Проект открывается в среде IDE. Логическую структуру проекта можно просмотреть в окне &quot;Projects&quot; (Ctrl-1), а структуру файлов &ndash; в окне &quot;Files&quot; (Ctrl-2). Например, окно &quot;Projects&quot; теперь должно выглядеть следующим образом:</p>
<p align="left"><img src="../../images/tutorials/paintapp/initial-proj-window60.png" border="1" alt="Логическая структура окна &quot;Projects&quot;">
</p><p>Кроме пакета локализации и файла layer.xml, проект также содержит следующие важные файлы:
</p><ul>
<li><b>Манифест модуля.</b> Объявляет проект модулем. Кроме того, он определяет некоторые характерные для модуля параметры настройки, например, местоположение файла layer.xml, местоположение пакета локализации и версию модуля.
</li><li><b>Сценарий сборки.</b> Предусматривает пространство для создания собственных параметров Ant и переопределения параметров, указанных в <tt>nbproject/build-impl.xml</tt>.
</li><li><b>Метаданные проекта.</b> Содержит такую информацию, как тип проекта, содержимое, платформа, путь к классам, зависимости и связи между командами проекта и параметрами в сценариях Ant.
</li></ul>
<p>В этом руководстве изменять эти файлы не придется.
</li>
</p><p></p><h3 class="tutorial"><a name="specifyingModProjDep"></a>Определение зависимостей проекта модуля</h3>
<p>Необходимо будет создать подклассы для нескольких классов, принадлежащих <a href="https://netbeans.org/download/dev/javadoc/"> интерфейсам API NetBeans</a>. Кроме того, проект должен зависеть от файла <tt>ColorChooser.jar</tt>. Все интерфейсы API NetBeans реализованы модулями, поэтому выполнение обеих задач подразумевает лишь добавление в список модулей некоторых необходимых для выполнения модулей.
</p><ol>
<li>В окне &quot;Projects&quot; щелкните правой кнопкой мыши узел проекта <tt>Paint</tt> и выберите &quot;Properties&quot;. Откроется диалоговое окно &quot;Project Properties&quot;. В области &quot;Categories&quot; выберите &quot;Libraries&quot;.</li>
<li>Для каждого указанного в приведенной ниже таблице интерфейса API выберите &quot;Add Dependency...&quot;, а затем в текстовом поле &quot;Filter&quot; начинайте вводить имя класса, для которого требуется подкласс.<br><br>
<p><table width="76%" border="1">
<tbody>
<tr>
<td>
<div align="left"><b>Класс</b></div>
</td>
<td>
<div align="left"><b>Интерфейс API</b></div>
</td>
<td>
<div align="left"><b>Цель</b></div>
</td>
</tr>
<tr>
<td><tt>ColorChooser</tt></td>
<td><tt>ColorChooser</tt></td>
<td>Модуль-обертка библиотеки для созданного элемента выбора цветов</td>
</tr>
<tr>
<td><tt>DataObject</tt></td>
<td><tt>Datasystems API</tt></td>
<td>Модуль NetBeans, содержащий класс &quot;DataObject&quot;</td>
</tr>
<tr>
<td><tt>DialogDisplayer</tt></td>
<td><tt>Dialogs API</tt></td>
<td>Позволяет создавать уведомления пользователя, описания диалогового окна и разрешает выводить их на экран.</td>
</tr>
<tr>
<td><tt>AbstractFile</tt></td>
<td><tt>File System API</tt></td>
<td>Позволяет общему интерфейсу API обращаться к файлам единообразным способом.</td>
</tr>
<tr>
<td><tt>AbstractNode</tt></td>
<td><tt>Nodes API</tt></td>
<td>Основное средство визуализации объектов в NetBeans.</td>
</tr>
<tr>
<td><tt>StatusDisplayer</tt></td>
<td><tt>UI Utilities API</tt></td>
<td>Класс &quot;StatusDisplayer&quot; используется для создания строки состояния в главном окне.</td>
</tr>
<tr>
<td><tt>WeakListeners</tt></td>
<td><tt>Utilities API</tt></td>
<td>Этот класс содержит класс &quot;WeakListeners&quot;.</td>
</tr>
<tr>
<td><tt>TopComponent</tt></td>
<td><tt>Window System API</tt></td>
<td>Этот класс содержит класс &quot;TopComponent JPanel&quot;.</td>
</tr>
</tbody>
</table>
</p><p>В вышеприведенной таблице в первом столбце перечислены все классы, которым в этом руководстве потребуются подклассы. В каждом из этих случаев начинайте вводить имя класса в поле &quot;Filter&quot; и просматривайте сужающийся список в поле &quot;Module&quot;. Второй столбец таблицы следует использовать для выбора подходящего интерфейса API (или, в случае <tt>ColorChooser</tt>, библиотеки) из сокращенного списка &quot;Module&quot;; для подтверждения выбора нажмите кнопку &quot;OK&quot;:
</p><p align="left"><img border="1" src="../../images/tutorials/paintapp/libfilter-60.png" alt="Окно при создании проекта">
</p></li><li>Нажмите кнопку &quot;OK&quot; для закрытия диалогового окна &quot;Project Properties&quot;.
</li><li>Если в окне &quot;Projects&quot; не развернут узел проекта модуля &quot;Paint&quot;, разверните его. Затем разверните узел &quot;Important Files&quot; и дважды щелкните узел &quot;Project Metadata&quot;. Обратите внимание, что выбранные интерфейсы API были объявлены как зависимости модулей.
</li></ol>
</ol></ol></ol></div><br>
<h2><a name="impMod"></a>Создание и внедрение элемента &quot;Paint Canvas&quot;</h2>
<div class="indent">
<h3 class="tutorial"><a name="creatingCanv"></a>Создание элемента &quot;Canvas&quot;</h3>
<p>Следующим действием будет создание фактического элемента, на котором пользователь сможет рисовать. В этом случае необходимо использовать только элемент Swing, поэтому будут рассмотрены не подробности его реализации, а лишь окончательная версия. Для этой панели в исходном коде используется элемент выбора цветов, для которого был создан модуль-обертка библиотеки. При запуске готового приложения он отобразится на панели инструментов редактирования изображений.</p>
<ol type="1">
<li>В окне &quot;Projects&quot; разверните узел <tt>Paint</tt>, затем узел &quot;Source Packages&quot;, после этого щелкните правой кнопкой мыши узел <tt>org.netbeans.paint</tt>. Выберите &quot;Choose New &gt; Java Class&quot;.</li>
<li>В поле &quot;Class Name&quot; введите имя класса <tt>PaintCanvas</tt>. Убедитесь, что файл <tt>org.netbeans.paint</tt> определен как &quot;Package&quot;. Нажмите кнопку &quot;Finish&quot;. В редакторе исходного кода откроется файл <tt>PaintCanvas.java</tt>.
</li><li>Замените стандартное содержимое файла содержимым, которое можно найти <a target="source" href="https://platform.netbeans.org/guide/tutorials/paintTutorial/PaintCanvas.java">здесь</a>. Если пакет имеет имя, отличное от <tt>org.netbeans.paint</tt>, исправьте имя пакета в редакторе исходного кода.</li>
</ol>
<p></p><h3 class="tutorial"><a name="prepTopComp"></a>Подготовка класса &quot;TopComponent&quot;</h3>
<p></p><p>Теперь необходимо будет написать первый класс для <a href="https://netbeans.org/download/dev/javadoc/"> интерфейсов API среды NetBeans</a>. Это класс <tt><a href="http://www.netbeans.org/download/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a></tt>. Класс <tt>TopComponent</tt> &ndash; это класс <tt>JPanel</tt>, для которого у системы управления окнами NetBeans имеются методы взаимодействия, поэтому его можно будет разместить внутри контейнера с вкладками в главном окне.
</p><ol type="1">
<li>В окне &quot;Projects&quot; разверните узел <tt>Paint</tt>, затем узел &quot;Source Packages&quot;, после этого щелкните правой кнопкой мыши узел <tt>org.netbeans.paint</tt>. Выберите &quot;Choose New &gt; Java Class&quot;.</li>
Введите имя класса <tt>PaintTopComponent</tt> в поле &quot;Class Name&quot;. Убедитесь, что файл <tt>org.netbeans.paint</tt> определен как &quot;Package&quot;. Нажмите кнопку &quot;Finish&quot;. В редакторе исходного кода откроется файл <tt>PaintTopComponent.java</tt>.
<li>В верхней части файла измените объявление класса на следующее:
<pre class="examplecode"> public class PaintTopComponent extends TopComponent implements ActionListener, ChangeListener {</pre></li>
<li>Нажмите Ctrl-Shift-I для исправления операторов импорта и кнопку в диалоговом окне кнопку &quot;OK&quot;. Среда IDE произведет необходимые объявления пакета импорта в верхней части файла.</p>
<p>Обратите внимание на красную линию под введенным объявлением класса. Установите курсор в строке и обратите внимание на лампочку, появившуюся в левом поле. Щелкните изображение лампочки (или нажмите Alt-Enter), как показано ниже:
</p><p><img border="1" src="../../images/tutorials/paintapp/lightbulb-60.png" alt="Лампочка">
</p><p>Выберите &quot;Implement all abstract methods&quot;. Среда IDE создаст два скелетных метода: <tt>actionPerformed()</tt> и <tt>stateChanged()</tt>. Немного позднее их необходимо будет заполнить кодом.</p></li>
<li>Над классом <tt>PaintTopComponent</tt> добавьте следующие три объявления переменных, а затем исправьте операторы импорта (Ctrl-Shift-I).
<pre class="examplecode"> private PaintCanvas canvas = new PaintCanvas(); //Элемент, предназначенный для рисования
private JComponent preview; //Элемент на панели инструментов, обозначающий размер кисти
private static int ct = 0; //Счетчик, который дает имена новым изображениям</pre></li>
<li>Теперь необходимо реализовать два шаблонных метода. Первый сообщает системе управления окнами о необходимости игнорирования открытых окон, если приложение закрыто; второй предоставляет основную строку для уникального идентификатора строки создаваемого элемента. Каждый элемент <tt>TopComponent</tt> имеет уникальный идентификатор строки, который используется при сохранении <tt>TopComponent</tt>. Вставьте два следующих метода в класс <tt>PaintTopComponent</tt>:
<pre class="examplecode"> public int getPersistenceType() {
return PERSISTENCE_NEVER;
}
public String preferredID() {
return &quot;Image&quot;;
}</pre></li>
</ol>
<p>После этого класс должен выглядеть следующим образом:
</p><pre class="examplecode">public class PaintTopComponent extends TopComponent implements ActionListener, ChangeListener {
private PaintCanvas canvas = new PaintCanvas(); //Элемент, предназначенный для рисования
private JComponent preview; //Элемент на панели инструментов, обозначающий размер кисти
private static int ct = 0; //Счетчик, который дает имена новым изображениям
public PaintTopComponent() {
}
public void actionPerformed(ActionEvent arg0) {
throw new UnsupportedOperationException(&quot;Not supported yet.&quot;);
}
public void stateChanged(ChangeEvent arg0) {
throw new UnsupportedOperationException(&quot;Not supported yet.&quot;);
}
public int getPersistenceType() {
return PERSISTENCE_NEVER;
}
public String preferredID() {
return &quot;Image&quot;;
}
}</pre>
<h3 class="tutorial"><a name="initTopComp"></a>Инициализация класса &quot;TopComponent&quot;</h3>
<p>В этом разделе будет добавлен код, инициализирующий интерфейс пользователя.
</p><ol type="1">
<li>Заполните конструктор, созданный средой IDE рядом с верхней частью класса, а затем исправьте операторы импорта (Ctrl-Shift-I):
<pre class="examplecode"> public PaintTopComponent() {
initComponents();
String displayName = NbBundle.getMessage(
PaintTopComponent.class,
&quot;UnsavedImageNameFormat&quot;,
new Object[] { new Integer(ct++) }
);
setDisplayName(displayName);
}</pre></li>
<p>Код в этом случае довольно прост. Первым вызывается еще не написанный метод <tt>initComponents()</tt>, который добавит панель инструментов и элемент &quot;PaintCanvas&quot; к элементу <tt>TopComponent</tt>. Так как этот метод еще не написан, он подчеркивается красной линией. Как и в предыдущем случае, щелкните изображение лампочки (или нажмите Alt-Enter) и примите предложение:
</p><p><img border="1" src="../../images/tutorials/paintapp/lightbulb-initcomponents-60.png" alt="Лампочка">
</p><p>Будет создан скелетный код метода <tt>initComponents()</tt>.
</p><li>Разверните пакет <tt>org.netbeans.paint</tt> в окне &quot;Projects&quot;. Дважды щелкните файл <tt>Bundle.properties</tt> для его открытия в редакторе исходного кода. В конец добавьте следующую строку:
<pre class="examplecode"> UnsavedImageNameFormat=Image {0}</pre>
<p>Она отвечает за текст, который будет использоваться для идентификации нового файла изображения перед его сохранением пользователем. Например, когда пользователь в первый раз выбирает &quot;New Canvas&quot; в готовом приложении, над редактором исходного кода появится вкладка с текстом &quot;Image 0&quot;. Перед продолжением не забудьте сохранить файл.
</p></li></ol>
<h3 class="tutorial"><a name="fillSkelMeth"></a>Заполнение кодом скелетных методов</h3>
<p>В этом разделе будет написан код интерфейса пользователя для создаваемого приложения. Для визуальной разработки формата можно также использовать GUI Builder среды IDE.
</p><ol>
<li>Метод <tt>initComponents()</tt> устанавливает в панели элементы, благодаря которым пользователь получает возможность взаимодействия с приложением. Его скелетный код был создан в предыдущем разделе в классе <tt>PaintTopComponent.java</tt>. Заполните его следующим образом:
<pre class="examplecode"> private void initComponents() {
setLayout(new BorderLayout());
JToolBar bar = new JToolBar();
ColorChooser fg = new ColorChooser();
preview = canvas.createBrushSizeView();
//Теперь сформируйте панель инструментов:
//Обеспечьте правильное размещение элементов:
Dimension min = new Dimension(32, 32);
preview.setMaximumSize(min);
fg.setPreferredSize(new Dimension(16, 16));
fg.setMinimumSize(min);
fg.setMaximumSize(min);
JButton clear = new JButton(
NbBundle.getMessage(PaintTopComponent.class, &quot;LBL_Clear&quot;));
JLabel fore = new JLabel(
NbBundle.getMessage(PaintTopComponent.class, &quot;LBL_Foreground&quot;));
fg.addActionListener(this);
clear.addActionListener(this);
JSlider js = new JSlider();
js.setMinimum(1);
js.setMaximum(24);
js.setValue(canvas.getDiam());
js.addChangeListener(this);
fg.setColor(canvas.getColor());
bar.add(clear);
bar.add(fore);
bar.add(fg);
JLabel bsize = new JLabel(
NbBundle.getMessage(PaintTopComponent.class, &quot;LBL_BrushSize&quot;));
bar.add(bsize);
bar.add(js);
bar.add(preview);
JLabel spacer = new JLabel(&quot; &quot;); //Выровняйте разделитель так, чтобы кисть в предварительном просмотре не была растянута до конца панели инструментов:
spacer.setPreferredSize(new Dimension(400, 24));
bar.add(spacer);
//Установите панель инструментов и элемент для рисования:
add(bar, BorderLayout.NORTH);
add(canvas, BorderLayout.CENTER);
}</pre></li>
<p>Нажмите Ctrl-Shift-I для автоматического создания необходимых операторов импорта.
</p><li>Заполните два других созданных метода. Они используются для прослушивания класса <tt>PaintTopComponent</tt>:
<pre class="examplecode"> public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) {
canvas.clear();
} else if (e.getSource() instanceof ColorChooser) {
ColorChooser cc = (ColorChooser) e.getSource();
canvas.setPaint (cc.getColor());
}
preview.paintImmediately(0, 0, preview.getWidth(), preview.getHeight());
}</pre>
<pre class="examplecode"> public void stateChanged(ChangeEvent e) {
JSlider js = (JSlider) e.getSource();
canvas.setDiam (js.getValue());
preview.paintImmediately(0, 0, preview.getWidth(), preview.getHeight());
}</pre>
</li>
<li>В конец файла <tt>Bundle.properties</tt> добавьте следующие пары &quot;ключ-значение&quot;:
<pre class="examplecode">
LBL_Clear = Clear
LBL_Foreground = Foreground
LBL_BrushSize = Brush Size
</pre>
<p>Перед продолжением не забудьте сохранить файл.
</p></li>
</ol>
<h3 class="tutorial"><a name="savingImage"></a>Функция сохранения изображения на диске</h3>
<p>В новом приложении необходимо реализовать возможность сохранения созданных изображений пользователем. Эта функциональная возможность активируется включением следующего кода в класс <tt>PaintTopComponent</tt>.</p>
<ol type="1">
<li>Вставьте следующий код в класс <tt>PaintTopComponent</tt>:
<pre class="examplecode"> public void save() throws IOException {
if (getDisplayName().endsWith(&quot;.png&quot;)) {
doSave(new File(getDisplayName()));
} else {
saveAs();
}
}</pre>
<pre class="examplecode"> public void saveAs() throws IOException {
JFileChooser ch = new JFileChooser();
if (ch.showSaveDialog(this) == JFileChooser.APPROVE_OPTION &amp;&amp; ch.getSelectedFile() != null) {
File f = ch.getSelectedFile();
if (!f.getPath().endsWith(&quot;.png&quot;)) {
f = new File(f.getPath() + &quot;.png&quot;);
}
if (!f.exists()) {
if (!f.createNewFile()) {
String failMsg = NbBundle.getMessage(
PaintTopComponent.class,
&quot;MSG_SaveFailed&quot;, new Object[] { f.getPath() }
);
JOptionPane.showMessageDialog(this, failMsg);
return;
}
} else {
String overwriteMsg = NbBundle.getMessage(
PaintTopComponent.class,
&quot;MSG_Overwrite&quot;, new Object[] { f.getPath() }
);
if (JOptionPane.showConfirmDialog(this, overwriteMsg)
!= JOptionPane.OK_OPTION) {
return;
}
}
doSave(f);
}
}</pre>
<pre class="examplecode"> private void doSave(File f) throws IOException {
BufferedImage img = canvas.getImage();
ImageIO.write(img, &quot;png&quot;, f);
String statusMsg = NbBundle.getMessage(PaintTopComponent.class,
&quot;MSG_Saved&quot;, new Object[] { f.getPath() });
StatusDisplayer.getDefault().setStatusText(statusMsg);
setDisplayName(f.getName());
}</pre></li>
<li>Добавьте следующие строки в файл <tt>Bundle.properties</tt>:
<pre class="examplecode"> MSG_SaveFailed = Could not write to file {0}
MSG_Overwrite = {0} exists. Overwrite?
MSG_Saved = Saved image to {0}</pre>
<p>Перед продолжением не забудьте сохранить файл.
</p></li>
<li>Нажмите Ctrl-Shift-I для исправления операторов импорта. Для класса <tt>File</tt> будут отображены два полностью определенных имени. Выберите вариант <tt>java.io.File</tt>.
</li></ol>
</div><br>
<h2><a name="defNew"></a>Создание пункта меню для создания нового холста &quot;New Canvas&quot;</h2>
<p>Для создания основных функциональных возможностей модуля используются шаблоны файлов разработки модуля. При использовании шаблона файла среда IDE регистрирует созданный элемент в файле <tt>layer.xml</tt>. После выполнения мастера для создания шаблона файла для дальнейшей разработки модуля используются <a href="https://netbeans.org/download/dev/javadoc/"> интерфейсы API NetBeans</a>.
</p><ol>
<li>В окне &quot;Projects&quot; щелкните правой кнопкой мыши узел проекта модуля &quot;Paint&quot; и выберите &quot;New &gt; File/Folder&quot;. В мастере создания файла в области &quot;Categories and Action&quot; под полем &quot;File Types&quot; выберите &quot;NetBeans Module Development&quot;. Нажмите кнопку &quot;Next&quot;.</li>
<li>На экране &quot;Action Type&quot; примите значения по умолчанию. Нажмите кнопку &quot;Next&quot;.
</li><li>На экране &quot;GUI Registration&quot; выберите &quot;Global Menu Item&quot; и &quot;Global Toolbar Button&quot;. Установите следующие значения:
<p>
</p><ul><li><b>Category:</b> Edit
</li><li><b>Menu:</b> File
</li><li><b>Position:</b> Любое местоположение!
</li><li><b>Toolbar:</b> File
</li><li><b>Position:</b> Любое местоположение!
</li></ul>
<p><b class="notes">Примечание:</b> Местоположение действия не имеет значения, однако оно должно находиться в меню &quot;File&quot; и на панели инструментов &quot;File&quot;.
</p><p>Экран должен выглядеть следующим образом:
</p><p align="left"><img src="../../images/tutorials/paintapp/newcanvasaction-60.png" alt="Экран &quot;GUI Registration&quot;">
</p><p>Нажмите кнопку &quot;Next&quot;.
</p></li><li>На экране &quot;Name, Icon, and Location&quot; в поле &quot;Class Name&quot; введите имя класса <tt>NewCanvasAction</tt> и в поле &quot;Display Name&quot; укажите имя <tt>New Canvas</tt>.
<p>В поле &quot;Icon&quot; вставьте этот значок (щелкните здесь правой кнопкой мыши, а затем сохраните его в папке <tt>org.netbeans.paint</tt>): <img src="../../images/tutorials/paintapp/new_icon.png" alt="значок &quot;New Canvas&quot;.">
</p></li><li>Нажмите кнопку &quot;Finish&quot;.</p>
<p>Среда IDE создаст файл <tt>NewCanvasAction.java</tt> в <tt>org.netbeans.paint</tt> и откроет его в редакторе исходного кода. На экране должно отобразиться следующее (для просмотра соответствующей документации Javadoc для интерфейса API среды NetBeans перейдите по ссылкам):
</p><pre class="examplecode"> package org.netbeans.paint;
import <a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/HelpCtx.html">org.openide.util.HelpCtx</a>;
import <a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/NbBundle.html">org.openide.util.NbBundle</a>;
import <a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/actions/CallableSystemAction.html">org.openide.util.actions.CallableSystemAction</a>;
public final class NewCanvasAction extends CallableSystemAction {
public void <a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/actions/CallableSystemAction.html#performAction()">performAction()</a> {
// Добавить: тело действия
}
public String <a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/actions/SystemAction.html#getName()">getName()</a> {
return NbBundle.getMessage(NewCanvasAction.class, &quot;CTL_NewCanvasAction&quot;);
}
protected String <a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/actions/SystemAction.html#iconResource()">iconResource()</a> {
return &quot;org/netbeans/paint/new_icon.png&quot;;
}
public HelpCtx <a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/actions/SystemAction.html#getHelpCtx()">getHelpCtx()</a> {
return HelpCtx.DEFAULT_HELP;
}
protected boolean <a href="https://netbeans.org/download/dev/javadoc/org-openide-util/org/openide/util/actions/CallableSystemAction.html#asynchronous()">asynchronous()</a> {
return false;
}
}</pre>
<p>Как указано на экране &quot;GUI Registration&quot;, среда IDE регистрирует класс действия как пункт меню и как кнопку на панели инструментов в файле <tt>layer.xml</tt>.
</p></li><li>В редакторе исходного кода откройте <tt>NewCanvasAction.java</tt> и заполните метод <tt>performAction()</tt> следующим кодом:
<pre class="examplecode"> public void performAction() {
PaintTopComponent tc = new PaintTopComponent();
tc.open();
tc.requestActive();
}</pre>
<p>Этот код создает новый экземпляр элемента редактирования изображения; откройте его, в результате чего он появится в главном окне, а затем активируйте его путем установки курсора и выбора связанной с ним вкладки.
</p></li>
<h2 class="tutorial"><a name="defSave"></a>Создание пункта меню для сохранения холста &quot;Save Canvas&quot;</h2>
<p>Как и в предыдущем разделе, для создания элемента меню используется мастер создания действий, с помощью которого далее будет создана функция сохранения изображений.
</p><ol>
<li>В окне &quot;Projects&quot; щелкните правой кнопкой мыши узел проекта модуля &quot;Paint&quot; и выберите &quot;New &gt; File/Folder&quot;. В мастере создания файла в области &quot;Categories and Action&quot; под полем &quot;File Types&quot; выберите &quot;NetBeans Module Development&quot;. Нажмите кнопку &quot;Next&quot;.</li>
<li>На экране &quot;Action Type&quot; примите значения по умолчанию. Нажмите кнопку &quot;Next&quot;.
</li><li>На экране &quot;GUI Registration&quot; выберите &quot;Global Menu Item&quot; и &quot;Global Toolbar Button&quot;. Установите следующие значения:
<p>
</p><ul><li><b>Category:</b> Edit
</li><li><b>Menu:</b> File
</li><li><b>Position:</b> Любое местоположение!
</li><li><b>Toolbar:</b> File
</li><li><b>Position:</b> Любое местоположение!
</li></ul>
<p><b class="notes">Примечание:</b> Местоположение действия не имеет значения, однако оно должно находиться в меню &quot;File&quot; и на панели инструментов &quot;File&quot;.
</p><p>Нажмите кнопку &quot;Next&quot;.
</p></li><li>На экране &quot;Name, Icon, and Location&quot; в поле &quot;Class Name&quot; введите имя класса <tt>SaveCanvasAction</tt> и в поле &quot;Display Name&quot; укажите имя <tt>Save Canvas</tt>. </p>
<p>В поле &quot;Icon&quot; вставьте этот значок (щелкните здесь правой кнопкой мыши, а затем сохраните его в папке <tt>org.netbeans.paint</tt>): <img src="../../images/tutorials/paintapp/save_icon.png" alt="значок &quot;Save Canvas&quot;.">
</p></li><li>Нажмите кнопку &quot;Finish&quot;.</p>
<p>Среда IDE создаст файл <tt>SaveCanvasAction.java</tt> в <tt>org.netbeans.paint</tt> и откроет его в редакторе исходного кода.
</p></li><li>В редакторе исходного кода убедитесь в том, что файл <tt>SaveCanvasAction.java</tt> открыт, и заполните метод <tt>performAction()</tt> следующим кодом:
<pre class="examplecode"> public void performAction() {
TopComponent tc = TopComponent.getRegistry().getActivated();
if (tc instanceof PaintTopComponent) {
try {
((PaintTopComponent) tc).saveAs();
} catch (IOException ioe) {
ErrorManager.getDefault().notify (ioe);
}
} else {
//Теоретически за промежуток времени между нажатием кнопки в меню или в панели инструментов и вызовом действия активный элемент мог измениться. Вряд ли,
//но теоретически возможно
Toolkit.getDefaultToolkit().beep();
}
}</pre>
<p>Нажмите Ctrl-Shift-I для создания необходимых операторов импорта:
</p><p><img border="1" src="../../images/tutorials/paintapp/fiximports-60.png" alt="Исправление операторов импорта">
</p></li><li>Путем изменения объявления класса добавьте прослушивающий процесс изменения свойств:
<pre class="examplecode"> public final class SaveCanvasAction extends CallableSystemAction implements PropertyChangeListener {</pre>
<p>Снова появится красная линия. Нажмите Alt-Enter для вызова сообщения с лампочкой и выберите предложение:
</p><p><img border="1" src="../../images/tutorials/paintapp/lightbulb-listener1-60.png" alt="Сообщение с лампочкой &ndash; прослушивающий процесс 1">
</p><p>Снова появится красная линия. Повторите процедуру и примите предложение:
</p><p><img border="1" src="../../images/tutorials/paintapp/lightbulb-listener2-60.png" alt="Сообщение с лампочкой &ndash; прослушивающий процесс 2">
</p><p>Заполните созданный метод <tt>propertyChange()</tt> следующим кодом:
</p><pre class="examplecode"> public void propertyChange(PropertyChangeEvent evt) {
if (TopComponent.Registry.PROP_ACTIVATED.equals(evt.getPropertyName())){
updateEnablement();
}
}</pre><p>
</p><p>При появлении красной линии нажмите Alt+Enter, и среда IDE создаст метод <tt>updateEnablement()</tt> в классе <tt>SaveCanvasAction</tt>.</p>
<p>Затем определите метод <tt>updateEnablement()</tt>:
</p><pre class="examplecode"> private void updateEnablement() {
setEnabled(TopComponent.getRegistry().getActivated()
instanceof PaintTopComponent);
}</pre><p>
</p><p>После этого определите конструктор:
</p><pre class="examplecode"> public SaveCanvasAction() {
TopComponent.getRegistry().addPropertyChangeListener (
WeakListeners.propertyChange(this,
TopComponent.getRegistry()));
updateEnablement();
}</pre>
<p>При появлении красной линии нажмите Alt+Enter для импорта средой IDE <tt>org.openide.util.WeakListeners</tt>.</p>
<p>Важной частью кода является добавление прослушивающего процесса изменения свойств. <tt>TopComponent.Registry</tt> &ndash; это реестр всех открытых <tt>TopComponents</tt> в системе, т.е. всех открытых вкладок. Он должен прослушиваться на наличие изменений и предусматривать разрешение или запрет выполнения действия в зависимости от текущего фокуса.
</p><p><b class="notes">Примечание:</b> Вместо непосредственного добавления прослушивающего процесса изменения свойств можно вызвать <tt>WeakListeners.propertyChange()</tt>. В результате будет создан прослушивающий процесс изменения свойств, слабо связанный с рассматриваемым действием. Несмотря на то, что действие активно только при открытом приложении, если код ни при каких условиях не открепляет прослушивающий процесс, рекомендуется предусмотреть слабосвязанный прослушивающий процесс. В противном случае возможна потенциальная утечка памяти &ndash; действие никогда не сможет быть обработано сборщиком мусора, так как реестр будет ссылаться на него в своем списке прослушивающих процессов.
</p></li>
<p>В окне &quot;Projects&quot; должно отображаться следующее:
</p><p><img border="1" src="../../images/tutorials/paintapp/final-proj-window-60.png" alt="Заключительный вид окна &quot;Projects&quot;">
</p><h2><a name="wrappingUp"></a>Заключительная подготовка</h2>
<p>Безусловно, основной задачей является создание приложения, а не среды IDE, поэтому необходимо выполнить несколько заключительных операций для исключения лишних модулей IDE и элементов интерфейса пользователя. Во-первых, необходимо создать экран-заставку для приложения, во-вторых, удалить лишние модули и, наконец, создать дистрибутив в формате ZIP и приложение на базе JNLP.
</p><ol>
<li>Выполните проект <tt>PaintApp</tt>. После запуска приложения установите небольшой размер основного экрана и нарисуйте экран-заставку. Для сохранения экрана используйте кнопку &quot;Save&quot;. </li>
<li>В первоначальном проекте щелкните правой кнопкой мыши узел <tt>PaintApp</tt>, выберите &quot;Properties&quot;, а затем в диалоговом окне &quot;Project Properties&quot; нажмите кнопку &quot;Build&quot;.</li>
<li>Выберите &quot;Create Standalone Application&quot;. Теперь можно ввести название приложения (имя в средстве запуска, создаваемом средой IDE) и текст заголовка (который будет выводиться в строке заголовка). По умолчанию должно отображаться следующее:</p>
<p><img border="1" src="../../images/tutorials/paintapp/splashscreen1-60.png" alt="Экран-заставка">
</p></li><li>Выберите &quot;Splash Screen&quot;. Найдите собственный экран-заставку. Если такового не имеется, можно использовать <a href="https://platform.netbeans.org/images/tutorials/paintapp/splash.gif">этот</a>. Нажмите кнопку &quot;OK&quot; для его прикрепления к приложению:</li>
<p><img border="1" src="../../images/tutorials/paintapp/splashscreen-60.png" alt="Экран-заставка">
</p><li>Выберите &quot;Libraries&quot; и разверните узел <tt>platform7</tt>. Это единственный кластер, содержащий модули, которые будут связаны с созданным приложением для рисования. Отмеченные модули включаются, неотмеченные &ndash; исключаются. Обратите внимание, что многие модули уже исключены. Один из модулей необходимо исключить вручную: <tt>Core UI</tt>. Для этого отмените его выбор.</p>
<p>Затем в файле <tt>layer.xml</tt> модуля Paint добавьте следующие теги в папку &quot;Menu&quot;. Эти теги удаляют меню &quot;GoTo&quot; и &quot;View&quot;, которые не должны быть представлены в приложении для рисования.</p>
<pre class="examplecode">&lt;file name=&quot;GoTo_hidden&quot;/&gt;
&lt;file name=&quot;View_hidden&quot;/&gt;</pre>
<p>В качестве альтернативы, вместо добавления вышеуказанных тегов вручную можно удалить папки в узле <tt>&lt;this layer in context&gt;</tt> файла <tt>layer.xml</tt>. Для этого разверните <tt>&lt;this layer in context&gt;</tt>, а затем разверните узел &quot;Menu Bar&quot;. Щелчком правой кнопки мыши вызовите меню для узлов &quot;GoTo&quot; и &quot;View&quot; и выберите &quot;Delete&quot;.
</p></li><li>После этого снова запустите приложение и проверьте появившийся экран-заставку. Обратите внимание, что в запущенном приложении в строке заголовка выводится указанный текст. Кроме того, сократилось количество пунктов меню, кнопок на панели инструментов и других элементов:<br><br>
<p><img border="1" src="../../images/tutorials/paintapp/result-without-menus-60.png" alt="Результат без меню">
</p></li>
<h2 class="tutorial"><a name="creatingDist"></a>Создание дистрибутива</h2>
<p>
Теперь необходимо выбрать тип дистрибутива. Щелкните правой кнопкой мыши узел <tt>PaintApp</tt> и для сборки готового приложения со всеми необходимыми модулями и файлами в один файл ZIP выберите &quot;Create ZIP Distribution&quot;. Кроме того, можно выбрать &quot;Build JNLP Application&quot; для создания версии приложения на базе JavaWebStart&trade;, которое можно будет разместить на веб-сервере и переходить к нему по ссылке напрямую с веб-страницы (потребуется указать точный URL-адрес &ndash; созданный дескриптор будет использовать протокол &quot;file:&quot;, поэтому можно будет тестировать созданный веб-дистрибутив на локальном компьютере).
</p><p>Поздравляем! Создание первого приложения на базе платформы NetBeans завершено. Следующая тема: <a href="https://platform.netbeans.org/tutorials/60/nbm-feedreader_ru.html">Руководство по созданию приложения для чтения каналов на платформе NetBeans 6.0</a>.
<br>
</p><div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback: NetBeans Platform 6.0 Paint Application Tutorial">Мы ждем ваших отзывов</a></div>
<br style="clear:both;" />
<hr>
</ol></ol></ol></body>
</head></html>