游戏重置后,KeyListener类变得无法响应

时间:2014-05-19 23:37:14

标签: java swing user-interface keylistener

我在java中编写一个简单的蛇应用程序我有一个包含游戏的gamePanel并将其添加到JFrame Window类中,当我第一次启动游戏时,keylistener工作正常但游戏丢失时(按下按钮时) ,游戏重置自己,但keylistener变得反应迟钝),我没有看到任何理由为什么它应该变得反应迟钝,我没有做任何事情

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();    
    }    
}

1 个答案:

答案 0 :(得分:3)

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

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

gamePanel.requestFocusInWindow();

框架可见后。

然而,这不会解决问题,因为您无法添加新的" GamePanel"到框架,因为您的内容窗格现在将包含两个GamePanel。如果组件以相反的顺序添加到框架中,则Swing将绘制组件。因此,您将首先绘制新的GamePanel,然后将旧的GamePanel绘制在顶部。因此,在添加新的GamePanel之前,您需要删除旧的GamePanel。

或者,如果您想要重置游戏,更好的方法是重置"重置" GamePanel中重置游戏的方法。不要