blob: 1406ffa5ac50b92eb0ef55af21b8f42b6c0efd93 [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.
//
= Руководство по началу работы с платформой 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
Добро пожаловать в link:https://netbeans.apache.org/platform/[*платформу NetBeans*]!
Основным преимуществом платформы NetBeans является модульная архитектура. Кроме того, имеется воможность использования в платформе NetBeans инструментария пользовательского интерфейса Swing, являющегося официальным инструментарием создания пользовательских интерфейсов в Java, в сочетании с отмеченным наградой средством разработки Matisse GUI Builder среды IDE NetBeans.
В данном руководстве вы познакомитесь с преимуществами использования модульности на очень простом примере, созданном Томасом Вюртингером (Thomas Würthinger), докторантом университета имени Иоганнеса Кеплера в г. Линц, Австрия. После изучения основных понятий вы сможете перейти к link:https://netbeans.apache.org/kb/docs/platform_ru.html[Учебной карте по платформе NetBeans], которая предлагает богатый выбор учебных курсов по различным сценариям, относящимся к платформе NetBeans.
Если вы ранее не работали с платформой NetBeans, настоятельно рекомендуем посмотреть серию демонстрационных роликов link:https://netbeans.apache.org/tutorials/nbm-10-top-apis.html[10 лучших интерфейсов API NetBeans].
*Для работы с этим учебным курсом требуются программное обеспечение и ресурсы, перечисленные в таблице ниже.*
NOTE: Хотя платформа NetBeans является самостоятельным продуктом, ее не требуется загружать отдельно. Обычно разработка приложения выполняется в среде IDE NetBeans, после чего из приложения исключаются модули, специфичные для среды IDE, но излишние в данном приложении.
== Одномодульное приложение платформы NetBeans
Начнем с создания простого приложения на платформе NetBeans, содержащего один модуль.
[start=1]
1. Выберите в меню "Файл" команду "Новый проект" и щелкните проект "Модули NetBeans". Выберите параметр "Приложение платформы NetBeans". На экране появится следующее окно:
image::images/quickstart-platform_wordapp01.png[]
Нажмите кнопку "Далее".
[start=2]
1. Вызовите новое приложение "WordApp" и установите его как основной проект среды IDE:
image::images/quickstart-platform_wordapp02.png[]
Основной проект среды IDE запускается при вызове команды глобального проекта "Выполнить проект".
Нажмите кнопку "Готово".
[start=3]
1. Разверните новое приложение в окне "Проекты", щелкните узел "Модули" правой кнопкой и выберите команду "Добавить новый". Вызовите новый модуль "WordEngine":
image::images/quickstart-platform_wordapp03.png[]
Нажмите кнопку "Далее".
[start=4]
1. Введите уникальное имя модуля, которое является базовым кодовым именем, и имя, которое будет отображаться в окне "Проекты":
image::images/quickstart-platform_wordapp04.png[]
Нажмите кнопку "Готово". Новый модуль создан. Структура модуля выводится в окне "Проекты".
[start=5]
1. Щелкните модуль "WordEngine" правой кнопкой и выберите в меню "Создать" команду "Прочее". В категории "Разработка модулей" выберите "Оконный компонент":
image::images/quickstart-platform_wordapp05.png[]
Нажмите кнопку "Далее". На экране появится следующее окно:
image::images/quickstart-platform_wordapp06.png[]
Нажмите кнопку "Далее".
[start=6]
1. Введите в качестве префикса имени класса слово "Text" и выберите "org.demo.wordengine" в списке пакетов:
image::images/quickstart-platform_wordapp07.png[]
Нажмите кнопку "Готово". К исходной структуре модуля будет добавлено новое окно с несколькими вспомогательными файлами XML.
[start=7]
1. Теперь дважды щелкните файл "TextTopComponent.java" для открытия его в представлении "Проектирование" в Конструкторе GUI Matisse. Для перетаскивания кнопок и текстовых областей в окно используйте палитру (CTRL+SHIFT+8):
image::images/quickstart-platform_wordapp15.png[]
Щелкните текстовую область правой кнопки мыши, выберите параметр "Изменить имя переменной" и задайте имя переменной "text". Данное имя позволяет выполнять доступ к компоненту из кода. Введите в качестве названия кнопки текст "Filter!"
[start=8]
1. Дважды щелкните кнопку, что вызовет автоматическое создание метода обработки события в редакторе исходного кода. Метод вызывается всякий раз при нажатии кнопки. Замените тело метода следующим кодом.
[source,java]
----
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String s = text.getText();
s = s.toUpperCase();
text.setText(s);
}
----
[start=9]
1. Щелкните приложение правой кнопкой мыши и выберите команду "Выполнить". Новое приложение на платформе NetBeans будет запущено, а модуль установлен. Ваше новое приложение должно выглядеть следующим образом:
image::images/quickstart-platform_wordapp08.png[]
[start=10]
1. Выберите в меню "Окно" команду "Text", введите текст в текстовую область и нажмите "Filter!". Текст будет выведен на экран в верхнем регистре:
image::images/quickstart-platform_wordapp09.png[]
Вы узнали, как создавать новое приложение на платформе NetBeans и как добавлять в него новые модули.
== Модульное приложение с использованием класса Lookup
Мы создадим два дополнительных модуля. Первый модуль определяет службу, которую второй обеспечивает для модуля, определенного в предыдущем разделе.
[start=1]
1. Разверните новое приложение в окне "Проекты", щелкните узел "Модули" правой кнопкой и выберите команду "Добавить новый". Дайте новому модулю имя "TextFilter" и базовое кодовое имя "org.demo.textfilter", выполните действия, предлагаемые мастером, для добавления модуля в ранее созданное приложение, как это было сделано в предыдущем разделе.
[start=2]
1. Щелкните правой кнопкой мыши модуль TextFilter и выберите "Создать" > "Интерфейс Java". В пакете "org.demo.textfilter" укажите имя интерфейса Java "TextFilter" и используйте редактор для его определения следующим образом:
[source,java]
----
package org.demo.textfilter;
public interface TextFilter {
String process(String s);
}
----
[start=3]
1. Щелкните модуль "TextFilter" правой кнопкой, выберите команду "Свойства" и используйте вкладку "Версии API", чтобы указать, что пакет, в который входит интерфейс, доступен во всем приложении:
image::images/quickstart-platform_wordapp10.png[]
[start=4]
1. Создайте третий модуль в приложении, назовите его "MyFilter" с "org.demo.myfilter" в качестве базового кодового имени.
[start=5]
1. Добавьте зависимость к модулю "TextFilter" в диалоговом окне "Свойства проекта" только что созданного модуля "MyFilter":
image::images/quickstart-platform_wordapp11.png[]
[start=6]
1. Теперь на основании определенной выше зависимости можно реализовать интерфейс, определенный во втором модуле:
[source,java]
----
package org.demo.myfilter;
import org.demo.textfilter.TextFilter;
@ServiceProvider(service=TextFilter.class)
public class UpperCaseFilter implements TextFilter {
public String process(String s) {
return s.toUpperCase();
}
}
----
Во время компиляции аннотация @ServiceProvider создает папку META-INF/services с файлом, в котором регистрируется реализация интерфейса TextFilter в соответствии с механизмомJDK 6 ServiceLoader. Необходимо установить зависимость от модуля API средств, который поставляет аннотацию ServiceProvider.
[start=7]
1. Теперь необходимо изменить код, обрабатывающий нажатие кнопки фильтрации, чтобы найти и загрузить средство реализации интерфейса "TextFilter". Когда такое средство реализации найдено, оно вызывается для фильтрации текста.
Прежде чем это выполнить, необходимо добавить зависимость к модулю "TextFilter" в диалоговом окне "Свойства проекта" модуля "WordEngine":
image::images/quickstart-platform_wordapp12.png[]
После этого можно загрузить реализации класса "TextFilter", как показано ниже:
[source,java]
----
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String s = text.getText();
*TextFilter filter = Lookup.getDefault().lookup(TextFilter.class)*;
if (filter != null) {
s = filter.process(s);
}
text.setText(s);
}
----
Вышестоящий метод можно было бы выполнить с помощью класса "ServiceLoader" пакета JDK 6, однако класс "Lookup" может использоваться в пакете JDK более ранней версии, чем JDK 6. Кроме того, класс "Lookup" имеет дополнительные функции, как показано в следующем разделе.
Теперь вы готовы к запуску кода и проверке того, что все работает как прежде. Несмотря на то, что функциональные возможности остались прежними, новая модульная конструкция предлагает четкое разделение между графическим пользовательским интерфейсом и реализацией фильтрации. Новое приложение можно легко расширять, просто добавляя новых поставщиков услуг в путь к классам приложения.
В качестве упражнения попробуйте внести в код изменения, последовательно применяющие ВСЕ найденные текстовые фильтры к тексту (используя метод "lookupAll"). Например, добавьте реализацию текстового фильтра, удаляющего все пробелы, а затем протестируйте полученное приложение.
== LookupListener и InstanceContent
Попробуем создать четвертый модуль, который динамически принимает тексты при нажатии кнопки "Filter!" в первом модуле.
[start=1]
1. В первом модуле измените конструктор "TextTopComponent" следующим образом:*private InstanceContent content;*
[source,java]
----
private TextTopComponent() {
initComponents();
setName(NbBundle.getMessage(TextTopComponent.class, "CTL_TextTopComponent"));
setToolTipText(NbBundle.getMessage(TextTopComponent.class, "HINT_TextTopComponent"));
// setIcon(Utilities.loadImage(ICON_PATH, true));
*content = new InstanceContent();
associateLookup(new AbstractLookup(content));*
}
----
[start=2]
1. Измените код кнопки фильтрации, чтобы при нажатии кнопки к объекту ``InstanceContent`` добавлялось старое значение.
[source,java]
----
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String s = text.getText();
TextFilter filter = Lookup.getDefault().lookup(TextFilter.class);
if (filter != null) {
*content.add(s);*
s = filter.process(s);
}
text.setText(s);
}
----
[start=3]
1. Создайте новый модуль и присвойте ему имя "History" с базовым кодовым именем "com.demo.history".
[start=4]
1. В модуле "History" создайте новый компонент окна с префиксом "History" в пакете "com.demo.history". Укажите, что этот компонент должен отображаться в позиции "editor". После создания окна добавьте к нему текстовую область. Измените имя переменной текстовой области на "historyText".
[start=5]
1. Добавьте к конструктору класса "HistoryTopComponent" код для отслеживания поиска класса ``String`` текущего активного окна. На экран будут выведены все полученные объекты ``String`` в текстовой области:*private Lookup.Result result;*
[source,java]
----
private HistoryTopComponent() {
...
*result = org.openide.util.Utilities.actionsGlobalContext().lookupResult(String.class);
result.addLookupListener(new LookupListener() {
public void resultChanged(LookupEvent e) {
historyText.setText(result.allInstances().toString());
}
});*
}
----
[start=6]
1. После этого приложение можно запустить и поэкспериментировать над ним. В результате на экран должно быть выведено окно, похожее на один из следующих вариантов:
image::images/quickstart-platform_wordapp13.png[]
В качестве упражнения попробуйте изменить тип результата поиска со значения ``String`` на ``Object`` и посмотрите, что произойдет, если выбрать другие окна.
Поздравляем! На этом этапе с помощью незначительного программирования был создан небольшой пример модульного приложения:
image::images/quickstart-platform_wordapp14.png[]
Приложение состоит из четырех модулей. Код из одного модуля может использоваться в другом модуле, только если (1) первый модуль явно раскрыл пакеты, и (2) второй модуль установил зависимость от первого модуля. Таким образом платформа NetBeans помогает организовать код в строгой модульной архитектуре, обеспечивая невозможность случайного повторного использования кода, за исключением случая установления контрактов между модулями, обеспечивающими код.
Кроме того, класс ``Lookup`` вводится как механизм коммуникации между модулями, как расширение метода ServiceLoader пакета JDK 6. Реализации загружаются через свои интерфейсы. Не используя код из реализации, модуль "WordEngine" может вывести на экран службу, предоставленную средством реализации. Таким способом обеспечивается свободное соединение между приложениями платформы NetBeans.
Для дальнейшего изучения модульности и платформы NetBeans перейдите к руководству "Управлением выбором в платформе NetBeans", состоящему из 4 частей, которое link:https://netbeans.apache.org/tutorials/nbm-selection-1.html[начинается здесь]. Затем можно воспользоваться link:https://netbeans.apache.org/kb/docs/platform_ru.html[Учебной картой по платформе NetBeans] и выбрать учебные курсы, максимально подходящие для вашего индивидуального бизнес-сценария. Кроме того, при возникновении вопросов по платформе NetBeans можно обратиться по адресу: dev@openide.netbeans.org. Архив вопросов находится link:https://mail-archives.apache.org/mod_mbox/netbeans-dev/[здесь].
Приятной работы с платформой NetBeans! Не забудьте подписаться на наши рассылки!