Настройка и добавление пунктов меню в Eclipse V3.3

Применение нового механизма меню версии 3.3 для ускорения разработки плагинов и RCP

В ранних версиях Eclipse добавить команды в меню, всплывающие меню или на панель инструментов было трудно. Теперь это не так! В версии Eclipse V3.3 появился простой механизм для этого. Из этой статьи вы узнаете, как использовать точку расширения org.eclipse.ui.menus.

Карстен Войт, ИТ-архитектор, IBM  

Карстен Войт (Karsten Voigt) работает ИТ-архитектором и консультантом IBM Global Business Services в Германии. Он имеет дело главным образом с заказчиками IBM из автомобильной промышленности и специализируется на создании интегрированных решений на базе rich-client приложений J2EE и Java, включая Lotus Expeditor. В свободное время Карстен проектирует, разрабатывает и применяет приложения на базе Java Swing и Eclipse Rich Client Platform.



26.10.2009

Меню, всплывающие меню и панели инструментов — элементы, без которых не обходится почти ни один плагин и ни одно приложение Eclipse Rich Client Platform (RCP). В Eclipse V3.3 появилась функция, которая упрощает процесс настройки и добавления пунктов меню. В этой статье показано, как использовать новый механизм меню для ускорения разработки плагинов и RCP.

В Eclipse V3.2 и более ранних версиях, чтобы добавить команды в меню, всплывающее меню или на панель инструментов, приходилось использовать несколько точек расширения. На самом деле их было четыре: org.eclipse.ui.actionSets, org.eclipse.ui.viewActions, org.eclipse.ui.editorActions и org.eclipse.ui.popupMenus. К сожалению, для добавления команды каждого вида требовалась отдельная точка расширения, а выполнение действия и представление данных нельзя было разделить.

В Eclipse V3.3 появился новый механизм: org.eclipse.ui.menus. Эта точка расширения – дает новый способ размещения пунктов меню.

В настоящей статье объясняются новые концепции меню и приводятся шаги по созданию небольшого приложения Eclipse RCP для демонстрации большинства новых возможностей. Нужно иметь некоторые базовые знания по использованию Eclipse RCP и структуре плагинов. На первом шаге загрузим с сайта Eclipse.org дистрибутив Eclipse со средой разработки плагинов Plug-in Development Environment (PDE) . Я рекомендую загрузить последнюю версию Eclipse Classic (чтобы узнать, где найти Eclipse, и получить дополнительную информацию для начинающих, обращайтесь к разделу Ресурсы.)

Структура команд

Прежде чем приступить к созданию плагина с применением нового механизма, нужно освоить структуру команд. Команда – это декларативное описание компонента, не зависящее от деталей реализации. Команда может относиться к той или иной категории, и ей может быть назначено сочетание клавиш. Такой подход позволяет определить типовую привязку клавиш и выбирать специфическую реализацию в зависимости от текущего контекста. Упрощенная схема классов команд приведена на рисунке 1.

Рисунок 1. Схема классов команд
Схема классов команд

Для определения команд используется точка расширения org.eclipse.ui.commands. Команды можно создавать и программно — при помощи интерфейса ICommandService. Для обработки команды можно использовать несколько обработчиков, но конкретной реализацией времени выполнения управляет только один. Для интеграции в рабочее пространство Eclipse командам можно присваивать изображения, пункты меню и назначения клавиш. Полезно группировать команды с применением категорий. Это упрощает навигацию в сложных приложениях rich-client.


Добавление пункта меню

Начнем с добавления пунктов меню. Для примера создадим небольшое приложение RCP с одним пунктом меню, который просто открывает диалоговое окно. Этот небольшой пример иллюстрирует основные принципы использования команд, обработчиков и меню.

Создадим новый проект разработки плагина MenuContribution и установим версию Eclipse в 3.3. На вопрос "Would you like to create a rich client application?" (Создать приложение rich client?) нужно ответить Yes. Воспользуемся шаблоном Hello RCP. Этот пример основан на пакете с именем com.ibm.de.eclipse.menu. Все остальные параметры можно оставить по умолчанию. Теперь выполните новый проект как Eclipse Application, и вы увидите следующее окно.

Рисунок 2. Пример Hello RCP
Пример Hello RCP

На этом приложении мы объясним разные способы добавления пунктов меню. Откройте plugin.xml, перейдите в Extensions и добавьте расширение org.eclipse.ui.commands. Так как все команды должны быть сгруппированы в категорию, выберите расширение команд и создайте новую категорию, щелкнув правой кнопкой на New > category. Заполните поля категории, как показано на рисунке 3.

Рисунок 3. Детали категории команд
Детали категории команд

Теперь добавьте команду внутри расширения, щелкнув правой кнопкой на New > command. Установите ID в значение com.ibm.de.eclipse.menu.command.testCmd, назовите его Test Command и установите значение categoryId равным com.ibm.de.eclipse.menu.command.cat1. Для исполнения логики этой команды нужен обработчик. Добавьте точку расширения org.eclipse.ui.handlers и создайте новый обработчик. Идентификатором commandId для этого обработчика будет com.ibm.de.eclipse.menu.command.testCmd. Чтобы создать класс обработчика, нажмите на ссылку класса, как показано на рисунке 4. На рисунке 5 представлен мастер с нужными значениями параметров.

Совет: Если вы указываете ссылку на класс в нескольких расширениях, создайте новый класс, содержащий необходимые интерфейсы для выбранной точки расширения.

Рисунок 4. Ссылка на новый класс обработчика
Ссылка на новый класс обработчиков
Рисунок 5. Мастер
Мастер

Обработчик должен реализовать метод execute. Добавьте строки из листинга 1, чтобы вывести окно сообщения.

Листинг 1. Обработчик метода execute
public Object execute(ExecutionEvent event) throws ExecutionException {
	IWorkbenchWindow window = 
HandlerUtil.getActiveWorkbenchWindowChecked(event);
	MessageDialog.openInformation(
		window.getShell(), "MenuEclipseArticle Plug-in",
		"Hello, Eclipse world");
	return null;
}

Сохраните класс, вернитесь к plugin.xml и сохраните этот файл. Теперь создадим пункт меню для новой команды и обработчика. Добавьте расширение org.eclipse.ui.menus и создайте новый элемент menuContribution. Пункт меню имеет только одно свойство locationURI. Оно определяет точку вставки, в которую будут добавлены дополнения. Используйте menu:org.eclipse.ui.main.menu в качестве locationURI. Этот URI определяет меню, размещенное в стандартном меню Eclipse.

Пока мы определили только точку вставки. Чтобы добавить конкретное меню, выберите пункт меню и создайте новое меню. Установите метку TestMenu и используйте ID com.ibm.de.eclipse.menu.test.

Наконец, определим связь между пунктом меню и подготовленной командой. Щелкните на TestMenu и добавьте новую команду. Установите commandId в com.ibm.de.eclipse.menu.command.testCmd и укажите метку Do something (сделать что-то). Расширения для вашего plugin.xml должны выглядеть, как показано на рисунке 6. Перед исполнением приложения Eclipse откройте класс ApplicationWorkbenchWindowAdvisor, перейдите в метод preWindowOpen и добавьте строку configurer.setShowMenuBar(true);. Выполните приложение Eclipse и проверьте свой новый пункт меню.

Рисунок 6. Обзор всех расширений
Обзор всех расширений

URI расположения меню

В предыдущем примере мы определили locationURI для меню, который добавляет пункт меню прямо на панель меню приложений, но locationURI поддерживает и другие способы вставки пунктов меню. Точки вставки меню описываются следующей схемой: <scheme>:<menu-id>[?<placement-modifier>].

<scheme> menu
Добавление пункта в главное меню или меню View. Значение <menu-id> должно указывать на существующий идентификатор представления или на стандартное меню Eclipse org.eclipse.ui.main.menu. Значение <placement-modifier> позволяет выбирать положение строк меню по схеме <placement>=<id>. Для размещений могут использоваться предваряющие или замыкающие теги, а <id> может быть существующим именем разделителя, идентификатором меню или идентификатором пункта меню.
Совет: Класс MenuUtil содержит некоторые стандартные значения констант для URI меню.
<scheme> toolbar
Добавление команды на любую панель инструментов. Значение <menu-id> для этой схемы может указывать на любой идентификатор представления (для представлений панелей инструментов), org.eclipse.ui.main.toolbar или любой идентификатор панели инструментов, входящей в главную панель инструментов. Можно также использовать <placement-modifier>.
<scheme> pop-up
Добавление меню для зарегистрированных идентификаторов контекста и org.eclipse.ui.popup.any для всех зарегистрированных меню контекста. Можно использовать также <placement-modifier>.

Теперь давайте расширим наш короткий пример и используем другие методы добавления команд меню.


Добавление представления и команды вызова представления

Добавим в свое приложение представление с кнопкой вызова на панели инструментов. Для этого заменим текущее действие главного меню на открытие представления.

Сначала добавьте точку расширения представления (org.eclipse.ui.views) и создайте новое представление с применением свойств, показанных на рисунке 7. Затем откройте TestHandler и замените текущий метод на открытие представления.

Листинг 2. Замена текущего метода на открытие представления
public Object execute(ExecutionEvent event) throws ExecutionException {
	try {
	HandlerUtil.getActiveWorkbenchWindow(event)
.getActivePage()
.showView("com.ibm.de.eclipse.menu.view.testview");
	} catch (PartInitException e) {
		throw new ExecutionException("Error while opening view", e);
	}
	return null;
}
Рисунок 7. Создание деталей элемента представления
Create view element details

Для этого представления нам нужны новая команда и обработчик для добавления предлагаемых дополнений. Создайте новую команду и новый обработчик. Используйте следующие свойства; обработчик должен иметь расширение org.eclipse.core.commands.AbstractHandler. При помощи листинга 1 заполните содержимое метода исполнения обработчика.

Таблица 1. Добавление новой команды и обработчика
Команда или обработчикОписаниеСвойство
Commandидентификаторcom.ibm.de.eclipse.menu.command.viewCmd
имякоманда View
описаниеПример команды view
categoryIdcom.ibm.de.eclipse.menu.command.cat1
HandlercommandIdcom.ibm.de.eclipse.menu.command.viewCmd
классcom.ibm.de.eclipse.menu.handler.ViewHandler

Теперь добавим два пункта меню. Сначала добавьте menuContribution (для панели меню представлений) с URI menu:com.ibm.de.eclipse.menu.view.testview. ID представления должен быть <menu-id>. Добавьте прямо в меню команду с идентификатором commandId: com.ibm.de.eclipse.menu.command.viewCmd и меткой Do something. Так как нам не нужна структура подменю, меню для этого пункта меню не требуется. Добавьте также menuContribution для панели инструментов и используйте URI toolbar:com.ibm.de.eclipse.menu.view.testview. Для панели инструментов укажите ту же команду, но здесь также нужно выбрать значок. Используйте любой из значков плагинов по умолчанию (например, icons/alt_window_16.gif). Запустите приложение, выполните команду главного меню и посмотрите на открывшееся окно. Представление должно содержать панель инструментов и меню с предложенными командами.

Рисунок 8. Пример представления с панелью инструментов и пунктом меню
Пример представления с панелью инструментов и пункта меню

Добавление меню, всплывающего по условию

Наконец, нужно добавить в наш пример приложения пункт меню, всплывающий по условию. Сначала в представление добавляется список элементов. Для этих элементов будет показываться контекстное меню. Откройте класс TestView и измените метод createPartControl.

Листинг 3. Добавление списка и контекстного меню в TestView
public void createPartControl(Composite parent) {
	ListViewer lViewer = new ListViewer(new List(parent, SWT.MULTI));
	lViewer.setContentProvider(new ArrayContentProvider());
	lViewer.setInput(new String[] { "1", "2", "3", "4" });
		
	MenuManager menuMgr = new MenuManager();
	menuMgr.add(
new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
	getSite().registerContextMenu(menuMgr, lViewer);
		
	Control control = lViewer.getControl();
	Menu menu = menuMgr.createContextMenu(control);
	control.setMenu(menu);		
}

Стандартный ArrayContentProvider создает ListViewer и показывает только набор параметров. Для этого списка создается MenuManager, и с использованием нового GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS) добавляется весь контент, определенный в plugin.xml. Контекстное меню регистрируется на сайте и добавляется к элементу управления ListViewer.

Добавьте в plugin.xml всплывающее меню и оператор условного перехода. Контекстное меню должно отображаться только в том случае, если мы выбрали два элемента из списка. Так как это условие может оказаться полезным в нескольких местах плагина, мы используем расширение org.eclipse.core.expressions.definitions, чтобы определить общее правило. Это расширение – часть плагина org.eclipse.core.expression, которая должна добавляться по требованию плагина. Перейдите к разделу зависимостей plugin.xml и добавьте этот плагин. Вернитесь в раздел расширения и добавьте org.eclipse.core.expressions.definitions. Присвойте вновь созданному определению идентификатор twoSelectedCheck. Если при добавлении расширения определение не было создано, создайте его. Для этого определения добавьте элемент with и установите значение переменной activeMenuSelection. Элемент with определяет имя переменной, используемой для этой проверки. Если переменная не может быть определена, при оценке правила будет выведено сообщение ExpressionException.

В Eclipse определено несколько стандартных переменных. Полный список имеющихся переменных можно найти в определении для Command Core Expressions в Wikipedia (см. Ресурсы). В данном примере воспользуемся activeMenuSelection. Эта переменная предоставляет выбор при отображении контекстного меню. Теперь добавьте к элементу счетчик и установите значение 2. Определено правило, которое подсчитывает активно выбранные элементы и выдает значение «истинно», если выбраны два элемента. Plugin.xml для этого определения должен выглядеть как в листинге 4.

Листинг 4. Расширение определения в plugin.xml
<extension point="org.eclipse.core.expressions.definitions">
<definition id="twoSelectedCheck">
         <with variable="activeMenuSelection">
            <count value="2"></count>
         </with>
      </definition>
</extension>

Создав определение, добавим новый пункт меню. Перейдите в точку расширения org.eclipse.ui.menus и добавьте меню с всплывающим окном locationURI: org.eclipse.ui.popup.any. Добавьте также команду commandIdcom.ibm.de.eclipse.menu.command.viewCmd для этого меню. До сих пор контекстное меню отображалось всегда. Чтобы изменить это поведение, добавьте к команде элемент visibleWhen. Затем добавьте к элементу visibleWhen элемент reference с definitionId twoSelectedCheck. Наконец, протестируйте приложение. Теперь TestView содержит список элементов. Если выбраны два элемента, мы увидим контекстное меню.

Использование элемента visibleWhen в файле конфигурации плагина — отличный способ ограничить видимость пунктов меню при проектировании или во время исполнения. Продемонстрируем эту возможность на нашем примере, расширив его с добавлением еще одного определения правила. В TestView появилось дополнительное текстовое поле, и команда на панели инструментов доступна только в том случае, когда текстовое поле находится в фокусе. Сначала добавьте в TestView код из листинга 5. Мы используем IFocusService для регистрации текстового поля таким образом, чтобы приложение могло управлять изменениями фокуса для текстового поля.

Листинг 5. TestView с текстовым полем, зарегистрированным в IFocusService
public void createPartControl(Composite parent) {
	parent.setLayout(new FillLayout(SWT.VERTICAL));
		
	Text text = new Text(parent, SWT.BORDER);
		
	IFocusService focusService = 
(IFocusService) PlatformUI.getWorkbench()
.getService(IFocusService.class);
	focusService.addFocusTracker(text, "textControlId");
		
	ListViewer lViewer = new ListViewer(new List(parent, SWT.MULTI));
	...
}

Следующий шаг – создание нового определения. Перейдите в org.eclipse.core.expressions.definitions и добавьте определение с именем focusDefinition и элементом with с использованием переменной activeFocusControlId. Эта переменная содержит идентификатор элемента управления, у которого есть фокус и который зарегистрирован с использованием IFocusService. Добавьте элемент equals со значением textControlId. Это правило выдает значение «истинно», если активный компонент, находящийся в фокусе, имеет идентификатор textControlId. В листинге 6 показано это определение в plugin.xml. Добавьте его в меню панели инструментов при помощи visibleWhen с элементом ссылки, показанном в листинге 7. Выполните и протестируйте пример.

Листинг 6. Определение правила управления фокусом
<definition id="focusDefinition">
<with variable="activeFocusControlId">
     		<equals value="textControlId"></equals>
      </with>
</definition>
Листинг 7. Кнопка на панели инструментов с функцией visibleWhen
<menuContribution
locationURI="toolbar:com.ibm.de.eclipse.menu.view.testview">
      <command
      	commandId="com.ibm.de.eclipse.menu.command.viewCmd"
            icon="icons/alt_window_16.gif" label="Do something"
            tooltip="Do something">
            <visibleWhen>
            	<reference definitionId="focusDefinition"></reference>
            </visibleWhen>
      </command>
</menuContribution>

Заключение

Новый механизм org.eclipse.ui.menus предлагает полезный способ согласованного и рационального внесения изменений и дополнений в меню. Единственная трудность заключается в том, чтобы научиться использовать locationURI. Кроме обычного определения меню, можно определить правила, которые позволяют отображать пункты меню по условию. Но как быть с существующими приложениями и плагинами? Ответ прост: модернизируйте свои приложения с применением нового механизма. Зачем? Некоторые функции Eclipse, на которые вы опирались, в будущих версиях могут оказаться недоступными. В разделе Ресурсы есть ссылки на дополнительную информацию о планируемых изменениях в управлении пунктами меню.


Загрузка

ОписаниеИмяРазмер
Примеры сценариев на Perlos-eclipse-3.3menuContribution.zip65 КБ

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы в первый раз заходите в developerWorks. Выберите данные в своем профиле (имя, страна/регион, компания) которые будут общедоступными и будут отображаться, когда вы публикуете какую-либо информацию. Вы можете изменить данные вашего ИБМ аккаунта в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source
ArticleID=439288
ArticleTitle=Настройка и добавление пунктов меню в Eclipse V3.3
publish-date=10262009