2017-01-15 22 views
0

現在、キーボードショートカットでトリガーできるアクションをトリガーする一連のツールバーボタンを含むEclipse RCPプラグインを開発中です。私のJavaコードでcommandIdを使用してアクティブなキーバインドを取得する

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

、私は正確に活性化しています:ここで

は、コンテキスト、コマンドとショートカットの結合に対応するキーを使用して、私ののplugin.xmlファイルの関連部分でありますnotepad4e.context私のビューと対応するキーボードイベントを聴くハンドラをアクティブにします。キーボードのショートカットは正常に動作しているように見えます。ユーザは、Eclipseの環境設定でキーバインドを再定義して、自分のニーズに最も適したものにすることができます。

私は次のようにバインディングに関する情報をツールバーボタンにツールチップテキストを設定したいと思います:ユーザーがバインドを変更する場合がありますよう Button with tool tip text shortcut

私は、キーバインディング情報をハードコーディングすることができず、ハードコードされた値はもはや有効ではありません。私は、プログラムで指定されたコマンドのキーバインディングを取得するソリューションを考え出しています。私は、次の3つの試みが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に関連付けられたバインディング見つけるように見えることはありません。しかし、第3の解決策では、私は予想される拘束力を見つける。それにもかかわらず、Eclipseのバインディングはすべて効率的なソリューションのようには見えません。さらに重要なのは、ユーザが自分の設定でデフォルトのショートカットを再定義した場合、bindingService.getBindings()コールは、非アクティブなデフォルトバインディングとアクティブな再定義されたユーザこれは私が探している値を返しません。

私はここで何が欠けていますか?与えられたcommandIdのアクティブなキーバインディングをプログラムでどのように取得できますか?

ありがとうございました。お手数をおかけしますようお願い申し上げます。

EDIT 17/01: 2つの最初の解決方法では、目的のバインディングが返されますが、ユーザーがプラグインとやりとりした後にのみ表示されます。これは、プラグインの設定中にツールヒントを設定しようとしているため、現実的ではありません。

+0

'Binding :: getContextId()'を使用して、コンテキストの正しいバインディングを見つけることができるはずです。 –

+0

@RüdigerHerrmann:3番目のメソッドの試行を参照している場合、残念ながら 'bindingService.getBindings() 'によって返された2つのバインディングは同じcontextIDを持ちます。 – Pyves

答えて

0

を私は、次のソリューションを選択している端部で:

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のバインディングが1つのみ存在し、返されます。

0

ここでテストすると、文脈を有効にした後すぐにgetBestActiveBindingForコードを呼び出すように見えます。

getShortcutDescription1Display.asyncExecRunnableにコールするようにコードを変更するだけで問題なく動作します。したがって、この電話をかける前にいくつかのセットアップを完了する必要があるようです。

テストのために私が使用:

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

あなたの答えをありがとう。残念ながら、これは私のためには機能しません。それにもかかわらず、タイミングの問題を指摘することによって正しいように思えるので、私は数秒後にユーザーがトリガーしたアクションによって呼び出すことを試みました。私はツールのヒントを設定するために何らかの種類のタスクを任意の秒数だけ遅延させるようなスケジュールを立てることができると思うが、少し不器用だと感じる。 – Pyves

+0

いくつかの追加テストの後に、遅延を導入しても機能しません。 'getBestActiveBindingFor'は、ユーザが以前にプラグインのビューで少なくとも1回クリックした場合にのみバインディングを返します。 – Pyves

+0

このコードを呼び出すときにビューがアクティブでないように聞こえるのは、メソッド名が示すように、これは最善の**アクティブな**バインディングです。他のビューがアクティブなためにコンテキストがアクティブでない場合は、何も検索されません。 –

関連する問題