KeyListener没有反应

时间:2017-06-04 14:42:12

标签: java animation graphics timer keylistener

我想让一架飞机全线移动。 这应该很简单,因为我以前做过 我有setFocusable(true),我已经添加了KeyListener,而且我还要requestFocusInWindow()

我不知道出了什么问题 按下某个键时,它甚至不会进入KeyPressed方法
我试图打印出“hi”进行测试。

    package game;

    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    import javax.swing.JFrame;

    public class GUI{

        /* Author: Carl Zhang
         * Date: 
         * 
         */

        //player's username
        public static String user;

        //classes
        public static GUI gui;
        public static LoginPanel lp;
        public static MenuPanel mp;
        public static GamePanel gp;
        public static HighscorePanel hp;

        public static InstructionPanel ip;

        //dimensions
        private static final int WIDTH = 500;
        private static final int HEIGHT = 500;

        public GUI() {


        JFrame frame = new JFrame("ZCraft");
            frame.setSize(WIDTH, HEIGHT);
            frame.setResizable(false);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);

        //adding JPanels
        lp = new LoginPanel();
        frame.add(lp);

        mp = new MenuPanel();
        frame.add(mp);  

        gp = new GamePanel();
        frame.add(gp);

        ip = new InstructionPanel();
        frame.add(ip);

        hp = new HighscorePanel();
        frame.add(hp);

        frame.setVisible(true);

    }//end constructor GUI() 

    public static int getWidth() {
        return WIDTH;

    }//end getWIDTH()

    public static int getHeight() {
        return HEIGHT;

    }//end getHEIGHT

    public static void main(String[] args) {
        gui = new GUI();

    }//end main

}//end class GUI

        package game;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GamePanel extends JPanel implements ActionListener, KeyListener {

    public static GamePanel gp;

    private boolean up = false;
    private boolean right = false;
    private boolean down = false;
    private boolean left = false;

    private ZCraft player;

    private JButton pause, back;

    public GamePanel(){
        //timer
        Timer timer = new Timer(5, this);

        setSize(GUI.getWidth(), GUI.getHeight());
        setBackground(Color.BLACK);
        setLayout(null);
        setVisible(false);

        /*

        pause = new JButton("Pause");
        pause.setHorizontalAlignment(SwingConstants.CENTER);
        pause.setBounds();
        pause.setBackground(Color.GREEN);
        pause.setForeground(Color.RED);
        pause.setOpaque(true);
        pause.setBorderPainted(false);
        pause.addActionListener(this);
        add(pause);

        back = new JButton("Back");
        back.setHorizontalAlignment(SwingConstants.CENTER);
        back.setBounds();
        back.setBackground(Color.GREEN);
        back.setForeground(Color.RED);
        back.setOpaque(true);
        back.setBorderPainted(false);
        back.addActionListener(this);
        add(back);

        */

        start();

        timer.start();

        setFocusable(true);
        addKeyListener(this);
        requestFocusInWindow();
        //setFocusTraversalKeysEnabled(false);
        //requestFocus();

    }//end constructor GamePanel()

    public void start() {
        player = new ZCraft(GUI.user);

    }//end start()

    public void update() {
        if(up) {
            player.moveYAxis(true);

        }else {
            player.moveYAxis(false);

        }

        if(right) {
            player.moveXAxis(true);

        }else {
            player.moveXAxis(false);

        }

    }//end update()

    public void render(Graphics g) {
        player.render(g);

    }//end render(Graphics g)

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        render(g);

    }//end paintComponent(Graphics g)

    @Override
    public void actionPerformed(ActionEvent e) {    
        update();
        repaint();

    }//end actionPerformed(ActionEvent e)

    @Override
    public void keyTyped(KeyEvent e) {}//end keyTyped(KeyEvent e)

    @Override
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();

        if(code == KeyEvent.VK_UP) {
            up = true;

        }

        if(code == KeyEvent.VK_RIGHT) {
            right = true;

        }

        if(code == KeyEvent.VK_DOWN) {
            down = true;

        }

        if(code == KeyEvent.VK_LEFT) {
            left = true;

        }

        if(code == KeyEvent.VK_SPACE) {
            //player.shoot();

        }

        if(code == KeyEvent.VK_1) {

        }

    }//end keyPressed(KeyEvent e)

    @Override
    public void keyReleased(KeyEvent e) {
        int code = e.getKeyCode();

        if(code == KeyEvent.VK_UP) {
            up = false;

        }

        if(code == KeyEvent.VK_RIGHT) {
            right = false;

        }

        if(code == KeyEvent.VK_DOWN) {
            down = false;

        }

        if(code == KeyEvent.VK_LEFT) {
            left = false;

        }

        if(code == KeyEvent.VK_SPACE) {
            //player.shoot();

        }

    }//end keyReleased(KeyEvent e)

}//end class GamePanel

我只想输入方法,我稍后会改变运动的东西

1 个答案:

答案 0 :(得分:1)

您似乎忽略了JFrame使用的布局管理器。 JFrame的contentPane使用BorderLayout,当向其添加多个组件时,您将覆盖以前添加的组件,因此您的GamePanel甚至不会显示更少的焦点。

最佳解决方案:

  • 好好学习和使用布局管理器
  • 使用Key Bindings,而不是KeyListeners。
  • 在提问时,请在问题上发布有效的MCVE,这是一个小而完整的程序,只有必要的代码来证明您的问题,我们可以复制,粘贴,编译和运行而无需修改,因为这会帮助我们完全理解你可能做错了什么。

我的MCVE测试您的代码:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GUI {
    public static String user;

    public static GUI gui;
    public static LoginPanel lp;
    public static MenuPanel mp;
    public static GamePanel gp;
    public static HighscorePanel hp;

    public static InstructionPanel ip;
    private static final int WIDTH = 500;
    private static final int HEIGHT = 500;

    public GUI() {

        JFrame frame = new JFrame("ZCraft");
        frame.setSize(WIDTH, HEIGHT);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        lp = new LoginPanel();
        frame.add(lp);

        mp = new MenuPanel();
        frame.add(mp);

        gp = new GamePanel();
        frame.add(gp);

        ip = new InstructionPanel();
        frame.add(ip);

        hp = new HighscorePanel();
        frame.add(hp);

        frame.setVisible(true);

    }

    public static int getWidth() {
        return WIDTH;

    }

    public static int getHeight() {
        return HEIGHT;

    }

    public static void main(String[] args) {
        gui = new GUI();

    }

}

class GamePanel extends JPanel implements ActionListener, KeyListener {

    public static GamePanel gp;

    private boolean up = false;
    private boolean right = false;
    private boolean down = false;
    private boolean left = false;

    private ZCraft player;

    private JButton pause, back;

    public GamePanel() {
        setBorder(BorderFactory.createTitledBorder("GamePanel")); // !!
        Timer timer = new Timer(5, this);

        setSize(GUI.getWidth(), GUI.getHeight());
        setBackground(Color.BLACK);
        setLayout(null);
        setVisible(false);

        start();

        timer.start();

        setFocusable(true);
        addKeyListener(this);
        requestFocusInWindow();

    }

    public void start() {
        player = new ZCraft(GUI.user);

    }

    public void update() {
        if (up) {
            player.moveYAxis(true);

        } else {
            player.moveYAxis(false);

        }

        if (right) {
            player.moveXAxis(true);

        } else {
            player.moveXAxis(false);

        }

    }

    public void render(Graphics g) {
        player.render(g);

    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        render(g);

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        update();
        repaint();

    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("keypressed: " + e);
        int code = e.getKeyCode();

        if (code == KeyEvent.VK_UP) {
            up = true;

        }

        if (code == KeyEvent.VK_RIGHT) {
            right = true;

        }

        if (code == KeyEvent.VK_DOWN) {
            down = true;

        }

        if (code == KeyEvent.VK_LEFT) {
            left = true;

        }

        if (code == KeyEvent.VK_SPACE) {

        }

        if (code == KeyEvent.VK_1) {

        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
        int code = e.getKeyCode();

        if (code == KeyEvent.VK_UP) {
            up = false;

        }

        if (code == KeyEvent.VK_RIGHT) {
            right = false;

        }

        if (code == KeyEvent.VK_DOWN) {
            down = false;

        }

        if (code == KeyEvent.VK_LEFT) {
            left = false;

        }

        if (code == KeyEvent.VK_SPACE) {

        }

    }

}

class LoginPanel extends MyJPanel {

}

class MenuPanel extends MyJPanel {

}

class HighscorePanel extends MyJPanel {

}

class InstructionPanel extends MyJPanel {

}

class MyJPanel extends JPanel {
    public MyJPanel() {
        setBorder(BorderFactory.createTitledBorder(getClass().getSimpleName()));
    }
}

class ZCraft {

    public ZCraft(String user) {
    }

    public void render(Graphics g) {

    }

    public void moveXAxis(boolean b) {

    }

    public void moveYAxis(boolean b) {

    }

}

请注意,只有HighScore JPanel会显示。

其他无关的问题:

  • 你严重过度使用静态修饰符,这使得测试代码和增强代码变得更加困难。
  • 您正在使用null布局,这是一件非常危险的事情,因此很难升级/更新您的计划。

例如:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class GUI2 extends JPanel {
    private static final int PREF_W = 500;
    private static final int PREF_H = PREF_W;    
    private LoginPanel lp = new LoginPanel();
    private MenuPanel mp = new MenuPanel();
    private MyGamePanel gp = new MyGamePanel();
    private HighscorePanel hp= new HighscorePanel();
    private InstructionPanel ip = new InstructionPanel();
    private JPanel[] panels = {lp, mp, gp, hp, ip};
    private DefaultComboBoxModel<String> comboModel = new DefaultComboBoxModel<>();
    private JComboBox<String> panelsCombo = new JComboBox<>(comboModel);
    private CardLayout cardLayout = new CardLayout();
    private JPanel cardHolderPanel = new JPanel(cardLayout);

    public GUI2() {
        for (JPanel panel : panels) {
            String key = panel.getClass().getSimpleName();
            cardHolderPanel.add(panel, key);
            comboModel.addElement(key);
        }

        JPanel bottomPanel = new JPanel();
        bottomPanel.add(panelsCombo);        

        panelsCombo.setFocusable(false);
        panelsCombo.addActionListener(e -> {
            String selection = (String) panelsCombo.getSelectedItem();
            cardLayout.show(cardHolderPanel, selection);
        });

        setLayout(new BorderLayout());
        add(cardHolderPanel, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.PAGE_END);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }


    private static void createAndShowGui() {
        GUI2 mainPanel = new GUI2();

        JFrame frame = new JFrame("GUI2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

@SuppressWarnings("serial")
class MyGamePanel extends MyJPanel {
    public MyGamePanel() {
        setKeyBindings();
    }

    private void setKeyBindings() {
        int condition = WHEN_IN_FOCUSED_WINDOW;
        InputMap inputMap = getInputMap(condition);
        ActionMap actionMap = getActionMap();

        KeyStroke enterStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
        String enterStrokeKey = enterStroke.toString();

        inputMap.put(enterStroke, enterStrokeKey);
        actionMap.put(enterStrokeKey, new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Enter pressed");
            }
        });
        intoMap(inputMap, actionMap, Direction.UP, KeyEvent.VK_UP);
        intoMap(inputMap, actionMap, Direction.DOWN, KeyEvent.VK_DOWN);
        intoMap(inputMap, actionMap, Direction.LEFT, KeyEvent.VK_LEFT);
        intoMap(inputMap, actionMap, Direction.RIGHT, KeyEvent.VK_RIGHT);
    }

    private void intoMap(InputMap inputMap, ActionMap actionMap, Direction dir, int keyCode) {
        KeyStroke release = KeyStroke.getKeyStroke(keyCode, 0, true);
        KeyStroke pressed = KeyStroke.getKeyStroke(keyCode, 0, false);
        inputMap.put(pressed, pressed.toString());
        inputMap.put(release, release.toString());
        actionMap.put(pressed.toString(), new DirectionAction(dir, false));
        actionMap.put(release.toString(), new DirectionAction(dir, true));
    }

    private class DirectionAction extends AbstractAction {
        private Direction dir;
        private boolean onRelease;

        public DirectionAction(Direction dir, boolean onRelease) {
            this.dir = dir;
            this.onRelease = onRelease;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.printf("Direction: %s; On Released: %b%n", dir.toString(), onRelease);
        }
    }
}

enum Direction {
    UP, DOWN, LEFT, RIGHT
}

class LoginPanel extends MyJPanel {

}

class MenuPanel extends MyJPanel {

}

class HighscorePanel extends MyJPanel {

}

class InstructionPanel extends MyJPanel {

}

@SuppressWarnings("serial")
class MyJPanel extends JPanel {
    public MyJPanel() {
        setBorder(BorderFactory.createTitledBorder(getClass().getSimpleName()));
    }
}

class ZCraft {

    public ZCraft(String user) {
    }

    public void render(Graphics g) {

    }

    public void moveXAxis(boolean b) {

    }

    public void moveYAxis(boolean b) {

    }

}