在Java编辑器中按下“Ctrl + a”,可以看见当前编辑器中的文本处于全选状态,这即是Eclipse IDE中快捷键的一处应用场景,在实际的插件开发中,我们会经常定制快捷键,那么Eclipse的快捷键是如何实现呢?
每个快捷键最终都会对应着具体操作,在Eclipse中,这个操作用IAction来描述,并在调用 IAction接口的run方法时执行,在Eclipse早期的版本中,定义Action的时候可同时定义与之关联的快捷键,这种方式会导致如下几个问题:
1、 不同的插件中不同语义的操作可能定义相同的快捷键。
2、 相同语义的操作可能会定义不同的快捷键,如复制、粘贴等操作。
3、 插件可能会定义以后与工作台冲突的快捷键(例如,工作台升级就会发生这种情况)。
为了解决上述问题,Eclipse引入了键绑定的机制,它可配置,这种机制在解决上述问题的时候又增加了如下的能力:
1、 用户可以控制应使用哪些键绑定
2、 插件可以定义模拟用户熟悉的其他工具的键绑定
3、 插件可以定义键绑定的上下文,以使它们只在某些情况下才是活动的
下面,通过一个简单的例子说明如何在键绑定的机制下实现自己的快捷键,在Eclipse插件的示例项目xml编辑器按下“Ctrl+o”时候,弹出一个对话框,如下图所示:
操作步骤以及说明如下:
-
-
新建插件工程,选择示例项目中的编辑器插件,并将编辑器对应的文件后缀名改为myxml,以区分Eclipse中已经集成的xml编辑器。
-
实现下列扩展点:
a) org.eclipse.ui.bindings扩展点,将命令与快捷键绑定,配置后好的plugin.xml如下:<extension point="org.eclipse.ui.bindings"> <key commandId="org.tjlvan.open" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="Ctrl+O"> </key> </extension>
b) org.eclipse.ui.commands扩展点,声明自己的Command,xml如下
<extension point="org.eclipse.ui.commands"> <command description="打开一个对话框" id="org.tjlvan.open" name="open"> </command> </extension>
c) org.eclipse.ui.actionSets扩展点,设置action的Retarger属性为true,表示这个Action是一个重定向Action,并设置Action的definitionId与Command的id一致。表示将此Id的Action与相应的Command关联
<extension point="org.eclipse.ui.actionSets"> <actionSet id="org.tjlvan.actionSet" label="myActionSet" visible="false"> <action definitionId="org.tjlvan.open" id="org.tjlvan.openAction" label="open" retarget="true"> </action> </actionSet> </extension>
d) 实现一个简单的OpenAction,在run方法中打开一个对话框
public class OpenAction extends Action { public OpenAction() { this.setId(OpenAction.class.getName()); this.setText("Open"); } public void run() { MessageDialog.openInformation(null, "测试", "定义自己的快捷键"); } }
e) 在xml编辑器对应的EditorActionContributor将我们OpenAction重定向,以便和特定快捷键关联,代码如下:public class SubTextEditorActionContributor extends BasicTextEditorActionContributor { private IAction openAction = new OpenAction(); public SubTextEditorActionContributor() { super(); } @Override public void setActiveEditor(IEditorPart part) { super.setActiveEditor(part); IActionBars actionBars= getActionBars(); actionBars.setGlobalActionHandler("org.tjlvan.openAction", openAction); } }
最后,看看按下“Ctrl+o” 是不是会弹出图示的对话框。
-
从上例中可以看出,Eclipse键绑定实现的策略是通过命令来定义语义操作,并将命令与快捷键绑定,命令的语义操作即IAction,可由插件实时设置,以便为同一语义的命令在不同情况下表现为不同的操作行为,如拷贝粘贴,这些在不同的插件中,表现出的具体行为也就不同,文本编辑器对文本操作,图形编辑器对图形进行操作,但它们的快捷键都是Ctrl+v,Ctrl+c;
我们在扩展点中声明Command和Binding,那么如何关联Command与具体的操作呢?
可通过以下的方式:
-
实现org.eclipse.ui.handlers扩展点或者在声明Command时候配置一个IHander, 这种方式下需要提供一个具体操作类实现org.eclipse.core.commands.IHander接口,在execute方法中执行具体的操作内容。
-
实现org.eclipse.ui.actionSets扩展点,配置全局Action,此Action的actionDefinitionId与Command的Id一致,当扩展点的属性Retarget属性为True的时候,我们需要在此为Command提供一个真实的Action作为Command的操作,当Retarget属性为False的时候,表示我们配置的Action是一个重定向Action,仅仅提供一个将此Action的Id与Command绑定的作用,这样,我们可按照本文例中的方法,定制自己的Action,最后调用IActionBars.setGlobalActionHandler(String actionId, IAction handler)方法,把自己的Action如OpenAction和快捷键进行绑定。