回答編集履歴

1

InputMapとActionMapを使った方式に書き換えました。

2015/12/30 07:44

投稿

argius
argius

スコア9390

test CHANGED
@@ -1,7 +1,83 @@
1
+ `KeyListener`は、フォーカスされているコンポーネントに対して有効になるので、そのフォーカスされているコンポーネントに`KeyListener`が設定されていなければなりません。
2
+
1
- も何あるかも知れませんがまず確実にすべき箇所
3
+ 私が実際してみたところでは起動後は`button`フォーカスされてました
2
4
 
3
5
 
4
6
 
5
- `mendo3`のコンラクタに`init`メソッドに書いている`addKeyListener`を移してださい
7
+ キーを押したときにどのコンポーネンにフォカスが当たっているかは不定ですので、今のままではこういう風にすれば動くようになります
6
8
 
9
+
10
+
11
+ ```lang-java
12
+
13
+ addKeyListener(this);
14
+
15
+ bg1.addKeyListener(this);
16
+
17
+ fileButton.addKeyListener(this);
18
+
19
+ button.addKeyListener(this);
20
+
21
+ ```
22
+
23
+
24
+
25
+ ですが、コンポーネントを追加するたびに`addKeyListener`を追加しないといけないのはちょっといただけませんね。
26
+
27
+
28
+
29
+ こういう場合は、`InputMap`と`ActionMap`を組み合わせます。
30
+
7
- このプログラムはアプレットでなく`JFrame`を使ったSwingアプリなので、`init`メソッドは必須はありません、自動で呼ばれせん
31
+ `JFrame`には直接設定できので、`getRootPane()`で取得たコンポーネントに設定し
32
+
33
+ `JComponent.WHEN_IN_FOCUSED_WINDOW`を設定することで、`RootPane`の子のコンポーネントにフォーカスが当たっていても、キーイベントを拾うことができます。
34
+
35
+
36
+
37
+ - `InputMap`と`ActionMap`を使った例
38
+
39
+
40
+
41
+ ```lang-java
42
+
43
+ // addKeyListener(this); // KeyListenerは使わない
44
+
45
+
46
+
47
+ InputMap imap = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
48
+
49
+ ActionMap amap = getRootPane().getActionMap();
50
+
51
+
52
+
53
+ // キーバインド: Aキー(修飾キーなし)
54
+
55
+ KeyStroke ksA = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0);
56
+
57
+ // アクションキー
58
+
59
+ String akPlaySound = "play-sound";
60
+
61
+ // アクション
62
+
63
+ Action action = new AbstractAction() {
64
+
65
+ @Override
66
+
67
+ public void actionPerformed(ActionEvent evt) {
68
+
69
+ AudioClip audio = Applet.newAudioClip(getClass().getResource("pinpon.wav"));
70
+
71
+ audio.play();
72
+
73
+ }
74
+
75
+ };
76
+
77
+ imap.put(ksA, akPlaySound);
78
+
79
+ amap.put(akPlaySound, action);
80
+
81
+ ```
82
+
83
+