2

无需发布太多代码,简而言之,我有一个行为有趣的 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 分钟并重新运行程序,该错误就会消失:/

编辑:(忘记发布 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;
    }

}
4

2 回答 2

4

这...

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

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

JDK中没有这样DefaultKeyEventDispatcher的类,因此您必须使用自定义版本,这意味着我们将不知道问题究竟是什么,因为我们既无法复制它,也无法研究它。

如果不知道您要达到什么目标,就不可能提供准确的指导,但您可能希望从如何编写关键监听器开始

于 2012-12-26T08:01:19.120 回答
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
            }
        });
于 2012-12-26T08:42:19.157 回答