KeyListener - 调用keyPressed但未调用KeyReleased

时间:2012-12-26 07:53:52

标签: java swing jpanel keylistener

如果没有发布太多代码,简而言之,我有一个表现得很有趣的KeyListener

我有一个JPanel,我实现了我的KeyListener:

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

我以前也尝过这样的话:

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

主要问题:

问题发生时,系统会调用public void keyPressed(KeyEvent e) 始终,但会调用public void keyReleased(KeyEvent e) 从不

当它发生时似乎是不可预测的,因为其他时候一切都按照它应该发挥作用。如果我等待大约5分钟并重新运行程序,那么这个bug就会消失:/

编辑:(忘了发布DefaultKeyEventDispatcher代码)

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

编辑2. KeyBoard类的样本

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

}

2 个答案:

答案 0 :(得分:4)

此...

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

不是注册KeyListener的方法。这将允许您查看应用程序处理的所有密钥。 KeyEventDispatcher没有keyPressedkeyReleased方法,只有dispatchKeyEvent

JDK中没有DefaultKeyEventDispatcher这样的类,所以你必须使用自定义版本,这意味着我们不知道问题到底是什么,因为我们既不能复制也不能研究它。

在不知道你想要达到的目的的情况下,无法提供准确的指导,但你可能想从How to Write a Key Listener开始

答案 1 :(得分:0)

使用密钥处理,如

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