Eclipse中消除快捷鍵定義衝突

由於Eclipse的易擴展性,理論上可以有無數個Action運行在一個RCP 程序中,但是快捷鍵是有限的,尤其是一些常用的,像Ctrl+C,Ctrl+S之類的普通用戶能記得住的就那麼幾個,萬一你自定義的Action的快捷鍵和Eclipse默認的發生了衝突怎麼辦?比如Eclipse默認Ctrl+S是Save的快捷鍵,但是你又自定義了一個SaveAction,希望用戶按下Ctrl+S之後執行的是自己的SaveAction的run方法.
     一般給Action綁定快捷鍵的方法是自定義binding和command,然後在action中指定definition id爲command的id.如下:
<extension
           point="org.eclipse.ui.bindings">
        <key
              commandId="myplugin.actions.save"
              contextId="org.eclipse.ui.contexts.window"
              schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
              sequence="CTRL+S">
        </key>
     </extension>
     <extension
           point="org.eclipse.ui.commands">
        <command
              id="myplugin.actions.save"
              name="Save">
        </command>
     </extension>

這樣的方法一般是不會有衝突的,但是像我們上面提到的情況,如果你自定義一個binding,它的key sequence是Ctrl+S,那就會有問題.由於org.eclipse.ui插件已經提供了一個Ctrl+S的快捷鍵,所以系統中會有兩個Ctrl+S,這樣Eclipse會在右下角pop up一個assist dialog,讓你從兩個Action中選擇一個,這樣可能會造成一些用戶使用上的不習慣.
解決辦法:
    1.直接改快捷鍵.
      這個最簡單了,比如把你自己的save定義成Alt+S.但是這個方法也是最不好的方法,因爲很多用戶並不知道Alt+S在你的程序裏面就是save.
    2.修改自定義action的definition id
      我們剛纔說過,action的definition id綁定着一個command,而command又對應着一個binding,Eclipse通過這樣的方式實現action和快捷鍵的綁定.我們再來看看Eclipse定義的command和key binding(摘自org.eclipse.ui的plugin.xml):
      <command
            name="%command.save.name"
            description="%command.save.description"
            categoryId="org.eclipse.ui.category.file"
            id="org.eclipse.ui.file.save" />
      <key
            commandId="org.eclipse.ui.file.save"
            sequence="M1+S"
            schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" />
      <key

     Eclipse的Save Action把definition id指定爲org.eclipse.ui.file.save,然後它就和上面的command進行了綁定,而這個command對應的key就是"M1+S"(Ctrl + S),這樣就實現了快捷鍵綁定.如果我們也把自定義的Save Action的definition id指定爲org.eclipse.ui.file.save,是不是就可以達到目的呢?答案是肯定的.
     Eclipse中的Action存在着一個類似"優先級"的概念(具體實現是通過action handler).越"具體"的action,優先級越高.Eclipse的Save Action明顯是一個global的action,(同樣的global action還有copy, cut,undo,redo等等).而我們自定義的action一般是實現了IWorkbenchWindowActionDelegate接口的,就是說,它是contribute to workbench window的,它是一個workbench action,它的優先級就高於任何global action.同理,如果你定義一個editor action或者view action,由於它比workbench還"具體"(workbench可以包含多個editor或view,workbench action對這些editor或view都是有效的;而editor action只對某個具體的editor有效),所以editor action的優先級就高於workbench action.這樣,如果自定義的action和eclipse缺省的action都綁定到同一個command,那麼eclipse runtim最後會選擇自定義的action來執行.
    3.終極解決大法:自定義schema
     Eclipse 有一個default的快捷鍵schema文件:org.eclipse.ui.defaultAcceleratorConfiguration.它存儲着Eclipse所有的快捷鍵.如果你自定義一個自己的schema文件,並把它設成當前使用的schema文件,那麼Eclipse就會調用自定義的schema文件.(新的schema文件可以在org.eclipse.ui.bindings擴展點中定義,請注意,在定義新schema的時候由一個parentID屬性,如果你定義了它,新的schema會像類繼承一樣把parent schema裏面的key binding全繼承下來.如果不定義,則是一個全新的schema)
    假定我們已經有了一個新的schema文件,id是myplugin.schema.然後我們在org.eclipse.ui.bindings下定義一個key:
<key
              commandId="myplugin.actions.save"
              contextId="org.eclipse.ui.contexts.window"
              schemaId="myplugin.schema"
              sequence="CTRL+S">
        </key>
我們已經把schemaId換成了myplugin.schema,表示我們把CTRL+S加到了myplugin.schema中,然後把新建的schema文件在product配置文件plugin_customization.ini中設置成當前的key schema文件:
org.eclipse.ui/KEY_CONFIGURATION_ID=myplugin.schema

這種方法雖然麻煩了一點,但卻可以治標又治本.而且由於可以指定parent schema,我們完全可以把org.eclipse.ui.defaultAcceleratorConfiguration作爲parent schema,繼承它全部的快捷鍵配置,只定制幾個會產生衝突的快捷鍵即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章