Java 使用KeyListener时,自定义JComponent将消失

Java 使用KeyListener时,自定义JComponent将消失,java,swing,jpanel,keylistener,jlayeredpane,Java,Swing,Jpanel,Keylistener,Jlayeredpane,一段时间以来,我一直在努力移动面板上的自定义精灵组件。下面是该类的代码: public class SpriteComponent extends JComponent { private int x = 0; private BufferedImage sprite; private int y = 0;//declare instance fields public SpriteComponent(){ try{

一段时间以来,我一直在努力移动面板上的自定义精灵组件。下面是该类的代码:

    public class SpriteComponent extends JComponent
{
    private int x = 0;
    private BufferedImage sprite;
    private int y = 0;//declare instance fields
    public SpriteComponent(){
        try{
            sprite = ImageIO.read(new File("Images/Sprite.png"));
        }catch(IOException e){}
    }
    public void moveR()
    {
        x += 64;
        repaint();
    }

    public void moveL()
    {
        x -= 64;
        repaint();
    }

    public void moveU()
    {
        y += 64;
        repaint();
    }

    public void moveD()
    {
        y -= 64;
        repaint();
    }

    public void actionPerformed(ActionEvent e)
    {
        repaint();
    }

    public void paintComponent(Graphics g)//overload paintComponent method
    {
        super.paintComponent(g);
        g.drawImage(sprite,x,y,null);
    }

    public Dimension getPreferredSize() {
        if(sprite==null) return new Dimension(64,64);
        else return new Dimension(sprite.getWidth(null),sprite.getHeight(null));
    }
}
我希望它在面板上移动,后面有一个图像。我尝试使用JLayeredPane,甚至创建自己的自定义面板,但当我将精灵添加到面板时,当我按箭头键时,精灵消失了。但它在常规面板中工作

以下是侦听器和UI的代码:

public class Engine
{
    public static void main(String[] args){
        JFrame frame = new JFrame();
        JLayeredPane lpane = new JLayeredPane();
        JPanel mappanel = new JPanel();
        JPanel invisible = new JPanel();
        frame.setPreferredSize(new Dimension(1200, 750));
        frame.setLayout(new BorderLayout());
        frame.add(lpane, BorderLayout.CENTER);
        lpane.setBounds(0, 0, 1110, 550);
        mappanel.add(new JLabel(new ImageIcon("Images/map.png")));
        mappanel.setBounds(0, 0, 1110, 550);
        mappanel.setOpaque(true);
        invisible.setBounds(0, 0, 1110, 550);
        invisible.setOpaque(false);
        final SpriteComponent s = new SpriteComponent();
        invisible.add(s);
        lpane.add(mappanel, new Integer(0), 0);
        lpane.add(invisible, new Integer(1), 0);
        frame.pack();
        frame.setVisible(true);
        frame.setTitle("Pokemon");

    JPanel pokemonlist = new JPanel();
    pokemonlist.setLayout(new GridLayout(1,6));
    frame.add(pokemonlist, BorderLayout.SOUTH);
    Font g = new Font(Font.SANS_SERIF, Font.BOLD, 15);
    mappanel.setBorder(new TitledBorder(new MatteBorder(15,15,15,15,new ImageIcon(new ImgUtils().scaleImage(15,15,"Images/Pokeball.png"))), "Map",0,0,g,Color.BLUE));
    pokemonlist.setBorder(new TitledBorder(new MatteBorder(15,15,15,15,new ImageIcon(new ImgUtils().scaleImage(15,15,"Images/Pokeball.png"))), "Pokemon List",0,0,g,Color.BLUE));

    class KeyPressListener implements KeyListener//inner class KeyPressListener implements interface KeyListener
    {
        public void keyPressed(KeyEvent e)
        {
            int x = e.getKeyCode();
            if (x==KeyEvent.VK_UP) s.moveU();
            if (x==KeyEvent.VK_RIGHT) s.moveR();
            if (x==KeyEvent.VK_LEFT) s.moveL();
            if (x==KeyEvent.VK_DOWN) s.moveD();
        }

        public void keyReleased(KeyEvent e)
        {}

        public void keyTyped(KeyEvent e)
        {}
    }
    KeyPressListener kpl = new KeyPressListener();
    frame.addKeyListener(kpl);
}
}

感谢您的帮助。

1)不要使用KeyListener,而是使用键绑定(谷歌教程)。2) 只需在[0,0]处的SpriteComponent的
paintComponent
方法中绘制背景缓冲区图像,就可以避免使用JLayeredPane,只要在绘制sprite之前这样做即可。非常感谢!我按照你的建议用SpriteComponent绘制了地图,它终于成功了!