0

在 Nimbus L&F 中,当按下 Enter 键时,如果一个按钮具有焦点,则无论另一个按钮是否已设置为默认值,都会单击该按钮,如下所示:

getRootPane().setDefaultButton(myButton);

此外,使用键绑定不起作用:

Action clickDefault = new AbstractAction("clickDefault") {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Got Here");
        getRootPane().getDefaultButton().doClick();
    }
};
InputMap im = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
im.put(enter, "defaultButton");
getRootPane().getActionMap().put("defaultButton", clickDefault);

我什至从未看到“到达这里”消息,但如果我绑定到另一个 KeyStroke,例如“P”,它会按预期运行。因此,似乎 Enter 键在到达此事件处理程序之前已被捕获。

我还尝试修改 UIDefaults:

    im = (InputMap) UIManager.getDefaults().get("Button.focusInputMap");
    im.put(enter, null);
    im.put(enterRelease, null);

那也失败了。任何人有任何想法如何做到这一点?

---更新---

进一步调查显示,JButton 的 InputMap 包含 {"pressed Enter": "pressed", "released ENTER": "released"} (以及 SPACE 的绑定)。相关组件的键绑定具有比 RootPane 更高的优先级。有关解决问题的代码,请参见下面的答案。

4

2 回答 2

0

我不使用 Nimbus LAF,所以我不确定它是如何工作的。

使用 Windows LAF,默认按钮会自动更改为当前具有焦点的按钮。这由具有焦点的按钮上的较暗边框表示。如果焦点不在按钮上,则默认按钮上的较暗边框将被重置。

在 Windows 中,您可以使用以下方法禁用此行为:

UIManager.put("Button.defaultButtonFollowsFocus", Boolean.FALSE);

现在,较暗的边框将保留在默认按钮上,并且 Enter 键将激活默认按钮。仍然可以使用空格键单击具有焦点的按钮。

于 2011-03-03T04:45:15.813 回答
0

好的,终于弄清楚了如何按照我的意愿进行这项工作。这是我正在使用的代码:

public class Main {
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {

            // Use Nimbus if it's available and we're not on Mac OSX
            if (!System.getProperty("os.name").equals("Mac OS X")) {
                try {
                    for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                        if ("Nimbus".equals(info.getName())) {
                            UIManager.setLookAndFeel(info.getClassName());

                            ((InputMap) UIManager.get("Button.focusInputMap"))
                                    .put(KeyStroke.getKeyStroke("pressed ENTER"), null);
                            ((InputMap) UIManager.get("Button.focusInputMap"))
                                    .put(KeyStroke.getKeyStroke("released ENTER"), null);

                            break;
                        }
                    }
                } catch (Exception e) {
                    // Default Look and Feel will be used
                }
            }

            MainWindow mainWindow = new MainWindow();
            mainWindow.setVisible(true);
        }
    });
}

} // 结束类 Main

我发现的一件重要的事情是必须在设置外观和感觉之后对 InputMap(s) 进行更新。我不知道在搞砸这些事情时需要这样做,但话又说回来,我对整个外观和感觉业务都是新手。

于 2011-03-03T05:34:33.450 回答