12

我正在使用 Metal 外观编写 Java Swing 应用程序。每次在我的应用程序中有一个 JButton 时,用户使用 Tab 键将焦点移到按钮上,然后按 Enter 键。没发生什么事!如果他按下 Space 键,则触发按钮事件。如何分配 Enter 键来触发与 Space 键相同的事件?感谢您的帮助。

4

6 回答 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 在他们对这个问题的回答中所描述的那样做一些事情。

于 2009-01-13T19:57:17.687 回答
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;
    }
}
于 2009-01-13T19:34:33.803 回答
1

实际上,这是一个外观问题。哪个键触发聚焦按钮取决于(并且应该)外观和感觉。

“默认按钮”解决方法有效,因为您使用的 L&F 使用 enter 作为默认按钮。

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

我要补充一点,我认为很多用户不会想按到按钮然后按 Enter 键(大多数人甚至不会注意到焦点指示器)——他们希望默认操作是“正确”的操作,并且在他们按下的任何地方都可以工作进入。正如理查德建议的那样,这只能通过输入映射来完成。

我当然建议在全局更改任何内容之前,清楚地了解用户的实际需求和期望(最好参考他们使用的其他应用程序)。

于 2009-01-14T02:46:41.713 回答
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); 
于 2009-01-13T18:55:08.593 回答
0

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

我在一个应用程序上这样做了,所有这样做的方法都是维护和调试的噩梦。事实是,这显然不是 Swing 的设计者想要实现的。

于 2009-01-13T19:18:34.710 回答
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");
}
于 2015-09-15T13:33:52.067 回答