blob: 5d67ecfa14213e5cc9c27f2c9c76ff0d69b572ef [file] [log] [blame]
//
// 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.
//
= Курс по использованию модуля Wizard
:jbake-type: platform_tutorial
:jbake-tags: tutorials
:jbake-status: published
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:icons: font
:experimental:
:description: Курс по использованию модуля Wizard - Apache NetBeans
:keywords: Apache NetBeans Platform, Platform Tutorials, Курс по использованию модуля Wizard
В этом учебном курсе вы узнаете, как использовать основные функциональные возможности, предлагаемые классами Wizard link:http://bits.netbeans.org/dev/javadoc/org-openide-dialogs/org/openide/package-summary.html[интерфейса API NetBeans ].
*Содержимое*
* <<set,Создание модуля проекта>>
* <<wiz,Создание инфраструктуры мастера>>
* <<action,Регистрация класса действия мастера>>
* <<design,Проектирование содержимого мастера>>
* <<process,Обработка данных пользователя>>
* <<validate,Проверка данных пользователя>>
* <<persist,Сохранение данных при перезапуске>>
* <<brand,Брэндинг мастера>>
* <<further,Дополнительные сведения>>
В приложениях платформы NetBeans существует возможность создания различных мастеров. Если необходимо создать мастер, который отображается в диалоговом окне создания проекта, обратитесь к link:https://netbeans.apache.org/tutorials/nbm-projectsamples.html[Учебному курсу по модулю добавления примера проекта]. Если необходимо создать мастер, который отображается в диалоговом окне создания файла, обратитесь к link:https://netbeans.apache.org/tutorials/nbm-filetemplates.html[Учебному курсу по созданию модулей шаблонов файлов]. В этом учебном курсе будет рассмотрено создание общего мастера, который появляется при щелчке кнопки на панели инструментов.
*Для работы с этим учебным курсом требуется программное обеспечение и ресурсы, перечисленные в следующей таблице.*
== Создание модуля проекта
Сначала используется мастер "Новый модуль проекта". В конце его работы создается структура основных источников с некоторыми файлами по умолчанию, которые необходимы для любого модуля среды NetBeans.
[start=1]
1. Выберите в меню "Файл" команду "Новый проект" (CTRL+SHIFT+N). В разделе "Категории" выберите параметр "Модули NetBeans". В области "Проекты" выберите "Модуль". Нажмите кнопку "Далее".
[start=2]
1. На панели "Имя и расположение" в поле "Имя проекта" введите текст ``DemoWizard`` . В поле "Расположение проекта" укажите любой каталог на компьютере. Оставьте параметр "Отдельный модуль" выбранным и не снимайте флажок "Установить как главный проект". Нажмите кнопку "Далее".
[start=3]
1. На панели "Основные настройки модуля" в поле "Основа кодового имени" введите текст ``org.demo.wizard`` .
[start=4]
1. Выберите "Создать слой XML". Не меняйте места расположения пакета локализации и файла слоя XML. Таким образом они будут сохранены с именем ``org/demo/wizard`` . Нажмите кнопку "Готово".
В среде IDE будет создан проект ``DemoWizard`` . Проект содержит все источники и метаданные проекта, например, сценарий построения проекта Ant. Проект откроется в среде IDE. Логическую структуру проекта можно просмотреть в окне "Проекты" (CTRL+1), а его файловую структуру в окне "Файлы" (CTRL+2).
== Создание инфраструктуры мастера
В этом разделе рассмотрено использование мастера "Мастер" для добавления к модулю заглушек мастера.
[start=1]
1. В окне "Проекты" щелкните правой кнопкой мыши узел проекта DemoWizard и выберите "Создать | Прочее", а затем "Разработка модуля | Мастер":
image::images/wizard_wizard-wizard.png[]
Нажмите кнопку "Далее".
[start=2]
1. На панели "Тип мастера" в поле "Количество панелей мастера" введите 2, а другие значения оставьте без изменений:
image::images/wizard_wizard-wizard-3.png[]
На вышеописанной панели используются следующие поля:
* *Тип регистрации.* Определяет место, из которого осуществляется доступ к мастеру. При выборе варианта "Особый" с помощью мастера Wizard будет создан новый класс действия, который используется для открытия и инициализации данного мастера. При выборе параметра "Создать файл" мастер Wizard зарегистрирует созданный мастер в файле ``layer.xml`` модуля.
* *Последовательность этапов мастера.* Определяет, будет ли мастер иметь линейный характер и будет ли у пользователя возможность пропустить какие-либо этапы мастера, в зависимости от выбранных на предыдущих этапах параметров. По умолчанию для линейного мастера выбран вариант "Статический", в то время как для мастера с пропускаемыми шагами требуется наличие специального класса итерации, который создается при выборе варианта "Динамический".
* *Количество панелей мастера.* Определяет количество панелей в создаваемом мастере. Для каждого этапа мастера будет создано два файла Java: представление и контроллер.
Нажмите кнопку "Далее".
[start=3]
1. На панели "Имя и расположение" введите в поле "Префикс имени класса" текст ``Demo`` , а в раскрывающемся меню "Пакет" выберите основной пакет.
image::images/wizard_wizard-wizard-4.png[]
Нажмите кнопку "Готово".
В окне "Проекты" должно отображаться следующее:
image::images/wizard_projects-window.png[]
== Регистрация класса действия мастера
В этом разделе описывается изменение класса действия и его регистрация в файле ``layer.xml`` .
[start=1]
1. Откройте файл ``DemoWizardAction.java`` и замените весь код следующим:
[source,java]
----
package org.demo.wizard;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.MessageFormat;
import javax.swing.JComponent;
import org.openide.DialogDisplayer;
import org.openide.WizardDescriptor;
public final class DemoWizardAction implements ActionListener {
private WizardDescriptor.Panel[] panels;
public void actionPerformed(ActionEvent e) {
WizardDescriptor wizardDescriptor = new WizardDescriptor(getPanels());
// {0} заменяется на WizardDesriptor.Panel.getComponent().getName()
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
wizardDescriptor.setTitle("Заголовок диалогового окна мастера");
Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
dialog.setVisible(true);
dialog.toFront();
boolean cancelled = wizardDescriptor.getValue() != WizardDescriptor.FINISH_OPTION;
if (!cancelled) {
// любые действия
}
}
/**
* Инициализация панелей, соответствующих отдельным этапам мастера
* и установка различных свойств, регулирующих внешний вид мастера.
*/
private WizardDescriptor.Panel[] getPanels() {
if (panels == null) {
panels = new WizardDescriptor.Panel[]{
new DemoWizardPanel1(),
new DemoWizardPanel2()
};
String[] steps = new String[panels.length];
for (int i = 0; i < panels.length; i++) {
Component c = panels[i].getComponent();
// Название этапа по умолчанию для имени компонента панели. Обычно используется
// для получения имени выбора цели, которое появляется
// в перечне этапов.
steps[i] = c.getName();
if (c instanceof JComponent) { // assume Swing components
JComponent jc = (JComponent) c;
// Задает номер этапа для компонента
// TODO использует org.openide.dialogs >= 7.8, может использовать WizardDescriptor.PROP_*:
jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i));
// Задание имени этапа для панели
jc.putClientProperty("WizardPanel_contentData", steps);
// Включение создания субтитров на каждом этапе
jc.putClientProperty("WizardPanel_autoWizardStyle", Boolean.TRUE);
// Отображает этапы на левой стороне с изображением на заднем фоне
jc.putClientProperty("WizardPanel_contentDisplayed", Boolean.TRUE);
// Включение нумерации для всех этапов
jc.putClientProperty("WizardPanel_contentNumbered", Boolean.TRUE);
}
}
}
return panels;
}
public String getName() {
return "Start Sample Wizard";
}
}
----
Используется тот же код, что и сгенерированный, за исключением реализации ``ActionListener`` вместо ``CallableSystemAction`` . Это сделано потому, что ``ActionListener`` является стандартным классом JDK, а ``CallableSystemAction`` - нет. Поскольку используется платформа NetBeans 6.5, можно использовать стандартный класс JDK, что более удобно и требует меньше кода.
[start=2]
1. Регистрация класса действий в файле ``layer.xml`` осуществляется следующим образом:
[source,xml]
----
<filesystem>
<folder name="Actions">
<folder name="File">
<file name="org-demo-wizard-DemoWizardAction.instance">
<attr name="delegate" newvalue="org.demo.wizard.DemoWizardAction"/>
<attr name="iconBase" stringvalue="org/demo/wizard/icon.png"/>
<attr name="instanceCreate" methodvalue="org.openide.awt.Actions.alwaysEnabled"/>
<attr name="noIconInMenu" stringvalue="false"/>
</file>
</folder>
</folder>
<folder name="Toolbars">
<folder name="File">
<file name="org-demo-wizard-DemoWizardAction.shadow">
<attr name="originalFile" stringvalue="Actions/File/org-demo-wizard-DemoWizardAction.instance"/>
<attr name="position" intvalue="0"/>
</file>
</folder>
</folder>
</filesystem>
----
Элемент "iconBase" указывает на изображение с именем "icon.png" в основном пакете. Если используется собственное изображение, оно должно быть размером 16x16 пикселей, или же необходимо сделать следующее:
image::images/wizard_icon.png[]
[start=3]
1. Запустите модуль. Запустится приложение, и на панели инструментов, в месте, которое задано в файле ``layer.xml`` , будут отображены кнопки:
image::images/wizard_result-1.png[]
Нажмите кнопку для открытия мастера:
image::images/wizard_result-2.png[]
Нажмите кнопку "Далее" и обратите внимание на то, что на последней панели кнопка "Готово" станет активной.
image::images/wizard_result-3.png[]
Теперь, когда структура мастера работает, добавим дополнительное содержимое.
== Проектирование содержимого мастера
В этом разделе описывается добавление содержимого к мастеру и настройка основных функций.
[start=1]
1. Откройте файл ``DemoWizardAction.java`` . Обратите внимание, существует возможность настройки различных свойств мастера:
image::images/wizard_wizard-tweaking.png[]
Описание этих свойств приведено link:http://ui.netbeans.org/docs/ui_apis/wide/index.html[здесь].
[start=2]
1. В ``DemoWizardAction.java`` измените текст ``wizardDescriptor.setTitle`` на следующий:
[source,java]
----
wizardDescriptor.setTitle("Выбор музыки");
----
[start=3]
1. Откройте файл ``DemoVisualPanel1.java`` и файл ``DemoVisualPanel2.java`` и используйте конструктор графического интерфейса пользователя "Matisse" для добавления компонентов Swing например, следующих:
image::images/wizard_panel-1-design.png[]
image::images/wizard_panel-2-design.png[]
Выше показаны файлы ``DemoVisualPanel1.java`` и ``DemoVisualPanel2.java`` , с компонентами Swing.
[start=4]
1. Откройте две панели в представлении Источник и измените их методы ``getName()`` на "Имя и адрес" и "Сведения о музыканте", соответственно.
[start=5]
1.
Запустите модуль еще раз. При открытии мастера, в зависимости от добавленных компонентов Swing и использованных настроек, внешний вид мастера будет аналогичен следующему:
image::images/wizard_result-4.png[]
Вышеприведенное изображение на левой панели мастера устанавливается в файле ``DemoWizardAction.java`` следующим образом:
[source,java]
----
wizardDescriptor.putProperty("WizardPanel_image", ImageUtilities.loadImage("org/demo/wizard/banner.png", true));
----
После того, как создано содержимое мастера, необходимо добавить программный код для обработки данных, которые вводятся пользователем.
== Обработка данных пользователя
В этом разделе описана процедура передачи данных пользователя от одной панели к другой, а также как отображение результатов для пользователя после нажатия кнопки "Готово".
[start=1]
1. В классе ``WizardPanel`` для получения набора данных из визуальных средств поддержки используется метод ``storeSettings`` . Например, создадим модуль получения данных в файле ``DemoVisualPanel1.java`` , а затем получим к нему доступ из файла ``DemoWizardPanel1.java`` :
[source,java]
----
public void storeSettings(Object settings) {
((WizardDescriptor) settings).putProperty("name", ((DemoVisualPanel1)getComponent()).getNameField());
((WizardDescriptor) settings).putProperty("address", ((DemoVisualPanel1)getComponent()).getAddressField());
}
----
[start=2]
1. Затем, с помощью файла ``DemoWizardAction.java`` получим введенные параметры и обработаем их:
[source,java]
----
public void actionPerformed(ActionEvent e) {
WizardDescriptor wizardDescriptor = new WizardDescriptor(getPanels());
// {0} будет заменен на WizardDesriptor.Panel.getComponent().getName()
wizardDescriptor.setTitleFormat(new MessageFormat("{0}"));
wizardDescriptor.setTitle("Music Selection");
Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor);
dialog.setVisible(true);
dialog.toFront();
boolean cancelled = wizardDescriptor.getValue() != WizardDescriptor.FINISH_OPTION;
if (!cancelled) {
*String name = (String) wizardDescriptor.getProperty("name");
String address = (String) wizardDescriptor.getProperty("address");
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(name + " " + address));*
}
}
----
``NotifyDescriptor`` также можно использовать другими способами, например в окне завершения кода:
image::images/wizard_notifydescriptor.png[]
Итак, была рассмотрена обработка данных, вводимых пользователем.
== Проверка данных пользователя
В этом разделе описана процедура проверки данных, введенных пользователем, при нажатии клавиши "Далее".
[start=1]
1. В ``DemoWizardPanel1`` измените сигнатуру класса, реализовав ``WizardDescriptor.ValidatingPanel`` вместо ``WizardDescriptor.Panel`` :
[source,java]
----
public class DemoWizardPanel1 implements WizardDescriptor.ValidatingPanel
----
[start=2]
1. В начале класса следует изменить объявление ``JComponent`` на объявление
[source,java]
----
private DemoVisualPanel1 component;
----
[start=3]
1. При реализации необходимо использовать абстрактный метод, например:
[source,java]
----
@Override
public void validate() throws WizardValidationException {
String name = component.getNameTextField().getText();
if (name.equals("")){
throw new WizardValidationException(null, "Invalid Name", null);
}
}
----
[start=4]
1. Запустите модуль. Нажмите кнопку "Далее", не вводя ничего в поле "Имя". После этого должен появиться нижеприведенный результат. Обратите внимание, что если данные не прошли проверку, то переход к следующей панели невозможен:
image::images/wizard_validation1.png[]
[start=5]
1. Также, если поле было оставлено пустым, можно сделать кнопку "Далее" неактивной. Сначала необходимо объявить вверху класса логические переменные:
[source,java]
----
private boolean isValid = true;
----
Затем переопределить ``isValid()`` следующим образом:
[source,java]
----
@Override
public boolean isValid() {
return isValid;
}
----
Тогда, при вызове ``validate()`` , который происходит при нажатии кнопки "Далее", возвращается значение "false":
[source,java]
----
@Override
public void validate() throws WizardValidationException {
String name = component.getNameTextField().getText();
if (name.equals("")) {
*isValid = false;*
throw new WizardValidationException(null, "Недопустимое имя", null);
}
}
----
Другой вариант заключается в первоначальном задании значения логической переменной "false". Затем реализуется ``DocumentListener`` , который добавляет слушатель для поля и, при вводе пользователем в этом поле текста, изменяет значения логической переменной на "true" и вызывает метод ``isValid()`` .
Итак, была рассмотрена проверка данных, вводимых пользователем.
Для получения дополнительных сведений о проверке данных, введенных пользователем, обратитесь к примеру Тома Вилера в конце данного учебного курса.
== Сохранение данных при перезапуске
В этом разделе описана процедура сохранения данных при закрытии приложения, и их дальнейшее получение мастером при повторном запуске.
[start=1]
1. В ``DemoWizardPanel1.java`` переопределите методы ``readSettings`` и ``storeSettings`` следующим образом:
[source,java]
----
*JTextField nameField = ((DemoVisualPanel1) getComponent()).getNameTextField();
JTextField addressField = ((DemoVisualPanel1) getComponent()).getAddressTextField();*
@Override
public void readSettings(Object settings) {
*nameField.setText(NbPreferences.forModule(DemoWizardPanel1.class).get("namePreference", ""));
addressField.setText(NbPreferences.forModule(DemoWizardPanel1.class).get("addressPreference", ""));*
}
@Override
public void storeSettings(Object settings) {
((WizardDescriptor) settings).putProperty("name", nameField.getText());
((WizardDescriptor) settings).putProperty("address", addressField.getText());
*NbPreferences.forModule(DemoWizardPanel1.class).put("namePreference", nameField.getText());
NbPreferences.forModule(DemoWizardPanel1.class).put("addressPreference", addressField.getText());*
}
----
[start=2]
1. Запустите модуль еще раз и введите имя и адрес в первой панели мастера:
image::images/wizard_nbpref1.png[]
[start=3]
1. Закройте приложение, откройте меню "Файлы" и просмотрите свойства файла в папке ``build`` приложения. На экране должны появиться следующие настройки:
image::images/wizard_nbpref2.png[]
[start=4]
1. Еще раз запустите приложение. При следующем открытии мастера для задания значений в полях мастера будут автоматически использованы ранее заданные настройки.
Итак, было рассмотрено сохранение данных при перезапуске.
== Брэндинг мастера
В этом разделе описана процедура изменения наименования кнопки "Далее" в инфраструктуре мастера на надпись "Дополнительно".
Под термином "брэндинг" подразумевается настройка, которая обычно заключается в незначительных изменениях с сохранением языка интерфейса, в то время как под понятием "интернационализация" или "локализация" подразумевается перевод на другие языки. Сведения относительно локализации модулей NetBeans приведены link:http://translatedfiles.netbeans.org/index-l10n.html[здесь].
[start=1]
1. В окне "Файлы" разверните папку ``branding`` и создайте нижеприведенную структуру файлов и папок:
image::images/wizard_branding-1.png[]
[start=2]
1. Содержимое файла задайте следующим образом:
[source,java]
----
CTL_NEXT=&amp;Дополнительно >
----
Для остальных строк можно выполнить следующий брэндинг:
[source,java]
----
CTL_CANCEL
CTL_PREVIOUS
CTL_FINISH
CTL_ContentName
----
Кнопка "CTL_ContentName" по умолчанию настроена на "Шаги" и используется в левой панели мастера, если свойство "WizardPanel_autoWizardStyle" не было установлено как "FALSE".
[start=3]
1. Запустите приложение. Кнопка "Далее" будет подписана "Дополнительно":
image::images/wizard_branding-2.png[]
Для удаления левой панели мастера можно использовать файл ``DemoWizardAction.java`` , как было описано ранее:
[source,java]
----
wizardDescriptor.putProperty("WizardPanel_autoWizardStyle", Boolean.FALSE);
----
В результате вышеописанных настроек вид мастера будет следующим:
image::images/wizard_branding-3.png[]
Был рассмотрен брэндинг строк, определенных в инфраструктуре мастера и создание собственной брендированной версии.
== Дополнительные сведения
Некоторые дополнительные сведения доступны в сети:
* Сайт о NetBeans Тома Вилера (щелкните изображение внизу):
[.feature]
--
image::images/wizard_tom.png[role="left", link="http://www.tomwheeler.com/netbeans/"]
--
Вышеприведенные примеры, хотя и были написаны для среды NetBeans 5.5, были успешно опробованы в среде IDE NetBeans 6.5.1 в операционной системе Ubuntu Linux с JDK 1.6.
Особенно полезны данные примеры для демонстрации проверки пользовательских данных.
* Блог Джирджена (Geertjan)
* link:http://blogs.oracle.com/geertjan/entry/how_wizards_work[Как работает мастер. Часть 1: введение]
* link:http://blogs.oracle.com/geertjan/entry/how_wizards_work_part_2[Как работает мастер. Часть 2: различные типы]
* link:http://blogs.oracle.com/geertjan/entry/how_wizards_work_part_3[Как работает мастер. Часть 3: ваш первый мастер]
* link:http://blogs.oracle.com/geertjan/entry/how_wizards_work_part_4[Как работает мастер. Часть 4: ваш собственный итератор]
* link:http://blogs.oracle.com/geertjan/entry/how_wizards_work_part_5[Как работает мастер. Часть 5: использование и внедрение существующих панелей]
* link:http://blogs.oracle.com/geertjan/entry/creating_a_better_java_class[Создание мастера Better Java Class]
== Управление версиями
|===
|*Версия* |*Дата* |*Изменения*
|1 |31 марта 2009 г. |Первоначальная версия. Выполнить:
* [.line-through]#Добавить раздел о проверке данных, введенных пользователем.#
* [.line-through]#Добавить раздел о сохранении данных мастером и загрузке данных из мастера.#
* Добавить таблицу с перечислением всех свойств WizardDescriptor.
* Добавить таблицу с перечислением и объяснением всех классов Wizard API.
* Добавить ссылки на Javadoc.
|2 |1 апреля 2009 г. |Добавлен раздел о проверке данных с примером программного кода, который делает кнопку "Далее" неактивной. Также добавлен раздел о сохранении состояния.
|3 |10 апреля 2009 г. |Приведены комментарии Тома Вилера, переписан раздел о брэндинге, так чтобы было больше информации о самом брэндинге, добавлены ссылки на сведения о локализации.
|===