键绑定不起作用

时间:2012-12-15 00:32:29

标签: java swing key-bindings

我让JButton通过ActionListener执行一些操作。在我尝试使用Action来绑定键盘快捷键(在this之后)之后,鼠标单击按钮可以正常工作,但对键盘没有反应。

以前的代码

在面板中创建的按钮,添加了actionListener。

private FooActionListener actionListener = new FooActionListener();

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

然后,在主类之外的FooActionListener类中的actionPerformed方法:

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

之后的代码
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 );

更新:我不太确定新代码实际上是否应该使用鼠标。假设该对象应该通过单击移动25个像素,并且它在原始代码中执行。但是通过新动作,它似乎每次点击都会移动两次甚至三次,这表明一个动作有些奇怪的行为。

1 个答案:

答案 0 :(得分:2)

按钮可能会吸引你的映射,但是,我会稍微改变一下。

因为您已经使用了Action(正确),所以您的移动逻辑大部分已经集中化了。

我只是将映射应用到主容器中。

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

    }

}