按Enter键时如何修改Nimbus L& F以激活默认按钮?

时间:2011-03-02 22:57:52

标签: java swing nimbus

在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);

我甚至从未看到“Got Here”消息,但如果我绑定到另一个KeyStroke,例如“P”,它将按预期运行。因此,似乎在进入此事件处理程序之前捕获了Enter键。

我也尝试修改UIDefaults:

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

那也失败了。任何人都有任何想法如何实现这一目标?

--- 更新 ---

进一步调查显示,JButton的InputMap包含{“按Enter”:“按下”,“释放ENTER”:“已发布”}(以及SPACE的绑定)。有问题的组件的键绑定优先于RootPane的优先级。有关解决问题的代码,请参阅下面的答案。

2 个答案:

答案 0 :(得分:0)

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

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

在Windows中,您可以使用以下命令禁用此行为:

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

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

答案 1 :(得分: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);
        }
    });
}

} //结束课主

我想到的一件重要事情是,在设置外观之后必须对InputMap进行更新。我不知道在弄乱这些东西时是必需的,但话又说回来,我是整个外观和生活的新手。