使用密钥绑定

时间:2013-07-30 01:06:39

标签: java swing key-bindings abstract-action

我正在做一些非常基本的编码,只是想学习键绑定背后的基本概念。这一切似乎都非常简单,但是我的逻辑或结构出现了问题,导致我的代码无法按照我想要的方式执行。

这是我的代码

public class Board {

ButtonListener buttonlistener;  
EnterAction enterAction;

public Board(){

    JFrame skeleton = new JFrame();
    skeleton.setDefaultCloseOperation(EXIT_ON_CLOSE);
    skeleton.setVisible(true);
    skeleton.setSize(400, 400);

    buttonlistener = new ButtonListener();
    enterAction = new EnterAction();

    JPanel panel = new JPanel();
    panel.setBackground(Color.BLACK);

    JButton button = new JButton("button");
    button.addActionListener(buttonlistener);
    panel.add(button);
    skeleton.add(panel);        
    panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");
    panel.getActionMap().put("doEnterAction", enterAction);

}

public class ButtonListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent arg0) {     
        System.out.println("button pressed");
    }       
}

public class EnterAction extends AbstractAction{
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("enter pressed");    
    }       
}

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

所以,它应该很简单。正如你所看到的那样,每当你按下回车键时,我只是想让它打印出来“按下”,但它不打印任何东西(除非你点击上面代码中显示的按钮)。另外,在eclipse中,EnterAction类以黄色下划线,我认为它可能没有被正确调用,但我不知道为什么它不会。

感谢任何帮助,谢谢。

3 个答案:

答案 0 :(得分:4)

更改

panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");

panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("S"), "doEnterAction");

另外

skeleton.setDefaultCloseOperation(EXIT_ON_CLOSE);

参数必须为JFrame.EXIT_ON_CLOSE或只需输入数字3

答案 1 :(得分:3)

我能看到的直接问题是以下声明

panel.getInputMap().put(KeyStroke.getKeyStroke("s"), "doEnterAction");

KeyStroke.getKeyStroke("s")将返回null。传递给此方法的String的要求非常特殊,没有详细记录(恕我直言)。

您可以使用KeyStroke.getKeyStroke("S")代替,但我更倾向于使用KeyStroke.getKeyStroke(KeyEvent.VK_S, 0),因为声明中不存在歧义。

我还建议你为输入地图定义焦点边界......

尝试使用panel.getInputMap()代替panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW),以确保在窗口聚焦时触发关键事件

请查看JComponent#getInputMap了解详情。

如果您尚未这样做,还应该查看How to use Key Bindings

答案 2 :(得分:2)

我认为Azad和MadProgrammer是正确的,我只需要做一个更简单的改变,除了他们建议让程序运行。我已经为你编写了三个项目作为代码注释:(复制和粘贴,你很高兴)。

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class Board {

    ButtonListener buttonlistener;
    EnterAction enterAction;

    public Board() {

        JFrame skeleton = new JFrame();
        //Change #1 below 
        skeleton.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        skeleton.setVisible(true);
        skeleton.setSize(400, 400);

        buttonlistener = new ButtonListener();
        enterAction = new EnterAction();

        JPanel panel = new JPanel();
        panel.setBackground(Color.BLACK);

        JButton button = new JButton("button");
        button.addActionListener(buttonlistener);
        panel.add(button);
        skeleton.add(panel);
        //Change #2 below
        panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke("S"), "doEnterAction");
        panel.getActionMap().put("doEnterAction", (Action) enterAction);

    }

    public class ButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            System.out.println("button pressed");
        }
    }

    public class EnterAction extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("enter pressed");
        }
    }

    public static void main(String[] args) {
        new Board();
    }
    //Change #3 below
}

这是截图: enter image description here