java - 游戏重置后 KeyListener 类变得无响应

标签 java swing user-interface keylistener

我正在用java编写一个简单的蛇应用程序,我有一个gamePanel,其中包含游戏并将其添加到JFrame Window类中,当我第一次启动游戏时,按键监听器工作正常,但是当游戏丢失时(按下按钮时) ,游戏会自行重置,但按键监听器变得无响应),我看不出有任何原因它会变得无响应,我没有对其执行任何操作

class Window extends JFrame {

    private static final long serialVersionUID = -2542001418764869760L;
    private final ButtonPanel buttonPanel;
    private GamePanel gamePanel;
    private ThreadsController c;

    // now size of the game can change only by modifiying this width and height

    public JFrame getFrame() {
        return this;
    }

    public JPanel getGamePanel() {
        return gamePanel;
    }

    public JPanel getButtonPanel() {
        return buttonPanel;
    }

    public Window() throws FileNotFoundException {

        this.setTitle("Snake");
        this.setSize(300, 300);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);

        gamePanel = new GamePanel();
        this.buttonPanel = new ButtonPanel(this, c);

        this.add(new TopPanel(), BorderLayout.NORTH);

        this.add(gamePanel, BorderLayout.CENTER);
        this.add(buttonPanel, BorderLayout.SOUTH);
        this.setVisible(true);
        c = new ThreadsController(gamePanel.getSnakeDepartPosition());
        this.buttonPanel.getExit().addActionListener(
                new ButtonActionListener(this, c));
        this.buttonPanel.getNewGame().addActionListener(
                new ButtonActionListener(this, c));

        c.start();
        this.addKeyListener(new KeyboardListener());
        this.setFocusable(true);
    }

    private class KeyboardListener extends KeyAdapter {

        public void keyPressed(KeyEvent e) {
            switch (e.getKeyCode()) {
            case KeyEvent.VK_RIGHT:
                // if it's not the opposite direction
                if (ThreadsController.directionSnake != Directions.LEFT)
                    ThreadsController.directionSnake = Directions.RIGHT;
                break;
            case KeyEvent.VK_UP:
                if (ThreadsController.directionSnake != Directions.BOTTOM)
                    ThreadsController.directionSnake = Directions.TOP;
                break;

            case KeyEvent.VK_LEFT:
                if (ThreadsController.directionSnake != Directions.RIGHT)
                    ThreadsController.directionSnake = Directions.LEFT;
                break;

            case KeyEvent.VK_DOWN:
                if (ThreadsController.directionSnake != Directions.TOP)
                    ThreadsController.directionSnake = Directions.BOTTOM;
                break;

            default:
                break;
            }
        }    
    }

}


here is the action listener

    public class ButtonActionListener implements ActionListener {

    private Window frame;
    private ThreadsController t;

    public ButtonActionListener(Window frame, ThreadsController t) {
        this.frame = frame;
        this.t = t;
    }

    @Override
    public void actionPerformed(ActionEvent clickedButton) {
        // TODO Auto-generated method stub
        /*
         * t.setAlive(false);
         * 
         * frame.getContentPane().remove(frame.getGamePanel());
         * 
         * 
         * 
         * frame.add(gamePanel, BorderLayout.CENTER); frame.setVisible(true);
         */GamePanel gamePanel = new GamePanel();
        gamePanel.addKeyListener(new KeyboardListenner());
        frame.add(gamePanel, BorderLayout.CENTER);
        frame.setVisible(true);
        t = new ThreadsController(new Tuple(10, 10));
        t.start();    
    }    
}

最佳答案

仅为具有焦点的组件生成 KeyEvent。

当您单击按钮时,该按钮现在具有焦点,而不是您的“GamePanel”。您需要使用:

gamePanel.requestFocusInWindow();

在框架可见之后。

但是,这并不能解决问题,因为您不能只向框架添加一个新的“GamePanel”,因为您的内容 Pane 现在将包含两个 GamePanel。如果组件添加到框架的顺序相反,Swing 将绘制组件。所以你的新 GamePanel 将首先被绘制,然后旧的 GamePanel 将被绘制在上面。因此,您需要在添加新 GamePanel 之前删除旧 GamePanel。

或者,如果您想重置游戏,更好的方法是在 GamePanel 中使用“重置”方法来重置游戏。别这样

关于java - 游戏重置后 KeyListener 类变得无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23748821/

相关文章:

java - MarqueePanel 中的 JEditorPane/JTextPane

java - 如何在java的Swing GUI中将图像设置为Frame的背景?

user-interface - 图结构(在 CS 意义上的图、节点、边)的(Web)用户界面的一个很好的例子是什么?

java - 跳转笔记 : main type is not specified

java - 如果收件箱中的邮件数量超过 int 范围会怎样?

java - Integer.parseInt() 和 Integer.toString() 运行时

html - 永久应用 bootstrap 主题

java - 在一个事务中组合 JPA 和 JDBC 操作

java - 将自定义文本从一个 JTextpane 发送到另一个 JTexpane

c - 如何在 GTK 中使用图像作为按钮?