我正在使用 Metal 外观编写 Java Swing 应用程序。每次在我的应用程序中有一个 JButton 时,用户使用 Tab 键将焦点移到按钮上,然后按 Enter 键。没发生什么事!如果他按下 Space 键,则触发按钮事件。如何分配 Enter 键来触发与 Space 键相同的事件?感谢您的帮助。
6 回答
我发现了以下内容:
http://tips4java.wordpress.com/2008/10/25/enter-key-and-button/
Rob Camick 写道,在使用 JDK5 及更高版本时,您只需添加...
UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);
...到应用程序来解决问题。这对我有用!我无法想象任何更简单的事情。但是,当使用较旧版本的 Java 时,您将不得不像 Richard 和 Peter 在他们对这个问题的回答中所描述的那样做一些事情。
这是完整的例子。Richard 很接近,但您还需要将按下的 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 作为默认按钮。
Peter 的解决方法明确更改了 L&F 默认的“焦点操作”键——如果你问我,这更有说服力。
我要补充一点,我认为很多用户不会想按到按钮然后按 Enter 键(大多数人甚至不会注意到焦点指示器)——他们希望默认操作是“正确”的操作,并且在他们按下的任何地方都可以工作进入。正如理查德建议的那样,这只能通过输入映射来完成。
我当然建议在全局更改任何内容之前,清楚地了解用户的实际需求和期望(最好参考他们使用的其他应用程序)。
您可以通过为 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");
}