如何在我的Java应用程序中将Enter键分配为所有JButton的触发键?

12

我正在使用Metal外观编写Java Swing应用程序。每当我的应用程序中有一个JButton,用户使用Tab键将焦点移动到按钮,然后按Enter键。但是,没有任何反应!如果用户按下空格键,则会触发按钮事件。如何将Enter键分配为触发与空格键相同的事件?谢谢您的帮助。

6个回答

18
我找到了以下内容: http://tips4java.wordpress.com/2008/10/25/enter-key-and-button/ Rob Camick在这里写道,在使用JDK5及更高版本时,您只需添加...
UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);

对于我的问题,这对我起了作用!而且我想不出有什么更简单的方法。但是,如果您使用旧版本的Java,则必须像Richard和Peter在他们回答此问题中描述的那样进行操作。


啊,非常好;-)文章也很棒。在回答问题时,我看了一下MetalLookAndFeel类,这仅仅是我使用的"Button.focusInputMap"上方的几行代码。 - Peter Štibraný

4

这里是完整的示例。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;
    }
}

非常感谢你,彼得。我认为最好的答案是基于代码的答案。点赞! - Alfred B. Thordarson

1

实际上,这是一个外观问题。哪个键触发焦点按钮取决于外观。

“默认按钮”解决方法有效,因为您使用的外观将回车用作默认按钮。

Peter的解决方法明确更改了L&F默认的“焦点操作”键-如果您问我,这更有说服力。

我想补充说,我认为许多用户不会想要切换到按钮然后按Enter键(大多数人甚至不会注意到焦点指示器)-他们希望默认操作是“正确”的,并且无论他们在哪里按Enter键都可以正常工作。这只能通过输入映射来完成,就像Richard建议的那样。

在全局更改任何内容之前,我肯定建议清楚地了解您的用户实际上想要和期望什么(最好参考他们使用的其他应用程序)。


0

您还可以将“默认按钮”设置为最近聚焦的按钮。

我在一个应用程序中做了这件事,所有做法都很难维护和调试。事实上,这显然不是Swing设计者想要发生的。


我同意,这将是一场噩梦。 - Alfred B. Thordarson

0
你可以通过为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); 

我不想对应用程序中的所有按钮都这样做,太麻烦了。 - Alfred B. Thordarson
你可以继承JButton并在构造函数中添加它。 - Richard Campbell

0

对于单选框和复选框,以上答案的扩展。在创建组件之前调用此函数。

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");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接