今更だけども、ようやくKeyEventをフォーカスのあるコンポーネントに関係なくアプレットでも奪取する方法が分かったので、メモ。
Toolkitを使って奪取する方法なら知ってたんだけど、これはアプレットじゃ使えないから困ってた。
KeyEventを横取りするにはKeyboardFocusManagerにKeyEventDispatcherを登録することで可能になる。なおKeyEventPostProcessorを登録すると一通りイベント処理が終わった後のイベントを横取りできる。
KeyboardFocusManagerはKeyboarFocusManager.getCurrentKeyboardFocusManager()で取得できる。
奪取することで何が出来るかって?
まず、例えばコンポーネントに依存しないショートカットキーを作ることとか出来るよね。
つぎに、先に奪取することでイベントを渡すコンポーネントを変更することが出来る。これ便利だね。
そして、自分でマウスイベントを作成したりするときに、ctrとかshiftとか、修飾キーをとっておくことが出来るよね。(私はこの目的で横取りが必要だった。)
public class Test extends JApplet { public void init() { //KeyEventDispathcerを登録 //KeyEventがコンポーネントに渡される前のKeyEventを全て横取りする。 KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher( new KeyEventDispatcher() { public boolean dispatchKeyEvent(KeyEvent e) { System.out.println("EventDispatcher "+e.getKeyChar()); return false;//trueを返すとこのKeyEventの処理は終了したと見なされる。 } } ); //KeyEventが全て処理完了した後に呼び出される。 //KeyEventDispathcerでtrueを返した場合はよびだされないぞ。 KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor( new KeyEventPostProcessor() { public boolean postProcessKeyEvent(KeyEvent e) { System.out.println("PostProcessor "+e.getKeyChar()); return false;//trueを返すとこのKeyEventの処理は終了したと見なされる。 } } ); //KeyEvent受け取り用のJPanel JPanel p = new JPanel(); add(p,BorderLayout.CENTER); p.setBackground(Color.red); //フォーカス取得作業 p.setFocusable(true); p.requestFocusInWindow(); //リスナ登録 p.addKeyListener(new KeyListener() { public void keyTyped(KeyEvent e) { System.out.println("typed "+e.getKeyChar()); } public void keyReleased(KeyEvent e) { System.out.println("released "+e.getKeyChar()); } public void keyPressed(KeyEvent e) { System.out.println("pressed "+e.getKeyChar()); } }); } }