Corey
Corey

Reputation: 152

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.

Upvotes: 1

Views: 150

Answers (3)

grepit
grepit

Reputation: 22382

I think Azad and MadProgrammer are correct, I only had to make one more simple change in addition to what they recommended to get the program running. I have numbered the three items for you as a comment in the code: (copy and paste and you are good to go).

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
}

here is the screenshot: enter image description here

Upvotes: 2

Azad
Azad

Reputation: 5055

Change

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

To

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

Also

skeleton.setDefaultCloseOperation(EXIT_ON_CLOSE);

the parameter must be JFrame.EXIT_ON_CLOSE or just put number 3.

Upvotes: 4

MadProgrammer
MadProgrammer

Reputation: 347184

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

Upvotes: 3

Related Questions