Search code examples
javaswingjbutton

Java Swing issue with JButton selecting/ActionPerformed


I'm currently developing a maze game and I have a setup where the user can change the controls, in order to do that there are several buttons corresponding to each game control (moving...etc). To change a game control the user must click the button, then press a key and after that the control key should have been updated such as the button text, it should appear like this: UP_MOVEMENT = NEW_CONTROL. So if I want to change the UP_MOVEMENT key to the "P" key for example, I should click one time on the UP_MOVEMENT button, then press the "P" key and it should be done. The problem is that once I click the button and after pressing the wanted key to see the button's text change I have to click on it again and I want it to be instantaneous. Here is a part of my code:

public JPanel createKeyBidings() {
    JPanel buttonBox = new JPanel();

    JButton upKey = new JButton("UP="+ KeyEvent.getKeyText(settings.getUp()));
    JButton downKey = new JButton("DOWN="+ KeyEvent.getKeyText(settings.getDown()));
    JButton leftKey = new JButton("LEFT="+KeyEvent.getKeyText(settings.getLeft()));
    JButton rigthKey=new JButton("RIGTH="+KeyEvent.getKeyText(settings.getRight()));
    JButton shoot = new JButton("SHOOT");

    upKey.addKeyListener(this);
    downKey.addKeyListener(this);
    leftKey.addKeyListener(this);
    rigthKey.addKeyListener(this);
    shoot.addKeyListener(this);

    upKey.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {

            if (keyPressed != null) {
                settings.setUp(keyPressed.getKeyCode());
                upKey.setText("UP=" + keyPressed.getKeyChar());
            }                   
        }
    });

    buttonBox.add(upKey);
    buttonBox.add(downKey);
    buttonBox.add(leftKey);
    buttonBox.add(rigthKey);
    buttonBox.add(shoot);

    return buttonBox;
}

Solution

  • If you want to react based upon a KeyPressed event, then you should consider placing the logic within the KeyListener methods. In other words, rather than keeping the last key pressed in the keyPressed variable, keep a buttonPressed variable that is set every time the ActionListener is fired. When a Key is pressed, check which button was last pressed and react accordingly. If you wish to only react when the button is held (pressed and before it is released rather than after it is released - when an ActionListener is fired), then in the KeyListener you can evaluate which button is pressed by checking the button is pressed through it's model (eg if ( myButton.getModel().isPressed() )