【问题标题】:Retrieve active key binding using a commandId使用 commandId 检索活动键绑定
【发布时间】:2017-01-15 18:47:25
【问题描述】:

我目前正在开发一个 Eclipse RCP 插件,其中包含一组工具栏按钮触发操作,也可以通过键盘快捷键触发。

这是我的 plugin.xml 文件的相关部分,包括上下文、命令和快捷方式的相应键绑定:

<plugin>
   <extension point="org.eclipse.ui.contexts">
      <context id="notepad4e.context" name="In Notepad4e" parentId="org.eclipse.ui.contexts.window" />
   </extension>
   <extension point="org.eclipse.ui.commands">
      <category id="notepad4e.command.category" name="Notepad4e" description="Category for Notepad4e commands" />
      <command categoryId="notepad4e.command.category" id="notepad4e.command.text.bold" description="Sets style to bold" name="Bold" />
   </extension>
   <extension point="org.eclipse.ui.bindings">
      <key commandId="notepad4e.command.text.bold" contextId="notepad4e.context" sequence="CTRL+B" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" />
   </extension>
</plugin>

在我的 Java 代码中,我为我的视图正确激活了 notepad4e.context,并激活了一个处理程序来监听相应的键盘事件。键盘快捷键似乎工作正常,用户可以在 Eclipse 的首选项中重新定义键绑定以最适合他的需要。

我想为工具栏按钮设置一个工具提示文本,其中包含有关绑定的信息,如下所示:

我无法对键绑定信息进行硬编码,因为用户可能会更改绑定,并且硬编码的值将不再有效。我正在尝试提出一种解决方案,以编程方式检索给定命令的键绑定。我使用IBindingService 进行了以下三个尝试:

private String getShortcutDescription1() {
    IBindingService bindingService = getViewSite().getService(IBindingService.class);
    TriggerSequence triggerSequence = bindingService.getBestActiveBindingFor("notepad4e.command.text.bold");
    if (triggerSequence != null) {
        return triggerSequence.format();
    }
    return "";
}

private String getShortcutDescription2() {
    IBindingService bindingService = getViewSite().getService(IBindingService.class);
    TriggerSequence[] triggerSequences = bindingService.getActiveBindingsFor("notepad4e.command.text.bold");
    if (triggerSequences.length > 0) {
        return triggerSequences[0].format();
    }
    return "";
}

private String getShortcutDescription3() {
    IBindingService bindingService = getViewSite().getService(IBindingService.class);
    for (Binding binding : bindingService.getBindings()) {
        if (binding.getParameterizedCommand() != null
                && "notepad4e.command.text.bold".equals(binding.getParameterizedCommand().getId())) {
            return binding.getTriggerSequence().format();
        }
    }
    return "";
}

前两个解决方案似乎没有找到与notepad4e.command.text.bold commandId 关联的任何绑定。然而,使用第三种解决方案,我确实找到了预期的绑定。尽管如此,遍历所有 Eclipse 的绑定似乎并不是一个有效的解决方案,更重要的是,如果用户在他的首选项中重新定义默认快捷方式,bindingService.getBindings() 调用会返回一个集合,其中包含非活动默认绑定和活动重新定义的用户一,所以这也不会返回我正在寻找的值。

我在这里错过了什么?如何以编程方式检索给定 commandId 的活动键绑定?

提前致谢,任何帮助将不胜感激!

EDIT 17/01:前两个解决方案确实返回了所需的绑定,但它们似乎只有在用户与插件交互后才会这样做。这不切实际,因为我试图在设置插件时设置工具提示。

【问题讨论】:

  • 您应该能够使用Binding::getContextId() 为您的上下文找到正确的绑定。
  • @RüdigerHerrmann:如果您指的是第三种方法尝试,不幸的是,bindingService.getBindings() 返回的两个绑定具有相同的 contextID。

标签: java eclipse eclipse-rcp


【解决方案1】:

最后我选择了以下解决方案:

private String getShortcutDescription() {
    Binding bestBinding = null;
    for (Binding binding : getViewSite().getService(IBindingService.class).getBindings()) {
        if (binding.getParameterizedCommand() != null
                && "notepad4e.command.text.bold".equals(binding.getParameterizedCommand().getId())) {
            if (bestBinding == null) {
                bestBinding = binding;
            } else if (binding.getType() == Binding.USER) {
                // Give higher priority to a user type binding (user has overriden default).
                bestBinding = binding;
                break;
            }
        }
    }
    return bestBinding == null ? "" : " " + bestBinding.getTriggerSequence().format();
}

即使用户尚未与插件交互(上下文处于活动状态但视图未处于活动状态),也会返回正确的绑定。如问题所述,如果用户在其首选项中重新定义了默认快捷方式,上述bindingService.getBindings() 调用将返回一个集合,其中包含非活动默认绑定和活动重新定义的用户绑定。如果找到,我选择类型为Binding.USER 的那个。如果用户没有重新定义绑定,则只有一个Binding.SYSTEM类型的绑定存在并被返回。

【讨论】:

    【解决方案2】:

    在此处进行测试,您似乎在激活上下文后过早调用了getBestActiveBindingFor 代码。

    只需将您的代码更改为在 Display.asyncExec 中调用 getShortcutDescription1 Runnable 即可。因此,您似乎需要完成一些设置才能进行此调用。

    我使用的测试:

    Display.getDefault().asyncExec(() ->
      {
        System.out.println("trigger " + getShortcutDescription1());
      });
    

    【讨论】:

    • 感谢您的回答。不幸的是,这对我不起作用。尽管如此,通过指出时间问题,您似乎是对的,我尝试在几秒钟后通过用户触发的操作调用该函数,它确实有效。我想我可以安排一些延迟任意秒数的任务来设置工具提示,但感觉有点笨拙。
    • 经过一些额外的测试,即使引入延迟也不起作用。 getBestActiveBindingFor 仅在用户之前在插件视图中至少单击过一次时才返回绑定。
    • 好吧,当您调用此代码时,听起来好像视图未激活 - 正如方法名称所暗示的,这是最好的 active 绑定。如果您的上下文由于其他视图处于活动状态而未处于活动状态,它将找不到任何东西。
    猜你喜欢
    • 2011-03-20
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多