JavaアプリケーションのすべてのJButtonのトリガーキーとしてEnterを割り当てるにはどうすればよいですか?
質問
Metalルックアンドフィールを使用してJava Swingアプリケーションを作成しています。アプリケーションにJButtonがあるたびに、ユーザーはTabキーを使用してフォーカスをボタンに移動し、Enterキーを押します。何も起こりません!彼がスペースキーを押すと、ボタンイベントが発生します。 Enterキーを割り当てて、スペースキーと同じイベントをトリガーするにはどうすればよいですか?ご協力ありがとうございます。
解決
次を見つけました:
http://tips4java.wordpress.com/2008 / 10/25 / enter-key-and-button /
Rob Camickが、JDK5以降を使用する場合、単に追加することを書いているところ...
UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);
...アプリケーションで問題を解決します。これは私のためにトリックをしました!そして、もっと単純なものは想像できません。ただし、古いバージョンのJavaを使用する場合は、RichardとPeterがこの質問に対する回答で説明するようなことを行う必要があります。
他のヒント
これは完全な例です。リチャードは身近でしたが、リリースされたばかりではなく、ENTERを押してアクションにマップする必要があります。すべてのボタンで機能するように、このマッピングをボタンのデフォルト入力マップに配置しました。インポートを追加すると、実行可能になります。
public class Main implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Main());
}
@Override
public void run() {
setupEnterActionForAllButtons();
JFrame frame = new JFrame("Button test");
frame.getContentPane().add(createButton(), BorderLayout.NORTH);
frame.getContentPane().add(createButton(), BorderLayout.SOUTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private void setupEnterActionForAllButtons() {
InputMap im = (InputMap) UIManager.getDefaults().get("Button.focusInputMap");
Object pressedAction = im.get(KeyStroke.getKeyStroke("pressed SPACE"));
Object releasedAction = im.get(KeyStroke.getKeyStroke("released SPACE"));
im.put(KeyStroke.getKeyStroke("pressed ENTER"), pressedAction);
im.put(KeyStroke.getKeyStroke("released ENTER"), releasedAction);
}
private JButton createButton() {
JButton b = new JButton("press enter");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Pressed");
}
});
return b;
}
}
実際、これはルックアンドフィールの問題です。どのキーがフォーカスされたボタンをトリガーするかは、ルックアンドフィール次第です(そうする必要があります)。
「デフォルトボタン」回避策は、使用しているL& FがデフォルトボタンにEnterを使用するため、機能します。
ピーターの回避策は、L& Fのデフォルトの「フォーカスアクション」を明示的に変更します。キー-私に尋ねると、いくらか納得できます。
多くのユーザーがボタンにタブで移動してEnterキーを押したくないと思うと付け加えます(ほとんどのユーザーはフォーカスインジケーターに気付かないでしょう)。デフォルトのアクションを「右」にしたいのです。 1つを押し、Enterキーを押した場所で作業します。これは、Richardが提案する入力マップでのみ実行できます。
グローバルに何かを変更する前に、ユーザーが実際に何を望んで何を期待しているのか(できれば他のアプリを参照して)の非常に明確な画像を取得することをお勧めします。
Enterキーに入力/アクションマップを割り当てることでそれを行います。次のようなもの:
// save the command mapping for space
Object spaceMap = button.getInputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true));
// add a mapping from enter to the same command.
button.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true),spaceMap);
「デフォルトボタン」も設定できます。最後にフォーカスされたボタンに。
これをアプリケーションで実行しましたが、これを実行するすべての方法は、保守とデバッグが面倒です。実際のところ、これはSwingのデザイナーが意図したものではないことは明らかです。
ラジオ、チェックボックスで同じことをするための上記の回答への拡張。 コンポーネントを作成する前にこれを呼び出しました
void setupEnterAction(String componentName){
String keyName = componentName + ".focusInputMap";
InputMap im = (InputMap) UIManager.getDefaults().get(keyName);
Object pressedAction = im.get(KeyStroke.getKeyStroke("pressed SPACE"));
Object releasedAction = im.get(KeyStroke.getKeyStroke("released SPACE"));
im.put(KeyStroke.getKeyStroke("pressed ENTER"), pressedAction);
im.put(KeyStroke.getKeyStroke("released ENTER"), releasedAction);
}
public void setEnterEvent(){
setupEnterAction("Button");
setupEnterAction("RadioButton");
setupEnterAction("CheckBox");
}