通过Button Action Listener添加游戏的JPanel(使用KeyListener)会禁用keylistener

时间:2012-11-21 04:30:13

标签: java button actionlistener keylistener

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class Game extends JPanel{
private static JFrame primary= new JFrame("Game");
private JButton x1;

public Game(){
    x1= new JButton("YES");
    x1.addActionListener(new LevelChoice(1));
    add(x1);
}

public static void setScreen(JPanel jp){


    //primary.removeAll();
    //System.out.println("hi");
    //primary.revalidate();
    //primary.repaint();

}

public static void main(String[] args){

    primary.setPreferredSize(new Dimension(1000, 700));
    /*primary.add(new LevelHUD("xxxxxxxxxxxxxxxxxxxx" +
            "xoooooooooooooooooox" +
            "xoooooooooooooooooox" +
            "xooomoooooooooooooox" +
            "xoooooooooxoooooooox" +
            "xoooooooooxooooomoox" +
            "xoooommoooxxxxooooox" +
            "xoooomooooooooooooox" +
            "xoooomooomooooooooox" +
            "xooomooooolooomoooox" +
            "xoooomcoooooooooooox" +
            "xooomococoooooooooox" +
            "xooomocoooloooooooox" +
            "xgoomocoooooooooooox" +
            "xcooooogooooooooooox" +
            "xocooooocoooooooooox" +
            "xoococooolooogooooox" +
            "xoooooooooooooooooox" +
            "xxxxxxxxxxxxxxxxxxxx"));*/

    primary.add(new Game());



    primary.setResizable(false);
    primary.setVisible(true);
    primary.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    primary.pack();
}

private class LevelChoice implements ActionListener{

    private int level;

    public LevelChoice(int i){
        level=i;
    }

    public void actionPerformed(ActionEvent e) {
        //Game.setScreen(new LevelHUD(gamelevel1));
        primary.add(new LevelHUD("xxxxxxxxxxxxxxxxxxxx" +
                "xoooooooooooooooooox" +
                "xoooooooooooooooooox" +
                "xooomoooooooooooooox" +
                "xoooooooooxoooooooox" +
                "xoooooooooxooooomoox" +
                "xoooommoooxxxxooooox" +
                "xoooomooooooooooooox" +
                "xoooomooomooooooooox" +
                "xooomooooolooomoooox" +
                "xoooomcoooooooooooox" +
                "xooomococoooooooooox" +
                "xooomocoooloooooooox" +
                "xgoomocoooooooooooox" +
                "xcooooogooooooooooox" +
                "xocooooocoooooooooox" +
                "xoococooolooogooooox" +
                "xoooooooooooooooooox" +
                "xxxxxxxxxxxxxxxxxxxx"));
        revalidate();

    }

}


}

好的,所以我有一个大约有12个课程的游戏,但我不会详细介绍 - 我的游戏涉及玩家使用箭头键通过关键听众进行移动。这是我的主要课程 - 现在发生的是这个。我试图让它成为一个人可以选择他们想要玩的级别 - A级或B级。然后我添加一个包含该游戏级别的JPanel供用户玩 - 如果我添加游戏级别主要方法,一切正常!

当我点击按钮然后添加JPanel时,玩家无法移动而且就是这样 - 但是关卡中的所有怪物都能正常工作。

有什么想法? ButtonListener是否覆盖KeyListener或其他什么? BTW,setFocusable已经在游戏级别面板类中设置为true,所以我怀疑这是一个问题

1 个答案:

答案 0 :(得分:0)

KeyListeners要求他们正在收听的组件,要有焦点,当您点击按钮时,重点更改并且不再将密钥“发送”到您的组件。

你有两个选择。将代码更改为使用Key Bindings(首选)或在要接收关键事件的面板上调用requestFocusInWindow

更新了示例

演示核心问题的简单示例。焦点必须返回到KeyListener的组件,它不足以集中它的子组件或父组件。

你应该确保焦点请求是在EDT中进行的,否则它可能会被盗

public class TestKeyListener {

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

    public TestKeyListener() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                KeyPane keyPane = new KeyPane();
                frame.add(keyPane);
                frame.add(new ButtonPane(keyPane), BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class KeyPane extends JPanel {

        private JLabel keyed;
        public KeyPane() {

            setLayout(new GridBagLayout());
            keyed = new JLabel("...");
            add(keyed);
            setFocusable(true);
            requestFocusInWindow();

            addKeyListener(new KeyAdapter() {

                @Override
                public void keyPressed(KeyEvent e) {
                    keyed.setText(KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers()).toString());
                }

            });

            addFocusListener(new FocusListener() {

                @Override
                public void focusGained(FocusEvent e) {
                    keyed.setText("Focus gained");
                }

                @Override
                public void focusLost(FocusEvent e) {
                    keyed.setText("Focus lost");
                }

            });

        }

    }

    public class ButtonPane extends JPanel {

        public ButtonPane(final Component focus) {
            setLayout(new GridBagLayout());
            JButton bad = new JButton("Steal Focus");
            JButton good = new JButton("Return Focus");
            good.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    focus.requestFocusInWindow();
                }
            });

            add(good);
            add(bad);
        }

    }

}