Java 交换JPanel后未触发KeyListener

Java 交换JPanel后未触发KeyListener,java,swing,awt,keylistener,Java,Swing,Awt,Keylistener,我制作了一个游戏,我拥有它,这样当用户在游戏中按下“I”时,游戏面板被设置为不可见,同时它将目录面板添加到JFrame中。然后,当用户退出资源清册时,它将删除资源清册JPanel,然后将游戏JPanel设置为可见 现在这一切听起来都不错,但每当它删除清单JPanel并返回游戏JPanel时,KeyListener就会停止工作。在移除清单JPanel之后,我甚至在游戏JPanel上设置了setFocusable(true)属性,但它仍然不能使KeyListener工作 以下是我的Jpanel游戏代

我制作了一个游戏,我拥有它,这样当用户在游戏中按下“I”时,游戏面板被设置为不可见,同时它将目录面板添加到JFrame中。然后,当用户退出资源清册时,它将删除资源清册JPanel,然后将游戏JPanel设置为可见

现在这一切听起来都不错,但每当它删除清单JPanel并返回游戏JPanel时,KeyListener就会停止工作。在移除清单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时能够正常工作吗

在移除清单JPanel之后,我甚至在游戏JPanel上设置了setFocusable(true)属性

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

panel.requestFocusInWindow();
交换面板后,确保面板再次聚焦

然而,更好的方法是使用键盘侦听器的itead

在移除清单JPanel之后,我甚至在游戏JPanel上设置了setFocusable(true)属性

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

panel.requestFocusInWindow();
交换面板后,确保面板再次聚焦


但是,更好的方法是使用键盘监听器的itead。

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

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

感谢Sam的帮助:)可能需要进行一些测试才能找出确切的问题所在,但是有一篇文章详细介绍了focus在Java中的工作原理,可能值得一读。除此之外,你可以注册一个FocusListener并验证你的游戏屏幕是否失去焦点而无法恢复。是的,我只是在游戏面板上放置了一个FocusListener,它失去了焦点而无法恢复。我能做些什么让它恢复焦点吗?它又出现了吗?可能是contentpane.add方法实际上正在删除您的游戏面板,因此您必须再次添加它。此外,我认为,比交换窗格更好的方法是使用JDialog与资源清册。感谢Sam的帮助:)可能需要一些测试来找出确切的问题,但是有一篇文章详细介绍了focus在Java中的工作原理,可能值得一读。除此之外,你可以注册一个FocusListener并验证你的游戏屏幕是否失去焦点而无法恢复。是的,我只是在游戏面板上放置了一个FocusListener,它失去了焦点而无法恢复。我能做些什么让它恢复焦点吗?它又出现了吗?可能是contentpane.add方法实际上正在删除您的游戏面板,因此您必须再次添加它。此外,我认为,比交换窗格更好的方法是使用JDialog和资源清册。