T.M. SoftStudio

feci quod potui, faciant meliora potentes

Купить полную версию книги "Среда разработки Eclipse 4: Руководство разработчика"



Создание RCP-приложений

Создание Eclipse 4 RCP-приложения

Создание Part-части

Откроем среду Eclipse с установленным плагином Eclipse 4 core tools.

В меню File выберем мастер New | Other | Eclipse 4 | Eclipse 4 Application Project, нажмем кнопку Next, введем имя проекта, нажмем кнопку Next | Next, отметим флажок Create sample content и нажмем кнопку Finish.

Во вкладке Form редактора файла Application.e4xmi модели приложения раскроем узел Application | Windows | Trimmed Window | Controls и увидим иерархию элементов Perspective Stack | Perspective | Controls | PartSashContainer | Part Stack | Part.

Элемент Perspective Stack представляет собой контейнер для перспектив, представленных элементами Perspective, которые также являются контейнерами и предназначены для компоновки частей – редакторов и представлений в рабочие области для различных целей использования.

Переключение между перспективами

Переключение между перспективами приложения осуществляется программным способом с помощью сервисов среды выполнения, представленных объектами org.eclipse.e4.ui.workbench.modeling.EModelService и org.eclipse.e4.ui.workbench.modeling.EPartService.

Сервис EModelService обеспечивает поиск перспективы по идентификатору соответствующего элемента модели приложения, а сервис EPartService обеспечивает переключение на найденную перспективу.

Во вкладке Form редактора файла Application.e4xmi модели приложения нажмем правой кнопкой мышки на узле Application | Windows | Trimmed Window | Controls| Perspective Stack и командой Add child | Perspective добавим перспективу.

Нажмем правой кнопкой мышки на узле Application | Windows | Trimmed Window | Main Menu и командой Add child | Menu добавим меню Open Perspective.

Нажмем правой кнопкой мышки на узле нового меню и командой Add child | DirectMenuItem добавим элемент меню.

В свойствах элемента DirectMenuItem нажмем на ссылку Class URI и создадим обработчик элемента меню со следующим кодом:

import org.eclipse.e4.core.di.annotations.Execute;

import org.eclipse.e4.ui.model.application.MApplication;

import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;

import org.eclipse.e4.ui.workbench.modeling.EModelService;

import org.eclipse.e4.ui.workbench.modeling.EPartService;

public class OpenHandler {

@Execute

public void execute(MApplication app, EPartService partService, EModelService modelService) {

MPerspective element = (MPerspective) modelService.find("e4rcp.perspective.0", app);

partService.switchPerspective(element);

}}

Теперь при выборе элемента меню будет происходить переключение на перспективу с идентификатором e4rcp.perspective.0.

PartSashContainer и Part Stack

Элемент PartSashContainer является контейнером, обеспечивающим компоновку контейнеров или частей вертикально или горизонтально.

Поле Container Data свойств дочерних элементов элемента PartSashContainer позволяет распределить свободное пространство контейнера между дочерними элементами согласно их веса.

Например, если контейнер PartSashContainer содержит два стека Part Stack, тогда стек со значением 90 поля Container Data займет 90 % пространства PartSashContainer-контейнера, а стек со значением 10 поля Container Data займет 10 % пространства PartSashContainer-контейнера.

Элемент Part Stack является контейнером, обеспечивающим отображение Part-частей в виде вкладок.

Part

Каждая Part-часть может быть реализована в виде View-представления, обеспечивающего отображение и управление иерархией элементов, или в виде Editor-редактора, обеспечивающего отображение и редактирование данных, связанных с элементами представления.

Щелкнем два раза левой кнопкой мышки на узле элемента Part и в правой части редактора Eclipse 4 model editor увидим свойства элемента Part.

Поле Label позволяет определить заголовок вкладки части.

Поле Tooltip позволяет задать всплывающую подсказку при наведении курсора мышки на вкладку неактивной части.

Поле Icon URI позволяет определить значок заголовка части.

Нажмем кнопку Find поля Icon URI и в появившемся диалоговом окне в поле IconName введем звездочку *. Выберем изображение, расположенное в папке icons проекта и нажмем кнопку OK.

Поле Class URI связывает элемент модели приложения с классом проекта. Мастер создания класса Part-части можно открыть, нажав на ссылку Class URI, или выбрав команду New | Other | Eclipse 4 | Classes | New Part Class меню File среды Eclipse.

Флажки PostContruct Method, Predestroy Method, Focus Method и Persist Method мастера создания класса Part-части позволяют задать генерацию методов класса, маркированных аннотациями javax.annotation.PostConstruct, javax.annotation.PreDestroy, org.eclipse.e4.ui.di.Focus и org.eclipse.e4.ui.di.Persist.

Аннотация @PostConstruct маркирует метод, вызываемый средой выполнения после создания объекта класса для наполнения содержимым Part-части.

Для наполнения содержимым Part-части можно воспользоваться плагином WindowBuilder (см. Графические системы SWT и JFace).

После установки плагина WindowBuilder файл класса Part-части можно открыть в редакторе WindowBuilder Editor с помощью команды Open With | WindowBuilder Editor контекстного меню представления Package Explorer.

Вкладка Design редактора WindowBuilder Editor обеспечивает визуальное редактирование содержимого Part-части. При этом изменяет код метода, промаркированного аннотацией @PostConstruct.

Аннотация @PreDestroy маркирует метод, вызываемый средой выполнения перед уничтожением объекта класса для освобождения ресурсов.

Аннотация @Focus маркирует метод, вызываемый средой выполнения при получении фокуса Part-частью.

В методе с аннотацией @Focus как правило определяется элемент Part-части, получающий фокус, например, текстовое поле:

@Focus

public void onFocus() {

text.setFocus();

}

Аннотация @Persist маркирует метод, вызываемый средой выполнения при вызове обработчика, используемого для сохранения изменений содержимого части.

Добавим код в метод с аннотацией @Persist:

@Persist

public void save(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell) {

MessageBox dialog = new MessageBox(shell, SWT.OK| SWT.CANCEL);

dialog.setMessage("Do you want to save this part?");

dialog.open();

}

Интерфейс org.eclipse.e4.ui.model.application.ui.basic.MPart, представляющий элемент Part-часть модели приложения, имеет суперинтерфейс org.eclipse.e4.ui.model.application.ui.MDirtyable.

Интерфейс MDirtyable обеспечивает два состояния Part-части – сохраненное состояние и измененное, но не сохраненное состояние.

Эти состояния используются для Part-части, реализованной в виде Editor-редактора.

Перевод из одного состояния в другое обеспечивает метод setDirty(boolean value) интерфейса MDirtyable. При этом если передается флаг true, тогда в заголовке Part-части отображается звездочка, указывающая на необходимость сохранения содержимого части.

Мастер создания класса Part-части автоматически генерирует конструктор класса, промаркированный аннотацией javax.inject.Inject, позволяющей внедрять объекты, доступные для среды выполнения.

Поэтому используем в конструкторе Part-класса объект MDirtyable:

private MDirtyable dirtyable;

@Inject

public ViewPart(MDirtyable dirtyable) {

this.dirtyable = dirtyable;

}

В методе с аннотацией @PostConstruct добавим к текстовому полю слушателя его изменений, в котором будем изменять MDirtyable-состояние Part-части:

private Text text;

@PostConstruct

public void postConstruct(Composite parent) {

parent.setLayout(new RowLayout(SWT.HORIZONTAL));

text = new Text(parent, SWT.BORDER);

text.addModifyListener(new ModifyListener(){

@Override

public void modifyText(ModifyEvent e) {

dirtyable.setDirty(true);

}

});

}

Флажок Toolbar свойств элемента Part правой части редактора Eclipse 4 model editor позволяет добавить панель инструментов для Part-части, отображаемую в той же области, что и заголовок части.

Отметим флажок Toolbar и в узле Part | Toolbar добавим дочерний элемент Direct Tool Item.

В свойствах элемента Direct Tool Item в поле Label введем Save, в поле Icon URI нажмем кнопку Find и выберем значок platform:/plugin/E4RCP/icons/save_edit.gif, нажмем ссылку Class URI и создадим обработчик со следующим кодом:

import javax.inject.Named;

import org.eclipse.e4.core.di.annotations.Execute;

import org.eclipse.e4.core.di.annotations.CanExecute;

import org.eclipse.e4.ui.model.application.ui.MDirtyable;

import org.eclipse.e4.ui.services.IServiceConstants;

import org.eclipse.e4.ui.workbench.modeling.EPartService;

import org.eclipse.e4.ui.model.application.ui.basic.MPart;

public class SavePartHandler {

@Execute

public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part, EPartService partService) {

partService.savePart(part, false);

}

@CanExecute

public boolean canExecute(

@Named(IServiceConstants.ACTIVE_PART) MDirtyable dirtyable) {

if (dirtyable == null) {

return false;

}

return dirtyable.isDirty();

}}

Здесь в методе с аннотацией @CanExecute проверяется MDirtyable-состояние Part-части и если оно требует сохранения содержимого, тогда вызывается метод с аннотацией @Execute, в котором вызов метода savePart() инициирует вызов метода с аннотацией @Persist.

Редактор файла Application.e4xmi модели приложения позволяет создавать помимо элемента Part элемент Input Part, дополнительно определяющий адрес Input URI объекта ввода данных.

Первоначально предполагалось, что элемент Input Part будет представлять реализацию Part-части в виде Editor-редактора. Однако реализовать Editor-редактор позволяет и обычный элемент Part с использованием аннотации @Persist, метода savePart() сервиса EPartService и интерфейса MDirtyable.

Флажок Closable свойств элемента Part правой части редактора Eclipse 4 model editor позволяет добавить в заголовок Part-части кнопку закрытия вкладки части (рис. 7.21).

Рис. 7.21. Кнопка закрытия части

Для повторного открытия части добавим в узел Application | Windows | Trimmed Window | Main Menu элемент Menu | DirectMenuItem с обработчиком (листинг 7.1).

Листинг 7.1. Обработчик повторного открытия Part-части

import org.eclipse.e4.core.di.annotations.Execute;

import org.eclipse.e4.ui.model.application.ui.basic.MPart;

import org.eclipse.e4.ui.workbench.modeling.EPartService;

import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;

public class OpenHandler {

@Execute

public void execute(EPartService partService) {

MPart part = partService.findPart("e4rcp.part.0");

part.setVisible(true);

partService.showPart(part, PartState.VISIBLE);

}}

Binding Contexts

Раздел Binding Contexts свойств элемента Part правой части редактора Eclipse 4 model editor позволяет добавить горячие клавиши, работающие только при активной Part-части.

В узел Application | Binding Contexts добавим дочерний элемент Binding Context с именем Active Part.

В узел Application | Binding Tables добавим дочерний элемент Binding Table. В поле Context Id элемента Binding Table кнопкой Find выберем созданный элемент Binding Context с именем Active Part.

В узел Application | Commands добавим дочерний элемент Command с именем openpartCommand.

В узел Application | Binding Tables | Binding Table добавим дочерний элемент KeyBinding. В поле Sequence элемента KeyBinding введем горячие клавиши M1+P (Ctrl+P), в поле Command кнопкой Find выберем созданный элемент Command с именем openpartCommand.

В узел Application | Handlers добавим дочерний элемент Handler, в поле Command которого кнопкой Find выберем созданный элемент Command с именем openpartCommand, а в поле Class URI добавим обработчик открытия Part-части (листинг 7.1).

В узел Application | Windows | Trimmed Window | Main Menu добавим элемент Menu | HandledMenuItem, в поле Command которого кнопкой Find выберем созданный элемент Command с именем openpartCommand.

В разделе Binding Contexts свойств элемента Part кнопкой Add добавим элемент Binding Context с именем Active Part.

Теперь при открытой Part-части набор горячих клавиш Ctrl+P вызовет активацию команды повторного открытия другой Part-части.

Persisted State

Раздел Persisted State свойств элемента Part правой части редактора Eclipse 4 model editor позволяет добавить сохраняемые свойства в виде пар ключ-значение, доступные с помощью метода getPersistedState() объекта MPart.

С помощью кнопки Add раздела Persisted State свойств элемента Part добавим свойства части, а в класс обработчика повторного открытия части добавим код:

import java.util.Map;

import javax.inject.Named;

import org.eclipse.e4.core.di.annotations.Execute;

import org.eclipse.e4.ui.model.application.ui.basic.MPart;

import org.eclipse.e4.ui.services.IServiceConstants;

import org.eclipse.e4.ui.workbench.modeling.EPartService;

import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;

import org.eclipse.swt.SWT;

import org.eclipse.swt.widgets.MessageBox;

import org.eclipse.swt.widgets.Shell;

public class OpenHandler {

@Execute

public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell, EPartService partService) {

MPart part = partService.findPart("e4rcp.part.0");

part.setVisible(true);

partService.showPart(part, PartState.VISIBLE);

MessageBox dialog = new MessageBox(shell, SWT.OK| SWT.CANCEL);

Map<String,String> map=part.getPersistedState();

String message="";

for (Map.Entry<String, String> entry : map.entrySet()) {

message=message+" "+entry.getKey() + " : " + entry.getValue();

}

dialog.setMessage(message);

dialog.open();

}}

Context Properties

Раздел Context Properties свойств элемента Part правой части редактора Eclipse 4 model editor позволяет добавить для Part-части свойства контекста IEclipseContext, доступные с помощью метода getContext().get("property") объекта MPart или с помощью аннотации @Named("property") String property для объекта MPart.

С помощью кнопки Add раздела Context Properties свойств элемента Part добавим свойства контекста, а в класс обработчика повторного открытия части добавим код:

import javax.inject.Named;

import org.eclipse.e4.core.di.annotations.Execute;

import org.eclipse.e4.ui.model.application.ui.basic.MPart;

import org.eclipse.e4.ui.services.IServiceConstants;

import org.eclipse.e4.ui.workbench.modeling.EPartService;

import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;

import org.eclipse.swt.SWT;

import org.eclipse.swt.widgets.MessageBox;

import org.eclipse.swt.widgets.Shell;

public class OpenHandler {

@Execute

public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell, EPartService partService) {

MPart part = partService.findPart("e4rcp.part.0");

part.setVisible(true);

partService.showPart(part, PartState.VISIBLE);

MessageBox dialog = new MessageBox(shell, SWT.OK| SWT.CANCEL);

String message = (String)part.getContext().get("property");

dialog.setMessage(message);

dialog.open();

}}

В метод с аннотацией @PostConstruct класса ViewPart добавим код:

@PostConstruct

public void postConstruct(Composite parent, @Named("property") String property) {

parent.setLayout(new RowLayout(SWT.HORIZONTAL));

text = new Text(parent, SWT.BORDER);

text.setText(property);

text.addModifyListener(new ModifyListener(){

@Override

public void modifyText(ModifyEvent e) {

dirtyable.setDirty(true);

}});}

Вкладка Supplementary редактора Eclipse 4 model editor позволяет добавлять тэги, а также переменные контекста для Part-части.

Переменные контекста

Переменные контекста обеспечивают механизм обмена данными между дочерними объектами компонента, в контексте которого переменные определены.

Во вкладке Supplementary свойств элемента Part правой части редактора Eclipse 4 model editor в поле Variables введем имя переменной и нажмем кнопку Add.

В конструкторе класса ViewPart определим значение переменной:

@Inject

public ViewPart(IEclipseContext context) {

context.set("my_variable", "string");

}

В обработчике элемента меню Part-части используем переменную контекста:

@Execute

public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell, @Named("my_variable") String value) {

MessageBox dialog = new MessageBox(shell, SWT.OK| SWT.CANCEL);

dialog.setMessage(value);

dialog.open();

}

Тэги элементов модели

Тэги элементов модели приложения обеспечивают дополнительную информацию, которая используется средой выполнения при визуализации GUI-компонентов.

В частности для Part-части предопределен тэг NoMove, запрещающий перетаскивание части мышкой (см. Добавление Addon-компонента).

Создание Part-части динамически

Создание Part-части динамически, программным способом, возможно с помощью дескриптора Part Descriptor, определенного в файле Application.e4xmi или созданного с использованием фабрики org.eclipse.e4.ui.model.application.descriptor.basic.MBasicFactory.

Чтобы использовать дескриптор Part Descriptor во вкладке Form редактора файла Application.e4xmi модели приложения нажмем правой кнопкой мышки на узле Application | Part Descriptors и командой Add child | Descriptor добавим элемент PartDescriptor.

В поле Label свойств элемента PartDescriptor введем заголовок части, в поле Class URI кнопкой Find добавим класс части, например, bundleclass://E4RCP/E4RCP.parts.SamplePart.

Нажмем правой кнопкой мышки на узле Application | Windows | Trimmed Window | Main Menu и командой Add child | Menu добавим меню Create Part.

Нажмем правой кнопкой мышки на узле нового меню и командой Add child | DirectMenuItem добавим элемент меню.

В свойствах элемента DirectMenuItem нажмем на ссылку Class URI и создадим обработчик элемента меню со следующим кодом:

import org.eclipse.e4.core.di.annotations.Execute;

import org.eclipse.e4.ui.model.application.MApplication;

import org.eclipse.e4.ui.model.application.ui.basic.MPart;

import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;

import org.eclipse.e4.ui.workbench.modeling.EModelService;

import org.eclipse.e4.ui.workbench.modeling.EPartService;

import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;

public class CreateHandler {

@Execute

public void execute(EPartService partService, MApplication application, EModelService modelService) {

MPart part=partService.createPart("e4rcp.partdescriptor.0");

MPartStack stack=(MPartStack)modelService.find("e4rcp.partstack.0", application);

stack.getChildren().add(part);

partService.showPart(part, PartState.ACTIVATE);

}}

Теперь при выборе элемента меню, на основе дескриптора, сервис EPartService создаст объект MPart, представляющий Part-часть, которая будет добавлена в существующий стек частей.

Фабрика MBasicFactory позволяет создать дескриптор части программным способом:

import org.eclipse.e4.core.di.annotations.Execute;

import org.eclipse.e4.ui.model.application.MApplication;

import org.eclipse.e4.ui.model.application.descriptor.basic.MBasicFactory;

import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;

import org.eclipse.e4.ui.model.application.ui.basic.MPart;

import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;

import org.eclipse.e4.ui.workbench.modeling.EModelService;

import org.eclipse.e4.ui.workbench.modeling.EPartService;

import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;

public class CreateHandler {

@Execute

public void execute(EPartService partService, MApplication application, EModelService modelService) {

MPartDescriptor descriptor = MBasicFactory.INSTANCE.createPartDescriptor();

descriptor.setLabel("New Part");

descriptor.setContributionURI("bundleclass://E4RCP/E4RCP.parts.SamplePart");

descriptor.setElementId("e4rcp.partdescriptor.0");

MPart part=partService.createPart("e4rcp.partdescriptor.0");

MPartStack stack=(MPartStack)modelService.find("e4rcp.partstack.0", application);

stack.getChildren().add(part);

partService.showPart(part, PartState.ACTIVATE);

}}

Создать Part-часть динамически также можно с помощью фабрики org.eclipse.e4.ui.model.application.ui.basic.MBasicFactory:

import java.util.List;

import org.eclipse.e4.core.di.annotations.Execute;

import org.eclipse.e4.ui.model.application.MApplication;

import org.eclipse.e4.ui.model.application.ui.basic.MBasicFactory;

import org.eclipse.e4.ui.model.application.ui.basic.MPart;

import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;

import org.eclipse.e4.ui.workbench.modeling.EModelService;

import org.eclipse.e4.ui.workbench.modeling.EPartService;

import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;

public class CreateHandler {

@Execute

public void execute(EPartService partService, MApplication application, EModelService modelService) {

MPart part = MBasicFactory.INSTANCE.createPart();

part.setLabel("New Part");

part.setContributionURI("bundleclass://E4RCP/E4RCP.parts.SamplePart");

// List<MPartStack> stacks = modelService.findElements(application, null, MPartStack.class, null);

// stacks.get(0).getChildren().add(part);

MPartStack stack=(MPartStack)modelService.find("e4rcp.partstack.0", application);

stack.getChildren().add(part);

partService.showPart(part, PartState.ACTIVATE);

}}


Создание Eclipse 4 RCP-приложения. Тэги модели приложения