javaswingkey-bindingsabstract-action

Using Keybinding


I'm doing some very basic coding, just trying to learn the basic concepts behind keybinding. It all seems very straightforward but there's something wrong with my logic or structure that is keeping my code from executing the way I want it to.

Here is my code

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

So, it should be pretty simple. As you can see I'm just trying to make it print out "enter pressed" whenever you press enter, but it isn't printing out anything (unless you click the button also shown in the code above). Also, in eclipse, the EnterAction class is underlined in yellow, I think it may not be being called right, but I don't know why it wouldn't be.

Any help is appreciated, thanks.


Solution

  • The immediate issue I can see is with the following statement

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

    KeyStroke.getKeyStroke("s") is going to return null. The requirements for the String passed to this method are very particular and not well documented (IMHO).

    You could use KeyStroke.getKeyStroke("S") instead, but I prefer to use KeyStroke.getKeyStroke(KeyEvent.VK_S, 0) as there is no chance of ambiguity in the statement.

    I would also recommend that you define the focus boundaries as well for the input map...

    Instead of panel.getInputMap(), try using panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) to ensure that the key event will be triggered if the window is focused

    Take a look at JComponent#getInputMap for more details.

    If you haven't already done so, you should also take a look at How to use Key Bindings