Developer'sWorks
Tips

Keyイベント処理方法

Keyイベントにより、処理を埋め込む方法をしては、 KeyListenerを登録 しイベントをハンドリングする方法と、ボタンなどのショートカット作成するのを目的に KeyMap(ニーモニック)の登録 する方法などが考えられます。
ボタンに対してKeyMapした場合は、キー入力によりマウスクリックと同等の処理が行われる(フォーカスが移動し、ボタンが押される)動作になります。 つまり、ボタンへのショートカットと同じになります。(ニーモニックの機能もKeyMapの機能を使用されています。)
AddKeyLitenerは「イベントをハンドリングする」というものになりますので、該当イベント発生時にLitenerのメソッドが発火される機能になります。
また、KeyLitenerは明示的にイベント消化しない限りイベント消化されないが、KeyMapはイベント消化されるという差があります。
使用目的により、使い分けを行ってください。

特にKeyMapにて処理と登録する際には、 これらの処理を埋め込む際には、どんな状況でイベントが発生するのか ということと、SwingデフォルトのKeyMapと絡んだらどうなるか?
、などを考慮して作成する必要があります。

Webtribe,VisualFrameのJavaクライアントでは、SwingデフォルトのKeyMapをそのまま使用しています。
そのため、F10を押すとメニューが開く、テーブルにフォーカスが当たっている状態にてF2を押すと編集状態/表示状態の切替 などの 動作を行います。

基本的には、SwingデフォルトのKeyMapとが重ならない指定をお勧めしていますが、 任意で登録したKeyMapとSwingデフォルトのKeyMapとが重なってしまった場合、どのような動きになるのか?という 理解を深めるために Swing(JDK1.0.3)でのKeyイベント発生の流れ の詳細を以下に記述します。

※ イベント消化 とは、KeyEvent isConsumed() により判断されます。明示的に消化する場合には public void consume() を実行します
※ この記述は JDK1.3.1_07 のソースを元に作成されました。バージョンにより差異が発生する可能性があります。ご了承ください。
※ KeyMap登録方法として、ボタンにFunctionKeyのKeyMap追加のビジネスルールが参考になります。

Swing(JDK1.0.3)でのKeyイベント発生の流れ

  1. GUI より キー イベント発生
  2. javax.swing.DefaultFocusManager pcocessKeyEvent 実行
    (VK_TAB によるフォーカス遷移処理)

    Keyが VK_TAB の場合は以下の処理を行う
    ※Configにて EnterをTabと同等にする設定がされている場合は VK_ENTER も対象になります。

    コンポーネント自身にフォーカスマネージャーがある場合(isManagingFocus()) 「CTRL_MASKでない もしくは KeyEvent.VK_Iの時」は処理を抜ける
    KeyEvent.KEY_PRESSEDでない場合にはイベント消化して処理終了
    VK_TAB もしくはShift+VK_TAB の場合はフォーカス移動処理を行いイベント消化して処理終了

  3. 上記にてイベント消化されていない場合
    javax.swing.JComponent processKeyEvent 実行
    (KeyListenerイベントの発火処理)

    java.awt.Component processKeyEvent を実行し、KeyListenerイベントの発火

  4. 上記にてイベント消化されていない場合
    javax.swing.JComponent processComponentKeyEvent 実行
    (主にUIでの処理)

  5. 上記にてイベント消化されていない場合
    javax.swing.JComponent processKeyBindings 実行
    (対象コンポーネントの KeyMap処理)
    現在フォーカス取得しているコンポーネントのKeyBiding処理を行う
    KeyBidingがあれば基本的にイベント消化される

  6. 上記にてイベント消化されていない場合
    (親コンポーネントの KeyMap処理)

    getParent() のコンポーネントに対して processKeyBindings 実行する
    Window,Appletなどのトップ画面になるまで この処理がループされる
    (indow,Appletなどのトップ画面は処理されない)
    KeyBidingが処理された時点でイベント消化され処理終了

  7. 上記にてイベント消化されていない場合
    (Topコンテナの KeyMap処理)

    javax.swing.JComponent processKeyBindingsForAllComponents 実行
    このメソッド内にて KeyboardManager fireKeyboardAction を実行し、コンテナのKeyMapに対象のものが無いか探す。
    複数登録されている場合は順次実行され、イベント消化されたタイミングで処理終了
    Swingデフォルトにて登録されている F10(メニュー表示) 処理はこのタイミングにて実行されます。

    指定キーのKeyMapが複数存在する場合は、登録された順番とは逆に実行されていきます。
    (実際、registされる順番は 降順 になる)
    つまり、SwingデフォルトでMappingされているものと同じキーで任意に登録した場合、任意に登録されたActionが 先に実行されます。