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

Вспомним, что утилита readme определяет собственный редактор, который добавляет действия в меню рабочей среды с помощью ReadmeEditorActionBarContributor.  

<extension
    point = "org.eclipse.ui.editors">
	<editor
  	   id = "org.eclipse.ui.examples.readmetool.ReadmeEditor"
  	   name="%Editors.ReadmeEditor"
      	   icon="icons/obj16/editor.png"
      	   class="org.eclipse.ui.examples.readmetool.ReadmeEditor"
	   extensions="readme"
           contributorClass="org.eclipse.ui.examples.readmetool.ReadmeEditorActionBarContributor">
	</editor>
</extension>

Рассмотрим подробнее происходящее в классе contributor.

   public ReadmeEditorActionBarContributor() {
	...
	action2 = new RetargetAction(IReadmeConstants.RETARGET2, MessageUtil.getString("Editor_Action2"));
	action2.setToolTipText(MessageUtil.getString("Readme_Editor_Action2"));
	action2.setDisabledImageDescriptor(ReadmeImages.EDITOR_ACTION2_IMAGE_DISABLE);
	action2.setImageDescriptor(ReadmeImages.EDITOR_ACTION2_IMAGE_ENABLE);
	...
	action3 = new LabelRetargetAction(IReadmeConstants.LABELRETARGET3, MessageUtil.getString("Editor_Action3"));
	action3.setDisabledImageDescriptor(ReadmeImages.EDITOR_ACTION3_IMAGE_DISABLE);
	action3.setImageDescriptor(ReadmeImages.EDITOR_ACTION3_IMAGE_ENABLE);
	...  
	handler2 = new EditorAction(MessageUtil.getString("Editor_Action2")); 
	...
	handler3 = new EditorAction(MessageUtil.getString("Editor_Action3")); 
	...

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

Но где регистрируются обработчики действий?  Настройка глобальных обработчиков происходит иначе, когда редактор задает действия с изменяемыми целями.  Почему это так?  Потому что дополняющий класс отвечает за отслеживание активных панелей и добавление обработчиков, когда различные панели или сам редактор становятся активными.  (Рабочая среда делает это за вас, если вы задаете обработчик для одного из глобальных действий).  Вот как ReadmeEditorActionBarContributor делает это:

public void init(IActionBars bars, IWorkbenchPage page) {
	super.init(bars, page);
	bars.setGlobalActionHandler(IReadmeConstants.RETARGET2, handler2);
	bars.setGlobalActionHandler(IReadmeConstants.LABELRETARGET3, handler3);
	...

Вначале дополняющий класс регистрирует свои обработчики для действий с изменяемыми целями.  Это гарантирует, что действия дополняющего класса будут запущены при активации редактора.  Затем каждый RetargetAction регистрируется как получатель запросов компонента на странице.

	...
	// Перехват действия с изменяемыми целями получателями запросов
	page.addPartListener(action2);
	page.addPartListener(action3);
	IWorkbenchPart activePart = page.getActivePart();
	if (activePart != null) {
		action2.partActivated(activePart);
		action3.partActivated(activePart);
	}
}

Добавление каждого RetargetAction в виде получателя запросов компонента означает, что они будет уведомлены при изменении активного компонента.  Действие может получить правильный глобальный обработчик от нового активированного компонента.  (Подробные сведения содержатся в описании реализации RetargetAction ).   Обратите внимание, что для выполнения действие связывается с текущим активным компонентом.

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

public void dispose() {
	// Удаляет действия с изменяемыми целями как получатели запросов страниц
	getPage().removePartListener(action2);
	getPage().removePartListener(action3);
}

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

   public void setActiveEditor(IEditorPart editor) {
	...
	handler2.setActiveEditor(editor);
	handler3.setActiveEditor(editor);
	...
}

На этом процесс настройки редактора завершается.  Когда редактор открыт и активен, обработчики (и их метки) будут отображаться в меню рабочей среды, как задано в ReadmeEditorActionBarContributor .

Меню Readme с тремя действиями редактора в меню рабочей среды

Теперь, когда дополняющие классы редактора созданы, что делает панель для регистрации обработчика?  Код клиента схож с регистрацией обработчика для действия рабочей среды, за исключением того, что ИД действия определяется редактором модуля.  Для этих действий ReadmeContentOutlinePage регистрирует обработчик.

public void createControl(Composite parent) {
	super.createControl(parent);
	...
	getSite().getActionBars().setGlobalActionHandler(
		IReadmeConstants.RETARGET2, 
		new OutlineAction(MessageUtil.getString("Outline_Action2")));  

	OutlineAction action = new OutlineAction(MessageUtil.getString("Outline_Action3")); 
	action.setToolTipText(MessageUtil.getString("Readme_Outline_Action3")); 
	getSite().getActionBars().setGlobalActionHandler(
		IReadmeConstants.LABELRETARGET3, 
		action);  
	...

Обратите внимание, что обработчик схемы задает текст подсказки и метку на втором действии, так как это позволяет изменить метку.  При активации панели схемы readme ее обработчики (и их метки) отображаются в меню рабочей среды.

Меню Readme с одним переименованным действием редактора

Обратите внимание, что переименованное действие отображает новую метку.