我的键绑定没有在 JPanel 中执行它的 actionPerformed

My keybinding didn't do its actionPerformed in JPanel

我在我的一个 JPanel 上添加了键绑定。问题是这个键绑定没有执行它的“actionPerformed”。即使我在 actionPerformed 中放置了一个系统输出,控制台上也没有任何输出。有人可以帮我解决这个问题吗?我已经尝试禁用我的按钮,但我的键绑定仍然不起作用。

package project.fin;

import java.awt.*;
import java.io.*;
import java.util.List;
import java.awt.event.*;
import javax.swing.*;

//Panel for my game
public class GamePlayPanel extends JPanel{
    private Image current;
    private Baby bayi;
    public GamePlayPanel(String img) {
        Dimension size = new Dimension(1200, 500);
        this.setPreferredSize(size);
        this.setMaximumSize(size);
        this.setMinimumSize(size);
        this.setSize(size);
        this.setLayout(null);
        
        //An baby object
        bayi = new Baby(100, 410, 5);
        
        //this is where my keyBinding initialized
        bayi.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0), "moveRight");
        bayi.getActionMap().put("moveRight", new Move_it(1));
        
    }
    
    //this is the action class that i want to put in my keybinding
    private class Move_it extends AbstractAction{
        int code;
        public Move_it(int code) {
            this.code=code;
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            System.out.println("test\n");
            if (this.code==1) {
                bayi.MoveRight();
            }
            repaint();
        }
    }
    
    //To draw my baby
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        bayi.draw(g);
    }

}

这是我的宝贝class:

package project.fin;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

import java.awt.event.*;
public class Baby extends JComponent{
    float x, y;
    float speed;
    Image current;
    private List <Image> ImgPool;
    private int Current;
    public Baby(float x, float y, float speed) {
        // TODO Auto-generated constructor stub
        this.x = x;
        this.y = y;
        this.speed = speed;
        ImgPool = new ArrayList<Image>();
        
        //These are just some images that i use to build my moving baby
        ImgPool.add(new ImageIcon("baby1_50.png").getImage());
        ImgPool.add(new ImageIcon("baby2_50.png").getImage());
        ImgPool.add(new ImageIcon("baby1_50.png").getImage());
        ImgPool.add(new ImageIcon("baby3_50.png").getImage());
        this.current = ImgPool.get(0);
        this.Current = 0;
    }
    
    //The action that i want my baby to do when a key is pressed
    public void MoveRight() {
            if (x>600) return;
            this.x+=speed;
            if (this.Current==3)this.Current=0;
            else
            this.Current++;
            this.current = this.ImgPool.get(Current);
    }
    

    public void draw(Graphics g) {
        g.drawImage(this.current, (int)this.x, (int)this.y, null);
    }
    
}

Baby 未附加到组件层次结构,因此不会收到任何按键事件。其实这样设计是没有意义的。 Bady 根本不需要从 JPanel 扩展。

相反,直接使用 GamePlayPanel

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.*;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new GamePlayPanel());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class GamePlayPanel extends JPanel {

        private Baby bayi;

        public GamePlayPanel() {
            //An baby object
            bayi = new Baby(100, 410, 5);

            //this is where my keyBinding initialized
            getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "moveRight");
            getActionMap().put("moveRight", new Move_it(1));

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(1200, 500);
        }

        //this is the action class that i want to put in my keybinding
        private class Move_it extends AbstractAction {

            int code;

            public Move_it(int code) {
                this.code = code;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System.out.println("test\n");
                if (this.code == 1) {
                    bayi.moveRight();
                }
                repaint();
            }
        }

        //To draw my baby
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            bayi.draw(g);
        }

    }

    public class Baby {

        float x, y;
        float speed;
        Image current;
        private List<Image> ImgPool;
        private int Current;

        public Baby(float x, float y, float speed) {
            // TODO Auto-generated constructor stub
            this.x = x;
            this.y = y;
            this.speed = speed;
            ImgPool = new ArrayList<Image>();

            //These are just some images that i use to build my moving baby
            ImgPool.add(new ImageIcon("baby1_50.png").getImage());
            ImgPool.add(new ImageIcon("baby2_50.png").getImage());
            ImgPool.add(new ImageIcon("baby1_50.png").getImage());
            ImgPool.add(new ImageIcon("baby3_50.png").getImage());
            this.current = ImgPool.get(0);
            this.Current = 0;
        }

        //The action that i want my baby to do when a key is pressed
        public void moveRight() {
            if (x > 600) {
                return;
            }
            this.x += speed;
            if (this.Current == 3) {
                this.Current = 0;
            } else {
                this.Current++;
            }
            this.current = this.ImgPool.get(Current);
        }

        public void draw(Graphics g) {
            g.drawImage(this.current, (int) this.x, (int) this.y, null);
        }

    }
}