Eclipse插件开发。键盘绑定到Action对象

时间:2014-07-09 13:32:26

标签: java eclipse-plugin

我开发了一个多页XML编辑器,希望绑定一个特定的操作,该操作将parseDocument()updateTabs()调用到一个键。该操作在我的编辑器撰稿人中定义如下:

private void createActions() {
    updateTabsAction = new Action() {
        @Override
        public void run() {
            ARTEditor artEditor = ((ARTEditor)((MultiPageEditorSite)activeEditorPart.getEditorSite()).getMultiPageEditor());
            artEditor.parseDocument();
            artEditor.updateTabs();
        }

        @Override
        public String getId()
        {
            return "com.portal.agenda.editors.updatetabs";
        }

    };
    updateTabsAction.setText("Update tabs");
    updateTabsAction.setToolTipText("Parses document and updates tabs to reflect textual changes");
    updateTabsAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
            getImageDescriptor(IDE.SharedImages.IMG_OBJS_TASK_TSK));
}
    @Override
    public void contributeToToolBar(IToolBarManager manager) {
    manager.add(new Separator());
    manager.add(updateTabsAction);
}

有可能以某种方式这样做吗?或者必须必须在plugin.xml中定义命令扩展并为其创建默认处理程序(例如,如there所述)?在这种情况下,它将是一种冗余代码,我想避免它。

1 个答案:

答案 0 :(得分:0)

Phew ...我花了很多时间弄清楚我必须做些什么才能让它发挥作用。

第一步getId()对我来说是错误的方法,setActionDefinitionId()是正确的方法。我创建了一个嵌套类,如下所示:

public final class UpdateTabsAction extends Action
{
    public UpdateTabsAction()
    {
        setText("Update tabs");
        setToolTipText("Parses document and updates tabs to reflect textual changes");
        setImageDescriptor(PlatformUI.getWorkbench()
                                     .getSharedImages()
                                     .getImageDescriptor(IDE.SharedImages.IMG_OBJS_TASK_TSK));
        setActionDefinitionId("com.portal.agenda.editors.updatetabs");
    }


    @Override
    public void run()
    {
            ARTEditor artEditor = (ARTEditor)activeEditorPart.getSite().getPage().getActiveEditor();
            artEditor.parseDocument();
            artEditor.updateTabs();
    }
}

第二步必须在处理程序服务中注册操作。我决定覆盖MultiPageEditorActionBarContributor方法setActivePage,因为它传递了一个有效的EditorPart实例,如果选择了该实例,则会引用我的文本编辑器:

// Required to avoid multiple registering of the action
private IHandlerActivation iHandlerActivation;

@Override
public void setActivePage(IEditorPart part)
{
    if (part != null && iHandlerActivation == null)
    {
        IHandlerService hService = ((IHandlerService)part.getSite().getService(IHandlerService.class));
        iHandlerActivation = hService.activateHandler(updateTabsAction.getActionDefinitionId(),
                                                      new ActionHandler(updateTabsAction));
    }

    if (activeEditorPart == part)
        return;
    activeEditorPart = part;

    // ...skipped...
}

第三步:我将此操作映射到plugin.xml中的命令扩展点。除此之外,我创建了一个上下文和绑定:

<extension
      point="org.eclipse.ui.commands">
   <category
         id="com.portal.agenda.editors.category"
         name="ARTEditor">
   </category>
   <command
         categoryId="com.portal.agenda.editors.category"
         description="Parse document and update tabs to reflect textual changes"
         id="com.portal.agenda.editors.updatetabs"
         name="Update tabs">
   </command>
</extension>
<extension
      point="org.eclipse.ui.contexts">
   <context
         id="com.portal.agenda.editors.context"
         name="%context.name"
         parentId="org.eclipse.ui.textEditorScope">
   </context>
</extension>
<extension
      point="org.eclipse.ui.bindings">
   <key
         commandId="com.portal.agenda.editors.updatetabs"
         contextId="com.portal.agenda.editors.context"
         schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
         sequence="F5">
   </key>
</extension>

第四步:我在FocusListener添加了StructuredTextEditor,因此只有在编辑器处于活动状态时才会激活上下文:

private void initKeyBindingContext()
{
    final IContextService cService = (IContextService)getSite().getService(IContextService.class);
    textEditor.getTextViewer().getTextWidget().addFocusListener(new FocusListener()
    {
        IContextActivation currentContext = null;


        public void focusGained(FocusEvent e)
        {
            if (currentContext == null)
                currentContext = cService.activateContext("com.portal.agenda.editors.context");
        }


        public void focusLost(FocusEvent e)
        {
            if (currentContext != null)
            {
                cService.deactivateContext(currentContext);
                currentContext = null;
            }
        }
    });
}