【问题标题】:KeyListener not being triggered after I swap JPanels交换 JPanel 后未触发 KeyListener
【发布时间】:2011-07-01 08:58:48
【问题描述】:

我正在制作一个游戏并且我拥有它,因此当用户在游戏中按下“I”时,游戏面板设置为不可见,同时它将库存面板添加到 JFrame。然后,当用户退出 Inventory 时,它将删除 Inventory JPanel,然后将游戏 JPanel 设置为可见。

现在这一切听起来不错,但是每当它删除 Inventory JPanel 并返回到游戏 JPanel 时,KeyListener 就会停止工作。我什至在删除 Inventory JPanel 后将 setFocusable(true) 属性设置回游戏 JPanel 上,但它仍然无法使 KeyListener 工作。

这是我的游戏 Jpanel 的代码:

package javavideogame;

public class Game extends JPanel implements ActionListener, Runnable
{

    public Game(MainCharacter character)
    {
        TAdapter a = new TAdapter();
        addKeyListener(a);
        setFocusable(true);
        setDoubleBuffered(true);
        setFocusTraversalKeysEnabled(false);
    }

    public void getInventoryScreen()
    {
        Main.inv = new Inventory();
        Main.inv.sayHello();
        Main.mainGame.getContentPane().add(Main.inv);
        Main.game.setVisible(false);
        Main.mainGame.validate();
    }

    public void closeInventory()
    {
        Main.inv.setFocusable(false);
        Main.mainGame.remove(Main.inv);
        Main.game.setVisible(true);
        Main.game.setFocusable(true);
    }

    public class TAdapter extends KeyAdapter
    {
        public void keyPressed(KeyEvent e)
        {
            character.keyPressed(e);
        }

        public void keyReleased(KeyEvent e)
        {
            character.keyReleased(e);
        }
    }

}

这是库存代码:

package javavideogame;

public class Inventory extends JPanel implements KeyListener
{
    public Inventory()
    {
        setBackground(Color.RED);
        addKeyListener(this);
        setFocusable(true);
    }

    public void keyPressed(KeyEvent e)
    {
        int key = e.getKeyCode();
        if(key == KeyEvent.VK_I)
        {
            Main.game.closeInventory();
        }
    }

    public void keyReleased(KeyEvent e)
    {

    }

    public void keyTyped(KeyEvent e)
    {

    }
}

是的,我很难让代码在这里正常工作:)

但是有没有什么我可以很容易地放入代码中,以便 KeyListener 在返回到游戏 JPanel 后实际上可以正常工作?

【问题讨论】:

  • 感谢山姆的帮助 :)
  • 可能需要进行一些测试才能找出确切的问题,但download.oracle.com/javase/6/docs/api/java/awt/doc-files/… 上有一篇文章详细介绍了 Java 中的焦点如何工作 - 可能值得一读。除此之外,您可以注册一个 FocusListener 并验证您的游戏屏幕正在失去焦点并且没有恢复。
  • 是的,我只是在游戏面板上放了一个焦点监听器,它失去了焦点,没有恢复。我能做些什么让它重新获得焦点?
  • 又出现了吗?可能是 contentpane.add 方法实际上正在删除您的游戏面板,因此您必须再次添加它。
  • 另外,我认为,一个比交换面板更好的主意是带有库存的 JDialog。

标签: java swing awt keylistener


【解决方案1】:

我什至在删除 Inventory JPanel 后将 setFocusable(true) 属性设置回游戏 JPanel

关键事件只发生在有焦点的组件上。您需要调用:

panel.requestFocusInWindow();

在交换面板以确保面板再次获得焦点之后。

但是,更好的方法是使用 KeyListener 的 Key Bindingsitead。

【讨论】:

    【解决方案2】:

    您可以跳过在内容窗格中添加和删除面板的工作,而只需设置可见性。然后,您还应该跳过设置可聚焦属性(无论如何,KeyEvents 都不会传递给不可见的组件),并且您的键侦听器应该被保留并在组件变得可见时再次生效。

    【讨论】:

      猜你喜欢
      • 2012-01-01
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 2014-06-04
      • 2014-05-06
      • 2018-07-07
      相关资源
      最近更新 更多