Java中的键侦听器/键绑定 [英] Key listeners/key bindings in Java

查看:64
本文介绍了Java中的键侦听器/键绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我该如何编码一个事件,该事件在按下键(特别是空格键)时开始,在按住 键时继续运行,并且仅在释放键时才停止?我正在尝试模拟在粗糙表面上移动的带轮对象.我尝试使用原始的KeyListener方法,但是问题是,当我按住空格键时,要模拟的对象会反复停止和启动.我听说可能的解决方案是键绑定,但是即使阅读了有关它的Java教程,我仍然不了解它们.

How do I code an event that starts when a key (specifically the space bar) is pressed, continues running when the key is held, and only stops when the key is released? I'm trying to simulate a wheeled object that moves across a rough surface. I've tried using the original KeyListener methods but the problem is, when I hold the space bar the object I'm simulating repeatedly stops and starts. I've heard a possible solution is key bindings but I still don't understand them even after reading the Java tutorial about it.

这是用于仿真的绘画方法(由每10毫秒休眠的线程控制一次):

Here's the paint method used for the simulation (controlled by a Thread which sleeps every 10 milliseconds):

public void paint(Graphics g)
{

    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    Shape roadsurface = new Rectangle2D.Float(0, 85, 1000, 200);
    g2.setColor(Color.BLACK);
    g2.setStroke(new BasicStroke(10));
    g2.draw(roadsurface);
    g2.setColor(new Color(102, 102, 153));
    g2.fill(roadsurface);
    Image carimage = Toolkit.getDefaultToolkit().getImage("cargrey.png");
    g2.drawImage(carimage, x_pos, y_pos, 60, 30, this);
    g2.finalize();
}

这是用于更改x_pos的方法(假定未声明的变量已在类主体中声明):

And here's the methods used to change x_pos (variables not declared are assumed to have been declared in the class body):

public void accelerate()
{
    do 
    { acc = 15.0 - t;
    vel = ( t * 15.0)  -  ( 0.5 * Math.pow(t, 2.0) );
    disp = ( 0.5 * 15.0 * Math.pow(t, 2.0) ) - ( (1.0/6.0) * Math.pow(t, 3.0) ); 
    x_pos = (int)disp;  
    t += 0.01; break;} while (acc > 0);
    while (acc <= 0)
    { acc = 0;
    disp = t * vel; 
    x_pos = (int)disp;  
    t += 0.01;
    }
}
public void brake(double vel, double disp)
{
    double u = 0;
    double disp2;
    while (vel > 0)
    { 
    disp2 = (vel * u) + (0.5 * -100 * Math.pow(u, 2.0) );
    vel = vel + (-100 * u); 
    x_pos = (int)(disp + disp2);    
    u += 0.01;
    t += 0.01; break;}
    while (vel <= 0)
    {
        u += 0.01;
        t += 0.01;      
    }
}   

这是我最初的想法:

 class Key1 extends Thread implements KeyListener
{
Track g;
boolean keyIsPressed;
Key1(Track g)
{
    this.g = g;
}
public void keyTyped(KeyEvent ke) {}
public void keyPressed(KeyEvent ke)
{
    if (ke.getKeyCode() == KeyEvent.VK_SPACE)
        keyIsPressed = true;
}
public void keyReleased(KeyEvent ke)
{
    if (ke.getKeyCode() == KeyEvent.VK_SPACE)
        keyIsPressed = false;
}
public void run() 
{
    while (keyIsPressed)
    {
    g.repaint();
    g.accelerate();
    try
    {
        Thread.sleep(10);
    }
    catch (InterruptedException ex)
    {
        // swallowed
    }
    while (!keyIsPressed)
    {
    g.repaint();
    g.brake(g.vel, g.disp);
    try
    {
        Thread.sleep(10);
    }
    catch (InterruptedException ex)
    {
        // swallowed
    }
}

}

推荐答案

最好和最常见的方法之一是为每个映射的键都有一个标志.当按下它(由KeyEvent检测)时,该标志设置为true.释放后(也由KeyEvent检测到),该标志设置为false.

One of the best and most common approaches is to have a flag for each mapped key. When it is pressed (detected by a KeyEvent), the flag is set to true. When it is released (also detected by a KeyEvent), the flag is set to false.

应用程序状态(由另一个线程定期检查)不是由Key状态或事件决定,而是由标志状态决定.

The application states (periodically checked by another thread) would be determined not by the Key state or event, but by the flag state.

这种简单的方法避免了由重复键设置引起的影响.

This simple approach avoids the implications that are caused by key repetition setups.

这篇关于Java中的键侦听器/键绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆