【问题标题】:How to modify Nimbus L&F to activate the default button when pressing the Enter key?如何修改 Nimbus L&F 以在按下 Enter 键时激活默认按钮?
【发布时间】:2011-03-02 22:57:52
【问题描述】:

在 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 包含 {"pressed Enter": "pressed", "released ENTER": "released"}(以及 SPACE 的绑定)。相关组件的键绑定具有比 RootPane 更高的优先级。有关解决问题的代码,请参阅下面的答案。

【问题讨论】:

    标签: java swing nimbus


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 不幸的是,这似乎不适用于 Nimbus。实际上,Nimbus Defaults 页面:link 表示 Button.defaultButtonFollowsFocus 设置为 False。我还对 getDefaults() 进行了检查以验证情况是否如此。
    【解决方案2】:

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

    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-12-26
      • 1970-01-01
      • 1970-01-01
      • 2016-04-23
      • 2016-06-27
      • 1970-01-01
      • 1970-01-01
      • 2020-01-18
      • 1970-01-01
      相关资源
      最近更新 更多