410013796724260
• Webmoney
R335386147728
Z369087728698
Базовый модуль UniversalБазовый модуль base-universal, выполненный по технологии OSGi, существенно облегчает и ускоряет формирование интерфейсного бандла для приложений на платформе JaBricks. Модуль base-universal объединяет в себе свойства двух базовых интерфейсных бандлов base-jdialog и base-jpanel. Таким образом, интерфейсная часть base-universal может быть представлена как диалоговым окном JDialog, так и в виде панели JPanel. В «чистом виде» модуль base-universal не применяется; он должен быть включен в конфигурацию приложения и использован в качестве родительского. Пример base-universal представлен в templ-universal. В настоящее время распространяется модуль версии 1.0.1, который полностью совместим с первой версией 1.0.0, и дополнен новым функционалом, отмеченным в тексте. Основные функциональные свойства модуля base-universal обеспечивают :
Таким образом, созданный с помощью модуля base-universal бандл имеет возможность формировать интерфейс из нескольких бандлов. Необходимо отметить, что после старта бандла можно только один экземпляр его интерфейсной части одномоментно интегрировать в другой бандл. Чтобы интегрировать бандл в разные модули приложения, к примеру, чтобы иметь возможность в разных частях приложения читать и изменять определенные справочные данные, необходимо чтобы бандл перед стартом находился в состоянии RESOLVED (остановлен) или INSTALLED (инсталлирован), т.е. не должен быть в состоянии ACTIVE. Особенности старта бандлаОтличительной особенностью старта бандла, созданного с использованием base-universal, является необходимость определения типа представления интерфейса guimode, значением которого может быть либо "jdialog", либо "jpanel". Если модуль, созданный с использованием base-universal, стартует главный фрейм приложения, то параметр guimode необходимо определить либо в структуре описания Панели инструментов, либо в описании Главного меню. То есть, бандл стартует по нажатию на кнопку «Панели инструментов» или при выборе одного из пунктов «Главного меню». Никаких отличий от старта своих «побратимов» ("base-jdialog", "base-jpanel") нет, если не считать необходимость описания guimode, в зависимости от значения которого может быть либо открыто диалоговое окно, либо у главного фрейма будет запрошен контейнер для размещения интерфейсной панели. Кроме стандартного старта бандла главным фреймом приложения, он может быть также стартован из другого бандла, который назовем родительским. В этом случае в структурах описаний «Панели инструментов» и «Главного меню» никакой информации о стартуемом бандле (назовем его дочерним) не будет. Поэтому дочерний бандл, созданный с использованием base-iniversal, будет запрашивать режим представления интерфейса guimode «по подписке». Родительский бандл должен ответить дочернему бандлу соответствующей «публикацией», чтобы стартованный бандл, мог создать интерфейс, либо реализовать заданные функции. В противном случае, он останется в режиме ожидания ответа (сообщения). Если дочерний бандл должен стартовать в режиме "jpanel", то он запросит для себя «по подписке» контейнер для размещения своего интерфейса. Поскольку дочерний бандл стартует из родительского, то тип представления интерфейса дочернего бандла определяется в родительском модуле, в который он может быть интегрирован. Таким образом, главной отличительной особенностью бандла на базе base-universal является возможность встраивания интерфейса дочернего бандла в родительский интерфейс. Бандл версии 1.0.1 дополнительно включает возможность сохранения значений компонентов при останове бандла и их восстановление при повторном старте бандла в течение одного сеанса работы приложения. Структура модуля
На скриншоте слева представлена структура модуля в виде проекта в IDE Eclipse. В пакете org.jabricks.universal располагаются активатор и классы формирования интерфейса. Активатор UniversalActivator содержит основные методы (start, stop),определенные технологией OSGi-бандла. Остальные классы пакета предназначены для реализации интерфейсной части бандла. Так, если к примеру, бандл будет формировать интерфейс в виде диалогового окна, то активатор будет использовать класс JBDialog, в противном случае будет использован класс JBPanel. Оба класса JBDialog и JBPanel наследуют свойства JBCommon, который содержит общие, доступные наследникам поля и методы (с модификаторами public/protected), необходимые для формирования интерфейса. Чтобы избежать дублирования кода при формировании интерфейса, рекомендуется непосредственно создавать GUI (graphic user interface) в некотором дополнительном классе, которому JBDialog и JBPanel будут передавать свои контейнеры для его размещения. На странице описания модуля templ-universal, использующего base-universal в качестве базового, представлен пример реализации данного подхода. Модуль версии 1.0.0 дополнительно включает также располагаемый в пакете org.jabricks.universal класс Reference, кооторый рекомендуется использовать в качестве объектов при формировании наборов данных для выпадающих списков JComboBox. В этом случае можно будет реализовать дополнительный функционал данной версии по восстановлению значений компонентов. Более подробно о функционале восстановления значений компонентов представлено здесь. В пакете org.jabricks.universal.pubsub располагаются классы реализации механизма «публикации/подписки» для организации взаимодействия с другими бандлами. Необходимо отметить, что непосредственно методы создания экземпляров «публикаторов» и «подписчиков», а также методы отправки сообщений располагаются в активаторе UniversalActivator. Кроме этого, активатор содержит методы, которые вызываются подписчиками при получении соответствующих сообщений от «публикаторов». Таким образом, в реализации механизма «публикации/подписки» активатор играет роль «дирижера». Старт бандла начинается вызовом метода активатора start. Стартовать бандл на базе base-universal могут как главный фрейм приложения из «Главного меню» или «Панели инструментов», так и любой другой бандл. Поэтому после старта могут развиваться разные сценарии создания интерфейса. В таблице представлено краткое описание классов модуля. Отправка всех сообщений «подписчикам» осуществляется активатором с использованием EventPublisher, имеющего соответстующие методы. 4 класса (GuimodeRequestSubscriber, GuimodeResponseSubscriber, PanelRequestSubscriber, PanelResponseSubscriber) используются для взаимодействия между «родительским» и «дочерним» бандлами. Остальные классы пакета org.jabricks.universal.pubsub участвуют в организации механизма «публикации/подписки» как между бандлами приложения, так и между бандлом и главным фреймом.
Активатор UniversalActivatorВ листинге активатора представлены поля и список доступных методов класса. Общие для всех полей модификатор protected «вынесен» в виде комментариев.
public class UniversalActivator implements BundleActivator,
IUniversalCommon,
IWidgetsConstants
{
// protected
// связанный с бандлом контекст
BundleContext context = null;
ServiceTracker<Object,
Object> logServiceTracker = null;
LogService logService = null;
ServiceRegistration<?> service_starttime = null;
ServiceRegistration<?> service_locale = null;
ServiceRegistration<?> service_connect = null;
ServiceRegistration<?> service_container = null;
ServiceRegistration<?> service_guimode = null;
ServiceRegistration<?> service_pnl_req = null;
ServiceRegistration<?> service_pnl_resp = null;
JBPanel jpanel = null;
JBDialog jdialog = null;
String guimode = null;
//-----------------------------------------------------
public void start(final BundleContext context)
throws Exception;
public void stop(final BundleContext context)
throws Exception;
//-----------------------------------------------------
public BundleContext getBundleContext();
//-----------------------------------------------------
protected void closeForm();
//-----------------------------------------------------
protected EventPublisher
createEventPublisher(ServiceReference<?> ref);
//-----------------------------------------------------
protected void createLocaleSubscriber();
public void changeLocale (Locale locale);
//-----------------------------------------------------
protected void createConnectSubscriber();
public void changeConnect();
//-----------------------------------------------------
public void saveComponentParams();
//-----------------------------------------------------
protected void
createJFrameSubscriber(UniversalActivator);
protected void sendContainerRequestEvent();
public void getJFrameResponseContainer (Container);
//-----------------------------------------------------
protected void getGuiMode();
protected void drawGUI(String guimode);
protected void createDialogGUI();
//-----------------------------------------------------
/*
* Методы организации публикации/подписки с главным
* фреймом для получения времени старта приложения
*/
protected void sendStartTimeRequestEvent();
protected void createStartTimeResponseSubscriber
(UniversalActivator);
public void getStartTimeResponseMessage(long time);
public long getStartTime()
//-----------------------------------------------------
/*
* Методы организации публикации/подписки между
* родительским и дочерним бандлами
*/
//-----------------------------------------------------
protected void createGuimodeRequestSubscriber();
public void getGuimodeRequestMessage();
protected void sendGuimodeRequestEvent ();
//-----------------------------------------------------
protected void createGuimodeResponseSubcriber();
public void getGuimodeResponseMessage(String guimd);
protected void sendGuimodeResponseEvent (String guimd);
//-----------------------------------------------------
protected void createPanelRequestSubscriber();
public void getPanelRequestMessage ();
protected void sendPanelRequestEvent ();
//-----------------------------------------------------
protected void createPanelResponseSubscriber();
public void getPanelResponseContainer(Container);
protected void
sendPanelResponseEvent(Container container);
//-----------------------------------------------------
}
start stop getBundleContext closeForm createEventPublisher createLocaleSubscriber createConnectionSubscriber createJFrameSubscriber getGuiMode drawGUI createDialogGUI Методы получения времени старта приложения Методом createStartTimeResponseSubscriber(UniversalActivator) создается подписчик на запрос времени старта приложения, после чего можно отправлять запрос главному фрейму методом sendStartTimeRequestEvent. При поступлении от главного фрейма ответа подписчик вызовет метод getStartTimeResponseMessage(long), которому в качестве параметра передаст время старта приложения в мс. Метод активатора getStartTime() позволяет получить время старта программы в классах формирования интерфейса. createGuimodeRequestSubscriber
// Метод активатора родительского бандла
@Override
public void getGuimodeRequestMessage()
{
super.getGuimodeRequestMessage();
/*
* Метод getGuimode() определяет значение guimode
* для стартуемого (дочернего) бандла
*/
String guimode = getGuimode();
if (guimode.equalsIgnoreCase(GUIMode_jpanel))
// Создание подписчика для запроса панели
createPanelRequestSubscriber();
sendGuimodeResponseEvent (guimode);
}
createGuimodeResponseSubcriber
// Метод активатора дочернего бандла
@Override
public void getGuimodeResponseMessage(final String guimode)
{
super.getGuimodeResponseMessage(null);
if (guimode.equalsIgnoreCase(GUIMode_jdialog))
createDialogGUI();
else
// Отправка сообщения с запросом панели
sendPanelRequestEvent();
}
createPanelRequestSubscriber
// Метод активатора родительского бандла
@Override
public void getPanelRequestMessage()
{
super.getPanelRequestMessage();
Container container = getContainer();
if (container != null)
sendPanelResponseEvent(container);
}
createPanelResponseSubscriber
// Метод активатора дочернего бандла
@Override
public void getPanelResponseContainer(Container container)
{
super.getPanelResponseContainer(null);
if (container != null) {
jpanel = new JPanelForm(this);
((JPanelForm)jpanel).createGUI(container);
}
}
Пимечание : Реализация механизма «публикации/подписки» между родительским и дочерним бандлами на сообщения отправки и получения «Режима представления интерфейса» (guimode) и контейнера родительского бандла с использованием бандла base-universal представлена в примере templ-universal и в описании Урока 14. Класс JBDialogКласс JBDialog наследует свойства класса JBCommon и включает переменную jdialog, определяющую диалоговое окно. Конструктор класса получает в качестве параметра контекст бандла, определяет текущий язык локализации (locale) и создает диалоговое окно. Метод formCentering определяет размер окна и выполняет его центрирование на экране монитора. Методы getWidth() и getHeight() переопределяют абстрактные методы суперкласса; данные методы используются для сохранения регулируемых настроек интерфейса (размера диалогового окна).
public class JBDialog extends JBCommon
{
protected JDialog jdialog = null;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public JBDialog (final BundleContext context)
{
this.context = context;
IResources resources = new ResourcesImpl();
this.locale = resources.getLocale();
jdialog = new JDialog();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Процедура центрирования окна
* @param width размер окна по горизонтали
* @param height размер окна по вертикали
*/
protected void formCentering(final int width,
final int height)
{
// Получение размера экрана
Dimension screenSize = Toolkit.getDefaultToolkit()
.getScreenSize();
int x = (screenSize.width - width ) / 2;
int y = (screenSize.height - height) / 2;
jdialog.setBounds(x, y, width, height);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
protected int getWidth()
{
return jdialog.getWidth();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
protected int getHeight()
{
return jdialog.getHeight();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public JDialog getJDialog()
{
return this.jdialog;
}
}
Класс JBPanelКласс JBPanel наследует свойства класса JBCommon. Конструктор класса в качестве параметра получает контекст бандла и определяет текущий язык локализации (locale). Процедура createPanel в качестве параметра получает контейнер и методом суперкласса createDesk создает неразделяемую панель pnlDesk типа JPanel, которую размещает в контейнере. Супер класс JBCommon имеет метод createSplitDesk(int divider_pos) для создания компонента splitDesk типа JSplitPane с горизонтальным размещением сепаратора (JSplitPane.HORIZONTAL_SPLIT) в позиции divider_pos. При необходимости Вы можете переопределить метод createPanel, чтобы использовать в качестве подложки интерфейса вместо неразделяемой панели pnlDesk разделенную на две части по горизонтали панель splitDesk, либо создать что-то своё. Методы getWidth() и getHeight() переопределяют абстрактные методы суперкласса; данные методы могут быть использованы для сохранения регулируемых настроек интерфейса.
public class JBPanel extends JBCommon
{
public JBPanel (BundleContext context)
{
this.context= context;
IResources resources = new ResourcesImpl();
this.locale = resources.getLocale();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Метод создания интерфейса рабочей области панели
* @param container контейнер
*/
protected void createPanel(Container container)
{
// Создание интерфейсной панели
this.createDesk();
pnlDesk.setLayout(new BorderLayout());
// Размещение панели в контейнере
container.add(pnlDesk);
container.doLayout();
pnlDesk.doLayout();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public JPanel getJPanel()
{
return this.pnlDesk;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
protected int getWidth()
{
if (pnlDesk != null)
return pnlDesk.getWidth();
else if (splitDesk != null)
return splitDesk.getWidth();
else
return 0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
protected int getHeight()
{
if (pnlDesk != null)
return pnlDesk.getHeight();
else if (splitDesk != null)
return splitDesk.getHeight();
else
return 0;
}
}
Класс JBCommonВ таблице представлены поля (переменные) и методы класса JBCommon, свойства которого наследуют интерфейсные классы JBDialog и JBPanel. Абстрактный класс JBCommon включает два абстрактных метода, которые используются при сохранении регулируемых настроек диалогового окна. Группа методов, связанная с сохранениями регулируемых настроек интерфейса (размер окна, положение сепаратора, размеры колонок таблиц), может быть также использована для сохранения и восстановления измененных значений в визуальных компонентах формы. Для этого следует переопределить методы writeDocument(document, path) и readDocument (fname). Версия модуля 1.0.1 дополнена методами обработки XML-документов, связанных с чтением файла с сохраняемыми регулируемыми настройками интерфейса; в содержимое файла (документа) можно включить дополнительную информацию.
Класс ComponentParamsComponentParams используется для описания изменяемых параметров (размер, положение) объектов типа JSplitPane, JTable. В листинге класса методы get/set не представлены.
public class ComponentParams
{
private String clazz ;
private String name ;
private int location;
private String columns ;
private String value ;
private String checked ;
private int selected;
private int tab ;
public ComponentParams() {}
public ComponentParams(String clazz, String name) {
this.clazz = clazz;
this.name = name;
}
// Методы get/set
...
}
Класс ReferenceReference следует использовать в качестве объекта при формировании набора данных для компонентов типа JComboBox. В листинге класса методы get/set не представлены.
public class Reference
{
private int id ;
private String name ;
public Класс Reference() {}
public Reference(int id, String name)
{
this.id = id;
this.name = name;
}
// Методы get/set
...
}
ЗависимостиБазовый модуль base-universal функционирует вместе со следующими бандлами приложения JaBricks :
Кроме данных бандлов платформы JaBricks модуль base-universal имеет следующие зависимости, загружаемые фреймворком при старте приложения :
Подключение модуля base-universalДля подключения модуля base-universal в приложение JaBricks необходимо :
GAV параметры модуля base-universal имеют следующие значения :
Подробнее о включении модуля в приложение Jabricks представлено здесь. Скачать base-universalРассмотренный на странице базовый модуль разработки интерфейса base-universal версии 1.0.0 упакован в архивный файл base-universal-1.0.0.zip (32.0 Кб); версия 1.0.1 упакована в архивный файл base-universal-1.0.1.zip (31.7 Кб). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
