java - 如何更改 ActionListener 的聚焦 JButton 的默认键绑定(bind)?

标签 java swing key-bindings keystroke

调用聚焦的 JButton 的 ActionListener 的默认键是 Space,但如何将其更改为另一个键?

最佳答案

你需要:

  1. 更新组件的 InputMap 以添加新的 KeyStroke 以指向现有的 Action

    <
  2. 防止 InputMap 中现有的 KeyStroke 调用现有的 Action。如果您希望能够使用两个 KeyStrokes 来调用默认操作,则此步骤是可选的。

注意:

  1. 您需要为“按下”和“释放”键更新 InputMap
  2. 必须按上述顺序更新 InputMap

修改 Hovercrafts 示例中的代码,您可以这样做:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class AlterSpaceBinding extends JPanel {
    private JButton myButton = new JButton("My Button -- associate with \"B\" key");

    public AlterSpaceBinding() {
        myButton = alterDefaultButtonAction(myButton, KeyEvent.VK_B);
        myButton.addActionListener(l -> {
            System.out.println("button pressed");
        });
        add(myButton);
        add(new JButton("Second Button -- no change"));

    }

    public static JButton alterDefaultButtonAction(JButton button, int desiredKeyCode) {

        // get the correct InputMap
        InputMap inputMap = button.getInputMap(JComponent.WHEN_FOCUSED);

        // get both key strokes for space key, but pressed and released
        KeyStroke spaceKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false);
        KeyStroke spaceKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true);

        // key stroke for desired key code
        KeyStroke desiredKeyPressed = KeyStroke.getKeyStroke(desiredKeyCode, 0, false);
        KeyStroke desiredKeyReleased = KeyStroke.getKeyStroke(desiredKeyCode, 0, true);

        // share the Action with desired KeyStroke
        inputMap.put(desiredKeyPressed, inputMap.get(spaceKeyPressed));
        inputMap.put(desiredKeyReleased, inputMap.get(spaceKeyReleased));

        // disable original KeyStrokes (optional)
        inputMap.put(spaceKeyPressed, "none");
        inputMap.put(spaceKeyReleased, "none");

        return button;
    }

    private static void createAndShowGui() {
        AlterSpaceBinding mainPanel = new AlterSpaceBinding();

        JFrame frame = new JFrame("AlterSpaceBinding");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

上面的代码不需要:

  1. 创建一个虚拟Action
  2. 操纵ActionMap

查看 Using Key Bindings有关操作组件的 InputMapActionMap 的更多示例。

注意:

更有可能的情况是,您想要更新应用程序中所有按钮的绑定(bind),以便拥有一个通用的 LAF。在这种情况下,您可以从所有 JButton 共享的 UIManager 更新“focusInputMap”:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SSCCE extends JPanel
{
    SSCCE()
    {
        add( new JButton("Button 1" ) );
        add( new JButton("Button 2" ) );
        add( new JButton("Button 3" ) );
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );

        // Update shared InputMap

        InputMap inputMap = (InputMap)UIManager.get("Button.focusInputMap");
        int desiredKeyCode = KeyEvent.VK_B; // type "b" to invoke Action on button

        KeyStroke spaceKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false);
        KeyStroke spaceKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true);

        // key stroke for desired key code
        KeyStroke desiredKeyPressed = KeyStroke.getKeyStroke(desiredKeyCode, 0, false);
        KeyStroke desiredKeyReleased = KeyStroke.getKeyStroke(desiredKeyCode, 0, true);

        // share the Action with desired KeyStroke
        inputMap.put(desiredKeyPressed, inputMap.get(spaceKeyPressed));
        inputMap.put(desiredKeyReleased, inputMap.get(spaceKeyReleased));

        // optionally disable original KeyStrokes
        inputMap.put(spaceKeyPressed, "none");
        inputMap.put(spaceKeyReleased, "none");
    }

    public static void main(String[] args) throws Exception
    {
        java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }
}

关于java - 如何更改 ActionListener 的聚焦 JButton 的默认键绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54131405/

相关文章:

Java 无法下载完整文件

java - 拖动对象时自动滚动 JScrollpane

java - keyBinding 中的焦点导航

java - 使用 Collectors.toMap 或 groupingBy 在 Map 中收集映射操作的结果

java - 用于在 Java 中创建 2D 形状的高级 API

java - 从另一个单独的类访问公共(public)非静态对象

java - 在Swing中,如何将计算后的结果自动加载到框架中?

xcode4 - Xcode 重复行

java - Eclipse:Ctrl+Shift+Right 不正确

java - 从 RestulSet 表编辑 JTable