简体   繁体   English

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

[英]How to modify Nimbus L&F to activate the default button when pressing the Enter key?

In the Nimbus L&F when one presses the Enter key, if a button has focus, that button is clicked whether or not another button has been set as default as in: 在Nimbus L&F中,当按下Enter键时,如果某个按钮具有焦点,则无论是否已将另一个按钮设置为默认按钮,都会单击该按钮,如下所示:

getRootPane().setDefaultButton(myButton);

Also, using Key Binding does not work: 同样,使用键绑定不起作用:

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

I never even see the "Got Here" message, though if I bind to another KeyStroke, such as "P" it functions as expected. 我什至都看不到“ Got Here”消息,尽管如果我绑定到另一个按键,例如“ P”,它会按预期运行。 So it would seem that the Enter key is being captured before it gets to this event handler. 因此,看来Enter键在到达此事件处理程序之前已被捕获。

I also tried modifying the UIDefaults: 我也尝试过修改UIDefaults:

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

That failed as well. 那也失败了。 Anyone have any ideas how to accomplish this? 任何人有任何想法如何做到这一点?

--- Update --- - 更新 -

Further investigation revealed that the InputMap for JButton contains {"pressed Enter": "pressed", "released ENTER": "released"} (as well as bindings for SPACE). 进一步的调查显示,JButton的InputMap包含{“ pressed Enter”:“ pressed”,“ released ENTER”:“ released”}(以及SPACE的绑定)。 The Key Binding of the Component in question has higher precedence than the RootPane's. 有问题的组件的键绑定具有比RootPane更高的优先级。 See my answer below for code that resolves the problem. 请参阅下面的答案,以获取解决问题的代码。

I don't use the Nimbus LAF so I'm not sure how it works. 我不使用Nimbus LAF,所以不确定其工作原理。

With the Windows LAF the default button automatically changes to be the button that currently has focus. 使用Windows LAF,默认按钮会自动更改为当前具有焦点的按钮。 This is indicated by are darker border on the button that has focus. 这由具有焦点的按钮上的深色边框指示。 If focus is not on a button, then the darker border will be reset on the default button. 如果焦点不在按钮上,则较暗的边框将在默认按钮上重置。

In Windows you can disable this behaviour by using: 在Windows中,您可以通过使用以下方式禁用此行为:

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

Now the darker border will remain on the default button and the Enter key will activate the default button. 现在,较暗的边框将保留在默认按钮上,而Enter键将激活默认按钮。 The button with focus can still be clicked by using the space bar. 使用空格键仍可以单击具有焦点的按钮。

Ok, finally figured out how to make this work as I wanted. 好的,终于弄清楚了如何按照我的意愿进行这项工作。 Here's the code I'm using: 这是我正在使用的代码:

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

} // end class Main } //结束类Main

One important thing I figured out was that the updates to the InputMap(s) must be made AFTER setting the Look and Feel. 我发现的一件重要事情是,必须在设置外观后对InputMap进行更新。 I wasn't aware that was required when messing with these things, but then again, I'm new at this whole Look and Feel business. 我不知道这些东西弄乱了是不是必需的,但是话又说回来,我在整个外观业务上都是新手。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM