| // |
| // 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=&Дополнительно > |
| |
| ---- |
| |
| Для остальных строк можно выполнить следующий брэндинг: |
| |
| |
| [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 г. |Приведены комментарии Тома Вилера, переписан раздел о брэндинге, так чтобы было больше информации о самом брэндинге, добавлены ссылки на сведения о локализации. |
| |=== |