4

好的,所以我在这里很沮丧。这里的这段代码只是一个非常简单的移动JComponent。

奇怪的是,当我完全没有改变任何东西时,keyPressed 事件会非常不一致。我启动程序,有时它会工作,我的球会在屏幕上移动。另一方面,我将关闭它并打开它而不更改任何内容,它将无法正常工作。我不认为焦点在这里是一个问题,尽管我真的不太了解它。我不知道是怎么回事。

任何帮助,将不胜感激。我只是不明白这个程序怎么会如此不一致地失败和成功。

这是我在角色类中的代码,因为我不认为只给你一个片段会有帮助。不知道是不是只有我一个人,还是什么的,如果你想编译看看,就去吧。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


public class Character extends JComponent implements KeyListener
{    
Timer timer = new Timer(5, new TimeListener());
private int x = 250;
private int y = 300;
char whichTimer;


public Character()
{
    addKeyListener(this);
    setFocusable(true);
    requestFocusInWindow();
    repaint();
}

public void keyReleased(KeyEvent e)
{
    if(e.getKeyCode() == KeyEvent.VK_W)
    {
        timer.stop();
    }
    if(e.getKeyCode() == KeyEvent.VK_A)
    {
        timer.stop();
    }
    if(e.getKeyCode() == KeyEvent.VK_S)
    {
        timer.stop();
    }
    if(e.getKeyCode() == KeyEvent.VK_D)
    {
        timer.stop();
    }
}
public void keyPressed(KeyEvent e)
{

    if(e.getKeyCode() == KeyEvent.VK_W)
    {
        timer.stop();
        whichTimer = 'W';
        timer.start();
    }

    if(e.getKeyCode() == KeyEvent.VK_A)
    {
        timer.stop();
        whichTimer = 'A';
        timer.start();
    }
    if(e.getKeyCode() == KeyEvent.VK_S)
    {
        timer.stop();
        whichTimer = 'S';
        timer.start();
    }
    if(e.getKeyCode() == KeyEvent.VK_D)
    {
        timer.stop();
        whichTimer = 'D';
        timer.start();
    }
}
public void keyTyped(KeyEvent e)
{

}
protected void paintComponent(Graphics g)
{
    super.paintComponent(g);
     Graphics2D g2d = (Graphics2D) g;

       // g2d.drawImage(fatsprite, x-10, y-10, null);
    g.setColor(Color.BLACK);
    g.fillOval(x-10, y-10, 20, 20);

}

class TimeListener implements ActionListener
{
    public void actionPerformed(ActionEvent e) 
    {
        if(whichTimer == 'W')
        {
            y-=1;
            repaint();
        }
        if(whichTimer == 'A')
        {
            x-=1;
            repaint();
        }
        if(whichTimer == 'S')
        {
            y+=1;
            repaint();
        }
        if(whichTimer == 'D')
        {
            x+=1;
            repaint();
        }
    }

}
}
4

3 回答 3

5

确保组件是可聚焦的并且具有焦点。此外,最好使用键绑定,有关更多详细信息,请参阅如何使用键绑定

于 2012-08-04T03:01:44.060 回答
3

@Max 是正确的,KeyBindings是解决问题的更好方法。关键问题(对不起,没有双关语)是一旦焦点移动到任何其他组件,您将不再收到关键事件。现在,你可能在想,“但我没有改变焦点”——你只需要点击另一个可聚焦的组件来失去关键焦点,或者按 Tab,这KeyListener通常不会被通知。

通常,正如您所发现的那样,KeyListeners它们是不可靠的,它们不仅只会在相关组件具有焦点时收到通知,而且可以在它们到达您之前使用密钥

于 2012-08-04T04:22:31.013 回答
3

1.问题是你loosing focus在这里超过了你的组件。

2.检查您的组件是否focusable,尝试使用KeyBinding

3.此外,请记住这一点...在Swings焦点从左到右和从上到下移动,其中如AWT,它根据将组件添加到容器中的顺序。

于 2012-08-04T04:44:03.943 回答