Java 为什么我的KeyListener在向框架添加按钮后不工作?

Java 为什么我的KeyListener在向框架添加按钮后不工作?,java,swing,jbutton,keylistener,Java,Swing,Jbutton,Keylistener,当我删除setButton并按下键时,有正确的反应,但如果我添加setButton,只有按钮起作用,按下键时没有反应,这里发生了什么 public class Sokaban extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; JButton btnBack,btnFirst,btnNext,btnPrev,btnLast,btnSelect,bt

当我删除setButton并按下键时,有正确的反应,但如果我添加setButton,只有按钮起作用,按下键时没有反应,这里发生了什么

public class Sokaban extends JFrame implements ActionListener {

    private static final long serialVersionUID = 1L;
    JButton btnBack,btnFirst,btnNext,btnPrev,btnLast,btnSelect,btnMusic,btnReset;
    JComboBox<String> cbMusic;
    JMenuBar menuBar;
    JMenu mnuOption,mnuSet,mnuHelp;
    JMenuItem miReset,miPrev,miNext,miSelect,miExit,miBack;
    JMenuItem miMusic1,miMusic2,miMusic3,miMusic4,miMusic5;
    JMenuItem miHelp;
    //music file
    String sMusic[] = {
        "eyes on me.mid",
        "guang.mid",
        "nor.mid",
        "popo.mid",
        "qin.mid"
    };
    //game panel
    MyPanel mainPanel;
    public Sokaban(int[][] samplemap){
        super("Game 2017");

        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Image image = toolkit.getImage("pic/p0.jpg");
        //set icon
        this.setIconImage(image);
        Container c = this.getContentPane();
        c.setLayout(null);
        c.setBackground(Color.orange);

        JLabel lblTitle = new JLabel("SOKABAN GAME",JLabel.CENTER);
        lblTitle.setFont(new Font("",Font.BOLD,20));
        lblTitle.setBounds(100,40,500,30);
        c.add(lblTitle,BorderLayout.NORTH);
        //put buttons
        setButton(c);
        setMenus();

        mainPanel = new MyPanel(samplemap);
        mainPanel.setBounds(60,120,450,450);
        mainPanel.setFocusable(true);
        mainPanel.requestFocusInWindow();
        c.add(mainPanel);

        setSize(720,720);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

    }

    //set button
    public void setButton(Container c){
        btnReset = new JButton("Reset");
        btnBack = new JButton("Back");
        btnFirst = new JButton("First");
        btnNext = new JButton("Next");
        btnPrev = new JButton("Prev");
        btnLast = new JButton("Last");
        btnSelect = new JButton("Select");
        btnMusic = new JButton("Music");
        JLabel lblMusic = new JLabel("Select Music");
        c.add(lblMusic);

        btnReset.addActionListener(this);
        btnBack.addActionListener(this);
        btnFirst.addActionListener(this);
        btnNext.addActionListener(this);
        btnPrev.addActionListener(this);
        btnLast.addActionListener(this);
        btnSelect.addActionListener(this);
        btnMusic.addActionListener(this);
        //cbMusic.addActionListener(this);

        cbMusic = new JComboBox<String>();
        cbMusic.addItem("default");
        cbMusic.addItem("good");
        cbMusic.addItem("music");
        cbMusic.addItem("choose");
        cbMusic.addItem("column");

        btnReset.setBounds(600,100,80,30);
        btnBack.setBounds(600,150,80,30);
        btnFirst.setBounds(600,200,80,30);
        btnNext.setBounds(600,250,80,30);
        btnPrev.setBounds(600,300,80,30);
        btnLast.setBounds(600,350,80,30);
        btnSelect.setBounds(600,400,80,30);
        btnMusic.setBounds(600,450,80,30);
        lblMusic.setBounds(600, 500, 80, 30);
        cbMusic.setBounds(600, 530, 80, 30);
        c.add(btnReset);
        c.add(btnBack);
        c.add(btnFirst);
        c.add(btnNext);
        c.add(btnPrev);
        c.add(btnLast);
        c.add(btnSelect);
        c.add(btnMusic);
        c.add(cbMusic);

    }


    //set menu
    public void setMenus(){
        mnuOption = new JMenu("Option");
         miReset = new JMenuItem("Reset");
         miPrev = new JMenuItem("Previous");
         miNext = new JMenuItem("Next");
         miSelect = new JMenuItem("Select");
         miExit = new JMenuItem("Exit");
         miBack = new JMenuItem("Back");

         mnuOption.add(miBack);
         mnuOption.add(miReset);
         mnuOption.add(miPrev);
         mnuOption.add(miNext);
         mnuOption.add(miSelect);
         mnuOption.addSeparator();
         mnuOption.add(miExit);

         mnuSet = new JMenu("Setting");
         miMusic1 = new JMenuItem("default");
         miMusic2 = new JMenuItem("good");
         miMusic3 = new JMenuItem("music");
         miMusic4 = new JMenuItem("choose");
         miMusic5 = new JMenuItem("column");
         mnuSet.add(miMusic1);
         mnuSet.add(miMusic2);
         mnuSet.add(miMusic3);
         mnuSet.add(miMusic4);
         mnuSet.add(miMusic5);

         mnuHelp = new JMenu("Help");
         mnuHelp.setMnemonic('H');
         miHelp = new JMenuItem("About us...");
         mnuHelp.add(miHelp);

         miBack.addActionListener(this);
         miReset.addActionListener(this);
         miPrev.addActionListener(this);
         miNext.addActionListener(this);
         miSelect.addActionListener(this);
         miMusic1.addActionListener(this);
         miMusic2.addActionListener(this);
         miMusic3.addActionListener(this);
         miMusic4.addActionListener(this);
         miMusic5.addActionListener(this);
         miHelp.addActionListener(this);

         menuBar = new JMenuBar();
         menuBar.add(mnuOption);
         menuBar.add(mnuSet);
         menuBar.add(mnuHelp);
         this.setJMenuBar(menuBar);

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        if(e.getSource().equals(miHelp)){
            String str = "COMP2911\n";
            str +="Assignment3\n";
            JOptionPane.showMessageDialog(this, str, "Help", JOptionPane.INFORMATION_MESSAGE);
        } else if(e.getSource().equals(miExit)){
            System.exit(0);
        } else if(e.getSource().equals(btnReset)){
            System.out.println("reset the game");
        } else if(e.getSource().equals(btnBack)){
            System.out.println("get to the back stage");
        }
    }

    //game panel
    public class MyPanel extends JPanel implements KeyListener{
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private int[][] oriMap;
        private int[][] tempMap;

        Toolkit kit = Toolkit.getDefaultToolkit();
        Image mapimg[] = {
            kit.getImage("pic/0.png"),
            kit.getImage("pic/1.gif"),
            kit.getImage("pic/2.png"),
            kit.getImage("pic/3.png"),
            kit.getImage("pic/4.gif"),
            kit.getImage("pic/5.GIF"),
            kit.getImage("pic/6.GIF"),
            kit.getImage("pic/7.GIF"),
            kit.getImage("pic/8.GIF"),
            kit.getImage("pic/9.png")
        };
        public int[][] getOriMap() {
            return oriMap;
        }
        public void setOriMap(int[][] oriMap) {
            this.oriMap = oriMap;
        }
        public MyPanel(int[][] map){
            readMap(map);
            setSize(600,600);
            this.addKeyListener(this);
            //this.setFocusable(true);
        //  requestFocus();
        //  repaint();
        }
        public void readMap(int[][] map){
            this.oriMap = map;
            this.tempMap = map;
        }
        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub

            System.out.println("2222222");

        }
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            System.out.println("1111111");
        }
        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub
            System.out.println("2333333333333");
        }


        @Override
        public void paint(Graphics g){
            for(int i = 0; i < 15; i++){
                for(int j = 0; j< 15;j++){
                    g.drawImage(mapimg[this.tempMap[j][i]], i*30, j*30, 30,30,this);
                }
            }
        }

    }

}

由于您正在将JPanel和JButton添加到JFrame中,因此KeyListener仅在JPanel被聚焦时才处于活动状态。当你按下一个按钮时,JPanel会失去焦点,如果你从一开始就有多个组件,它不会自动聚焦。您应该将KeyListener添加到JFrame中。

1使用KeyListener的常见问题源于组件不可聚焦b组件没有聚焦。2对于Swing,我们通常使用而不是较低级别的KeyListener。3在获得250行代码之前,您应该真正测试这些东西!4为了更快地获得更好的帮助,请发布一个or。5请对代码和代码、结构化文档(如HTML/XML或输入/输出)使用代码格式。。。。要做到这一点,请选择文本并单击消息发布/编辑表单顶部的{}按钮。键绑定、键绑定、键绑定-任何不建议使用它们的答案都是错误的KeyListener只会在其注册的组件可聚焦且具有焦点时响应键事件,因此当您向UI添加按钮时,它抓住了键盘的焦点。如前所述,唯一正确的答案是使用键绑定。当按钮抓住键盘焦点时,如何将KeyListener添加到帧中以解决问题。您只是将问题从一个位置移动到另一个位置,而没有实际解决它,因为JFrame包含JButton,当JButton被聚焦时,JFrame被聚焦。只要JFrame的任何组件都被聚焦,它就会始终被聚焦。基本上,只要用户在该窗口中,JFrame就会始终处于焦点位置。如果你是那个否决我的人,你能不能不要否决你没有尝试过的事情@MadProgrammer但是按钮获得键盘焦点,而不是框架-这不是键盘侦听器的工作方式