【问题标题】:Why won't the keyPressed method be called?为什么不调用 keyPressed 方法?
【发布时间】:2011-07-19 17:21:09
【问题描述】:

我正在为一个项目使用 Java 制作格斗游戏,并试图让图片在面板上移动并重新绘制,以响应键盘 (keyEvents)。我试图通过在 keyPressed 方法中进行开关来实现这一点,同时将 keyListener 添加到面板中。我一直在遵循我的 Java 书中的一个示例,我编写的代码几乎相同,但它不起作用。

我真正想知道的是为什么它似乎根本没有对 keyEvents 做出反应。该程序编译良好,但没有任何反应。我不知道出了什么问题。如果我做一个,它不会到达keyPressed() 方法中的断点,如果我把它放在那里它也不会做一个println()。所以keyPressed() 方法根本没有反应。我还测试并确保面板是可聚焦的,因此我确定它具有键盘焦点。

public class MovePanel extends JPanel implements KeyListener {
    private ImageIcon currentImage, facingLeft, facingRight;
    private int position;
    private final int MOVEMENT;
    private GameFrame gameFrame;
    private URL lefturl, righturl;

    public MovePanel(GameFrame gameFrame) {
        // Taking in a gameFrame to be able to swap the active panel 
        // (not really relevant).
        this.gameFrame = gameFrame;

        // Adding the key listener here.
        addKeyListener(this);

        // These are just the Images I'm using to test. 
        // Trying to get it to swap from one to the other.
    lefturl = getClass().getResource("/Images/facingLeft.jpg");
    righturl = getClass().getResource("/Images/facingRight.jpg");

    facingLeft = new ImageIcon(lefturl);
    facingRight = new ImageIcon(righturl);

    currentImage = facingLeft;
    position = 50;
    MOVEMENT = 30;

    setBackground(Color.red);
    setPreferredSize(new Dimension(600,300));

        // Calling this method so that the panel will react 
        // to the keyboard without having to be clicked.
    setFocusable(true);
    }

    // This is just the paintComponent method which works fine to paint the image
    // when starting the game.
    public void paintComponent(Graphics page) {
    super.paintComponent(page);
    currentImage.paintIcon(this, page, position, 170);
    }

    // No matter what I try to do inside the keyPressed method
    // it doesnt seem to react at all.
    public void keyPressed(KeyEvent e) {

        // This switch is to make the method react accordingly to the keys pressed.
        switch (e.getKeyCode()) {
        case KeyEvent.VK_LEFT: 

            // Here I'm changing the "active" image and the position 
            // by changing the position variable which is used 
            // to determine the x placement of the image.
            // This case is suppused to react if the left arrow key is pressed.
            currentImage = facingRight;
            position -= MOVEMENT;
            break; 
        case KeyEvent.VK_RIGHT: 
            currentImage = facingRight;
            position += MOVEMENT;
            break; 

        // This case is to exit to the menu when escape is pressed.
        case KeyEvent.VK_ESCAPE: 
            gameFrame.setMenuPanelActive();
            break; 
        }
        // After reacting to any of the proper keys pressed 
        // I'm trying to repaint which will use the
        // paintComponent method to paint the new image in its new position.
        repaint();
    }
    // I have empty definitions for the other 
    // implemented methods but won't be posting them.
}

有人知道为什么这不起作用吗?为什么keyPressed() 方法没有反应?

【问题讨论】:

  • 可能框架正在捕捉事件...您确定面板处于焦点上吗?把这样的监听器也放在框架上,看看有没有被调用:)
  • 您的代码对我来说似乎工作正常。您确定没有其他组件具有焦点吗?
  • 我将如何检查是否是这种情况?当我将侦听器添加到面板时,框架如何做到这一点?真的很茫然,连我的教授都没明白为什么这行不通:(
  • 我用过 if (this.isFocusable() == true) setBackground(Color.black);看看它是否可聚焦,我也使用了 this.requestFocus();在构造函数中查看是否是问题所在,尽管我不能确定。真的不习惯这里的评论系统,我在尝试换行时一直在评论:P 我会尝试在框架中添加一个监听器。
  • 我尝试使用 if (gameFrame.isFocusOwner() == true) { System.out.println("ppifjlos"); } 因为 Eclipse 说 hasFocus() 已经过时了。试图测试框架是否有焦点,但似乎没有。还尝试在面板上执行此操作,但它也没有执行任何操作,因此似乎没有焦点。

标签: java user-interface keylistener keyevent


【解决方案1】:

我没有看到下面的代码

你应该调用下面的行来创建 MovePanel 的实例

 MovePanel.requestFocus();      // Give the panel focus.



public class demo extends JFrame 
{
    MovePanel  panel;

    public demo () 
    {
        panel= new MovingTextPanel();
        this.getContentPane().setLayout(new BorderLayout())
        this.setTitle("Demo");
        this.pack();
        panel.requestFocus();      // Give the panel focus.
    }
}

在你的 MovePanel 中添加 setFocusable 为 true

 public MovePanel(GameFrame gameFrame) {

        this.setFocusable(true);   // Allow this panel to get focus.
        // Adding the key listener here.
        addKeyListener(this);

更多痕迹

- Characters (a, A, #, ...) - handled in the keyTyped() listener.
- Virtual keys (arrow keys, function keys, etc) - handled with keyPressed() listener.
- Modifier keys (shift, alt, control, ...) - Usually their status (up/down) is tested by calls in one of the other listeners, rather than in keyPressed().

  public void keyTyped(KeyEvent e) {
    System.out.println(e.toString());
  }
  public void keyPressed(KeyEvent e) {
   System.out.println(e.toString());
  }
  public void keyReleased(KeyEvent e) {
    System.out.println(e.toString());
  }

【讨论】:

  • requestFocusInWindow() 比 requestFocus() 更推荐 :)
  • 我尝试添加 movePanel.requestFocus();我创建了 MovePanel 但它没有做任何事情,它仍然不会通过我在 MovePanel 的构造函数中使用 this.isFocusOwner() 所做的检查。我不知道为什么它不会聚焦,因为 isFocusable() 方法产生 true :(
  • @Suresh S 我将跟踪添加到侦听器,没有任何反应。像我这样的磨砂程序员怎么能把事情搞得一团糟:P
  • @Suresh-S 我将侦听器添加到框架中,它似乎确实是以某种方式窃取焦点的那个,因为痕迹在那里做出反应。这有什么帮助吗?
  • @Clearout: 如果有 frame 的监听器,注释掉试试。
猜你喜欢
  • 1970-01-01
  • 2015-01-26
  • 2012-11-15
  • 2016-04-15
  • 1970-01-01
  • 2015-07-01
  • 2018-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多