简体   繁体   English

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

[英]Eclipse plugin developement. Keyboard binding to an Action object

I develop a multipage XML-Editor and would like bind a specific action which calls parseDocument() and updateTabs() to a key. 我开发一个多XML编辑器,并希望绑定它调用特定的动作parseDocument()updateTabs()的关键。 The action is defined in my editor contributor as follows: 该动作在我的编辑器贡献者中定义如下:

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);
}

Is there any possibility to do this some way? 有可能以某种方式执行此操作吗? Or do I obligatory have to define command extension in the plugin.xml and to create a default handler for it (as described there for example)? 还是我义不容辞必须在plugin.xml中定义命令扩展,并为它创建一个默认的处理程序(如描述例如)? In this case it would be kind of redundant code and I'd like to avoid it. 在这种情况下,这将是一种冗余代码,我想避免使用它。

Phew... it has cost me a lot of time to figure out what I had to do to make it work. ew ...花了我很多时间弄清楚我必须做些什么才能使其工作。

Step one : getId() was the wrong method for my purpose, setActionDefinitionId() is the correct one. 步骤一getId()对我而言是错误的方法, setActionDefinitionId()是正确的方法。 I created a nested class as follows: 我创建了一个嵌套类,如下所示:

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();
    }
}

Step two The action must be registered with the handler service. 第二步该操作必须在处理程序服务中注册。 I decided to override MultiPageEditorActionBarContributor 's method setActivePage since it get passed a valid EditorPart instance, which is reference to my text editor if it's selected: 我决定重写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...
}

Step three : I mapped this action to a command extension point in the plugin.xml. 第三步 :我将此动作映射到plugin.xml中的命令扩展点。 In addition to it I created a context and binding: 除了它,我还创建了上下文和绑定:

<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>

Step four : I added a FocusListener to my StructuredTextEditor so the context is only activated if the editor is active: 第四步 :我在我的StructuredTextEditor添加了一个FocusListener ,以便仅在编辑器处于活动状态时才激活上下文:

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;
            }
        }
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM