我正在使用Metal外观编写Java Swing应用程序。每当我的应用程序中有一个JButton,用户使用Tab键将焦点移动到按钮,然后按Enter键。但是,没有任何反应!如果用户按下空格键,则会触发按钮事件。如何将Enter键分配为触发与空格键相同的事件?谢谢您的帮助。
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;
}
}
实际上,这是一个外观问题。哪个键触发焦点按钮取决于外观。
“默认按钮”解决方法有效,因为您使用的外观将回车用作默认按钮。
Peter的解决方法明确更改了L&F默认的“焦点操作”键-如果您问我,这更有说服力。
我想补充说,我认为许多用户不会想要切换到按钮然后按Enter键(大多数人甚至不会注意到焦点指示器)-他们希望默认操作是“正确”的,并且无论他们在哪里按Enter键都可以正常工作。这只能通过输入映射来完成,就像Richard建议的那样。
在全局更改任何内容之前,我肯定建议清楚地了解您的用户实际上想要和期望什么(最好参考他们使用的其他应用程序)。
您还可以将“默认按钮”设置为最近聚焦的按钮。
我在一个应用程序中做了这件事,所有做法都很难维护和调试。事实上,这显然不是Swing设计者想要发生的。
// 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);
对于单选框和复选框,以上答案的扩展。在创建组件之前调用此函数。
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");
}