Java KeyListener“;对象更新";

Java KeyListener“;对象更新";,java,swing,keylistener,Java,Swing,Keylistener,我有一个名为keylister的Keyboard类,它实现了keylister的方法 按键可以有4种状态(UP、ISUP、DOWN、ISDOWN),所有这些状态都表示它们是处于关闭状态,还是刚刚处于关闭状态 在每次更新键盘之前,我想将所有向上s更改为ISUPS,向下s更改为ISDOWNs 键盘类上有一个Update方法,但我不知道何时调用它(因为addKeyListener()函数似乎很神奇,只需不调用任何函数就可以工作[可能会启动线程]) 我如何知道何时调用Update方法?(就在键盘即将触发

我有一个名为
keylister
Keyboard
类,它实现了
keylister
的方法

按键可以有4种状态(
UP、ISUP、DOWN、ISDOWN
),所有这些状态都表示它们是处于关闭状态,还是刚刚处于关闭状态

在每次更新
键盘之前,我想将所有
向上
s更改为
ISUPS
向下
s更改为
ISDOWN
s

键盘类上有一个
Update
方法,但我不知道何时调用它(因为
addKeyListener()
函数似乎很神奇,只需不调用任何函数就可以工作[可能会启动线程])

我如何知道何时调用
Update
方法?(就在
键盘即将触发事件之前)

下面是
键盘
类本身:

package game.input;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashMap;
import java.util.Map;

enum KeyStatus
{
    DOWN, ISDOWN, UP, ISUP
}

public class Keyboard implements KeyListener
{
    private Map<Character, KeyStatus> keys;

    public Keyboard()
    {
        keys = new HashMap<Character, KeyStatus>();

        for (int i = 0; i < 256; i++)
        {
            keys.put((char)i, KeyStatus.ISUP);
        }
    }

    public void update() //This should be called after every event loop (how?)
    {
        for (Map.Entry<Character, KeyStatus> ks: keys.entrySet())
        {
            if (ks.getValue() == KeyStatus.UP)
                keys.put(ks.getKey(), KeyStatus.ISUP);

            else if (ks.getValue() == KeyStatus.DOWN)
                keys.put(ks.getKey(), KeyStatus.ISDOWN);
        }
    }

    public boolean keyDown(char i)
    {
        return (keys.get(i) == KeyStatus.DOWN || keys.get(i) == KeyStatus.ISDOWN);
    }

    public boolean onKeyDown(char i)
    {
        return (keys.get(i) == KeyStatus.DOWN);
    }

    public boolean keyUp(char i)
    {
        return (keys.get(i) == KeyStatus.UP || keys.get(i) == KeyStatus.ISUP);
    }

    public boolean onKeyUp(char i)
    {
        return (keys.get(i) == KeyStatus.UP);
    }


    @Override
    public void keyPressed(KeyEvent key)
    {
        keys.put(key.getKeyChar(), KeyStatus.DOWN);
    }

    @Override
    public void keyReleased(KeyEvent key)
    {
        keys.put(key.getKeyChar(), KeyStatus.UP);
    }

    @Override
    public void keyTyped(KeyEvent key)
    {
    }

}
package.input;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
导入java.util.HashMap;
导入java.util.Map;
枚举键状态
{
向下,向下,向上,向上
}
公共类键盘实现KeyListener
{
私有地图密钥;
公用键盘()
{
keys=newhashmap();
对于(int i=0;i<256;i++)
{
keys.put((char)i,KeyStatus.ISUP);
}
}
public void update()//应该在每个事件循环后调用它(如何调用?)
{
对于(Map.Entry ks:keys.entrySet())
{
if(ks.getValue()==KeyStatus.UP)
keys.put(ks.getKey(),KeyStatus.ISUP);
else if(ks.getValue()==KeyStatus.DOWN)
keys.put(ks.getKey(),KeyStatus.ISDOWN);
}
}
公共布尔键控(字符i)
{
return(keys.get(i)=KeyStatus.DOWN | | keys.get(i)=KeyStatus.ISDOWN);
}
公共布尔onKeyDown(字符i)
{
返回(keys.get(i)=KeyStatus.DOWN);
}
公共布尔键控(字符i)
{
return(keys.get(i)=KeyStatus.UP | | keys.get(i)=KeyStatus.ISUP);
}
公共布尔onKeyUp(字符i)
{
return(key.get(i)=KeyStatus.UP);
}
@凌驾
按下公共无效键(KeyEvent键)
{
keys.put(key.getKeyChar(),KeyStatus.DOWN);
}
@凌驾
公共无效密钥已释放(KeyEvent密钥)
{
keys.put(key.getKeyChar(),KeyStatus.UP);
}
@凌驾
public void键类型(KeyEvent键)
{
}
}

KeyListener
注册到组件,当发生某种
KeyEvent
时,
EventQueue
会通知该组件。
EventQueue
由平台特定的机制通知,该机制直接绑定到操作系统/本机层

Swing在侦听器方面通常使用。也就是说,您将侦听器附加到一个组件,该组件将在发生某些事情时通知您

您不应该“需要”调用任何方法来检查键的状态。相反,当触发
KeyEvent
时,会通知
KeyListener
(通过事件链)并通过
KeyListener
界面触发适当的事件

KeyListener
需要向屏幕上可见的、可以获得键盘焦点且在事件发生时具有焦点的组件注册

请查看以了解更多详细信息

你可能也会发现这很有用

KeyListener
存在焦点问题(只有当前可聚焦/聚焦的组件才能接收
KeyEvents
)。建议您改用

已更新

在一轮讨论后,我们总结出真正的问题是什么,我们得出结论,OP试图生成一个当前按下但已由游戏引擎处理的按键屏蔽列表,以避免按键重复触发更多更新

我们得出结论,OP应该生成一个“已处理”和“活动”的密钥列表

当触发按键事件时,键盘处理程序将检查按键是否存在于“已处理”列表中,如果存在,则忽略按键,否则将其置于活动列表中

当游戏引擎处理按键时,它扫描“活动”列表,采取行动并将每个按键置于“已处理”列表中


一旦密钥被释放,它将从处理列表中删除。

对不起,我理解您的上下状态,但ISUP和ISDOWN代表什么?它们似乎是多余的。另外,你有没有阅读过关于键绑定的内容,这些内容可能比KeyListener更好?@Hovercraftfullofeels up,DOWN=用户刚刚按下了键。ISUP,ISDOWN=键当前处于关闭状态。您在上面调用的不是状态,而是事件。我担心你的结构被破坏了。你想要的是两种状态,我称之为向上和向下,并指示键当前是向上还是向下。然后,您将侦听状态更改的事件。但是你不能让这个事件成为一种状态。@HovercraftFullOfEels虽然这通常是有意义的,但我正在写一个游戏。并非每个组件都可以访问
KeyListener
。这不是正确的方法吗?(将密钥的当前状态存储在一个数组中,当您得到一个DOWN事件时,更改数组中的密钥?[到DOWN,然后在一个循环后到ISDOWN])好的,回答这个问题,您的UP状态应该持续多久?什么时候应该从UP变为ISUP,通过什么机制?你用的是哪种定时器?答案是,这是毫无意义的。同样,你的逻辑和结构是错误的。你的建议不是正确的方法,绝对不是。事实上,你目前的全部问题是你没有这个机制,事实上你不需要它,也不想要它。我把所有这些东西都记下来了,这不是我的问题。我只是想更新密钥数组的状态,以表示密钥的长度