Key binding does not work

主宰稳场 提交于 2019-12-11 04:16:49

问题


I have JButton performing some action via ActionListener. After I try to use Action to bind a keyboard shortcut (following this), mouse click on button works, but no reaction to keyboard.

Code Before

Button created within a panel, actionListener added.

private FooActionListener actionListener = new FooActionListener();

buttonLeft = new JButton("Left");
up.addActionListener(actionListener);

Then, actionPerformed method within FooActionListener class outside the main class:

public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();
    if (source == buttonLeft) { thing.move(Direction.LEFT); }
}

Code After

final String leftText = "Left";
final Action left = new AbstractAction() {

    @Override
    public void actionPerformed(ActionEvent e) {
        thing.move(Direction.LEFT);
    }
};

buttonLeft = new JButton(left);
buttonLeft.setText(leftText);
KeyStroke keyLeft = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0);
buttonLeft.getInputMap(buttonLeft.WHEN_IN_FOCUSED_WINDOW).put(keyLeft,
    "Left");
buttonLeft.getActionMap().put("Left", left );

Update: I am not quite sure that new code actually performs with the mouse as it should. Let’s say the object supposed to move 25 pixels by one click, and it does in the original code. But with the new action it seems that it moves twice or even trice with each click, which suggests some weird behavior of an action.


回答1:


It's possible that the button is absorbing you mappings, I would, however, do it slightly differently.

Because you've used an Action (correctly), you movement logic is mostly centralised already.

I would simply apply the mappings to the main container instead.

public class TestKeybindings01 {

    public static void main(String[] args) {
        new TestKeybindings01();
    }

    public TestKeybindings01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JLabel label;
        private JButton left;
        private JButton right;

        public TestPane() {

            label = new JLabel("Make a choice");
            label.setHorizontalAlignment(JLabel.CENTER);

            LeftAction leftAction = new LeftAction(label);
            RightAction rightAction = new RightAction(label);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");

            ActionMap am = getActionMap();
            am.put("left", leftAction);
            am.put("right", rightAction);

            left = new JButton(leftAction);
            right = new JButton(rightAction);

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.gridwidth = 2;
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            add(label, gbc);

            gbc.gridy++;
            gbc.gridwidth = 1;
            add(left, gbc);
            gbc.gridx++;
            add(right, gbc);


        }

    }

    public abstract class AbstractDirectionAction extends AbstractAction {

        private JLabel label;

        public AbstractDirectionAction(JLabel label) {
            this.label = label;
        }

        public JLabel getLabel() {
            return label;
        }

        public void setDirection(String text) {
            getLabel().setText(text);
        }

    }

    public class LeftAction extends AbstractDirectionAction {

        public LeftAction(JLabel label) {
            super(label);
            putValue(NAME, "<<");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            setDirection("Left");
        }

    }

    public class RightAction extends AbstractDirectionAction {

        public RightAction(JLabel label) {
            super(label);
            putValue(NAME, ">>");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            setDirection("Right");
        }

    }

}


来源:https://stackoverflow.com/questions/13888162/key-binding-does-not-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!