2
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 个类 atm 的游戏,但我不会对此进行详细介绍 - 我的游戏涉及玩家通过按键侦听器使用箭头键的移动。这是我的主要课程- 现在发生的事情是这样的。我正在努力做到这一点,以便人们可以选择他们想要在 A 级或 B 级上玩的关卡。然后我添加一个包含该游戏关卡供用户玩的 JPanel——如果我在主要方法,一切正常!

但是,当我单击按钮然后添加 JPanel 时,玩家无法移动,仅此而已 - 但是,关卡中的所有怪物都可以正常工作。

有什么想法吗?ButtonListener 是否覆盖 KeyListener 之类的?顺便说一句,setFocusable 在游戏级别面板类中已经设置为 true,所以我怀疑这是一个问题

4

1 回答 1

0

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

你有两个选择。更改您的代码以使用键绑定(首选)或调用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);
        }

    }

}
于 2012-11-21T04:33:30.907 回答