Kenny Cason
Kenny Cason

Reputation: 12328

KeyListener - keyPressed called but KeyReleased not called

Without posting too much code, in short I have a KeyListener that is behaving funny

I have a JPanel and I implement my KeyListener like this:

keyboard = new KeyBoard(); // implements KeyListener
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new DefaultKeyEventDispatcher(keyboard));

also I have previously tried it like this:

theJPanel.addKeyListener(myKeyListener);
theJPanel.setFocusable(true);
theJPanel.requestFocusInWindow();

The main problem:

When the problem occurs, public void keyPressed(KeyEvent e) always gets called, but public void keyReleased(KeyEvent e) never gets called.

It seems to be unpredictable when it happens as other times everything functions as it should. The bug literally goes away if I just wait about 5 minutes and rerun the program :/

Edit: (Forgot to post the DefaultKeyEventDispatcher code)

package game.keyboard;

import java.awt.KeyEventDispatcher;
import java.awt.event.KeyEvent;

public class DefaultKeyEventDispatcher implements KeyEventDispatcher {

    private KeyBoard keyboard;

    public DefaultKeyEventDispatcher(KeyBoard keyboard) {
        this.keyboard = keyboard;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent e) {
        if (e.getID() == KeyEvent.KEY_PRESSED) {
            keyboard.keyPressed(e);
        } else if (e.getID() == KeyEvent.KEY_RELEASED) {
            keyboard.keyReleased(e);
        } else if (e.getID() == KeyEvent.KEY_TYPED) {
            keyboard.keyTyped(e);
        }
        return false;
    }
}

Edit 2. A sample from the KeyBoard Class

package game.keyboard;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyBoard implements KeyListener {

    private boolean[] keys;

    private long[] keyPressedTime;

    public KeyBoard() {
        keys = new boolean[KeyEvent.KEY_LAST];
        keyPressedTime = new long[KeyEvent.KEY_LAST];
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        keys[e.getKeyCode()] = true;
        keyPressedTime[e.getKeyCode()] = System.currentTimeMillis();
    }

    @Override
    public void keyReleased(KeyEvent e) {
        keys[e.getKeyCode()] = false;   
        keyPressedTime[e.getKeyCode()] = -1;
    }

    public long keyPressedTime(int k) {
        return keyPressedTime[k];
    }

    public boolean isKeyPressed(int k) {
        return keys[k];
    }

    public boolean isKeyCombo(int[] k) {
        boolean ret = true;
        for(int i = 0;i < k.length; i++) {
            ret &= keys[k[i]];
        }
        return ret;
    }

}

Upvotes: 2

Views: 7943

Answers (2)

Nidhish Krishnan
Nidhish Krishnan

Reputation: 20741

use Key handling like

textfield.addKeyListener(new  KeyListener(){

            @Override
            public void keyTyped(KeyEvent e) 
            {
               //Key Type Action
               //example
               int code = e.getKeyCode();
               switch(code)
               {
                case KeyEvent.VK_UP:
                {
                JOptionPane.showMessageDialog(rootPane,"UP Key pressed");
                break;
                }

                case KeyEvent.VK_DOWN:
                {
                   JOptionPane.showMessageDialog(rootPane,"DOWN Key pressed");
                  break;
                }

                case KeyEvent.VK_LEFT:
                {
                  JOptionPane.showMessageDialog(rootPane,"LEFT Key pressed");
                  break;
                }

                case KeyEvent.VK_RIGHT:
                {
                  JOptionPane.showMessageDialog(rootPane,"RIGHT Key pressed");
                  break;
                }
               }
            }

            @Override
            public void keyPressed(KeyEvent e) {
                // key pressed action
            }

            @Override
            public void keyReleased(KeyEvent e) {
                // key released action
            }
        });

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347194

This...

keyboard = new KeyBoard(); // implements KeyListener
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new DefaultKeyEventDispatcher(keyboard));

Is not the way to register a KeyListener. This will allow you to see ALL the keys been processed by the application. KeyEventDispatcher does not have keyPressed or keyReleased methods, only dispatchKeyEvent.

There is no such class as DefaultKeyEventDispatcher in the JDK so you must be using a customized version, meaning, we will have no idea about what the problem actually is, because we can neither replicate it or study it.

Without knowing what it is you are trying to achieve, it's impossible to provide accurate guidance, but you might like to start with How to Write a Key Listener

Upvotes: 4

Related Questions