交换JPanels后没有触发KeyListener

时间:2011-02-21 15:38:56

标签: java swing awt keylistener

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

现在这一切听起来不错,但每当它删除Inventory JPanel并返回游戏JPanel时,KeyListener就会停止工作。我删除了Inventory JPanel后,甚至在游戏JPanel上重新设置了setFocusable(true)属性,但它仍然没有使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就会正常工作吗?

2 个答案:

答案 0 :(得分:5)

  

我删除了Inventory JPanel后,甚至在游戏JPanel上重新设置了setFocusable(true)属性

关键事件只会转到具有焦点的组件。你需要调用:

panel.requestFocusInWindow();

交换面板后确保面板再次聚焦。

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

答案 1 :(得分:0)

您可以跳过在内容窗格中添加和删除面板的工作,只需设置可见性即可。然后你也应该跳过设置focusable属性(KeyEvents不会传递给一个不可见的组件),你的关键监听器应该保留下来,并在组件可见时再次生效。