我有没有正确地构建这个关键监听器? [英] Did I structure this key listener properly?

查看:174
本文介绍了我有没有正确地构建这个关键监听器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我这么问是因为我想在我的的GamePanel 类的<​​code> addShot()方法被调用时,用户点击<大骨节病>输入,这个初始化一个镜头对象重新presenting从船上发射了一枚导弹,但它不会做任何事情。是否有知名度的问题在这里,还是我只是在结构关键事件和监听的关系错了吗?我只张贴相关code,但如果需要,我可以张贴的其余部分。

这里的code:

 公共静态类的GameTest扩展的JFrame {    私有静态最终诠释WINDOW_WIDTH = 800;
    私有静态最终诠释WINDOW_HEIGHT = 500;
    公众的GamePanel的GamePanel;
    公众的GameTest()抛出IOException
        超(炸自由);
        的setResizable(假);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        的setSize(WINDOW_WIDTH,WINDOW_HEIGHT);
        的setLayout(新的BorderLayout());
        的GamePanel =新的GamePanel();
        添加(的GamePanel);
        中心(本);
        调用setVisible(真);
        this.addKeyListener(新aKeyListener());
        this.setFocusable(真);    } //结束构造    公共无效中心(JFrame的帧){
        GraphicsEnvironment中GE = GraphicsEnvironment.getLocalGraphicsEnvironment();
        点中心= ge.getCenterPoint();        INT W = frame.getWidth();
        INT H = frame.getHeight();        INT X = center.x - 瓦特/ 2,Y = center.y - H / 2;
        frame.setBounds(X,Y,W,H);
        frame.validate();
    中心的方法} //结束    公共类aKeyListener实现的KeyListener {        @覆盖
        公共无效的keyTyped(KeyEvent的E){
        } //结束时清空法的keyTyped        @覆盖
        公共无效键pressed(KeyEvent的E){
            开关(e.getKey code()){
                案例KeyEvent.VK_A:
                    Launcher.lRun = -20;
                    gamePanel.move(的GamePanel);
                    打破;
                案例KeyEvent.VK_D:
                    Launcher.lRun = 20;
                    gamePanel.move(的GamePanel);
                    打破;
                案例KeyEvent.VK_ENTER:
                        gamePanel.addShot();
                    打破;
                默认:
                    Launcher.lRun = 0;
            }        } //结束键pressed方法        @覆盖
        公共无效调用keyReleased(KeyEvent的E){
        } //结束时清空的keyReleased方法    } //结束aKeyListener类} //结束的GameTest类


解决方案

  1. 此致可能是一个焦点问题 - 这是在的GamePanel偷焦点也许,一个非常常见的有KeyListeners问题

  2. 一般的建议:用按键绑定,而不是这种类型的需求的KeyListener的青睐

相关链接:


修改结果
例如:

 进口java.awt.Dimension中;
进口java.awt.event.ActionEvent中;
进口java.awt.event.KeyEvent中;进口的javax.swing *。公共类的GameTest扩展的JFrame {   私有静态最终诠释WINDOW_WIDTH = 800;
   私有静态最终诠释WINDOW_HEIGHT = 500;
   公众的GamePanel的GamePanel;   公众的GameTest(){
      超(炸自由);
      的setResizable(假);
      // setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      //的setSize(WINDOW_WIDTH,WINDOW_HEIGHT); //永远不要这样做
      的GamePanel =新的GamePanel();
      setUpKeyBinding(的GamePanel);
      添加(的GamePanel);
      包();
      setLocationRelativeTo(NULL); //为中心!
      调用setVisible(真);
   }   @覆盖
   公共尺寸的get preferredSize(){
      返回新的Dimension(WINDOW_WIDTH,WINDOW_HEIGHT);
   }   私人无效setUpKeyBinding(的GamePanel gamePanel2){      //只需要窗口具有焦点
      INT条件= JComponent.WHEN_IN_FOCUSED_WINDOW;      //获取的GamePanel的的InputMap和ActionMap中,因为这些将被用来设置
      //我们的键绑定
      InputMap中的InputMap = gamePanel2.getInputMap(条件);
      ActionMap中的ActionMap = gamePanel2.getActionMap();      //绑定一个重要回迁20个像素
      的KeyStroke keyStroke的= KeyStroke.getKeyStroke(KeyEvent.VK_A,0);
      inputMap.put(击键keyStroke.toString());
      actionMap.put(keyStroke.toString(),新MoveAction(gamePanel2,-20));      //绑定D键向前移动20个像素
      keyStroke的= KeyStroke.getKeyStroke(KeyEvent.VK_D,0);
      inputMap.put(击键keyStroke.toString());
      actionMap.put(keyStroke.toString(),新MoveAction(gamePanel2,20));      //绑定ENTER键
      keyStroke的= KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0);
      inputMap.put(击键keyStroke.toString());
      actionMap.put(keyStroke.toString(),新Ent​​erAction(gamePanel2));   }   公共静态无效的主要(字串[] args){
      新的GameTest();
   }   这将势必击键//我们的Action类
   私有类MoveAction扩展AbstractAction {
      私人的GamePanel gamePanel2;
      私人诠释距离;      公共MoveAction(的GamePanel gamePanel2,诠释距离){
         this.gamePanel2 = gamePanel2;
         this.distance =距离;
      }      @覆盖
      公共无效的actionPerformed(ActionEvent的五){
         gamePanel2.moveItem(距离);
      }
   }   私有类EnterAction扩展AbstractAction {
      私人的GamePanel gamePanel2;      公共EnterAction(的GamePanel gamePanel2){
         this.gamePanel2 = gamePanel2;
      }      @覆盖
      公共无效的actionPerformed(ActionEvent的五){
         gamePanel2.addShot();
      }
   }}//一个简单的GamePanel类只表示一切正在按预期
一流的GamePanel继承JPanel {   公共无效移动选项(int i)以{
      //你的移动选项的方法,而不是将实际移动的东西,我的距离
      的System.out.println(移动项目方法的距离:+ I);
   }   公共无效addShot(){
      //你的addShot方法将实际拍摄
      的System.out.println(添加拍摄法);
   }}

I'm asking because I want the addShot() method in my GamePanel class to be called when the user hits enter," this initializes a shot object representing a missile fired from a ship, but it doesn't do anything. Is there a visibility issue here, or did I just structure the key event and listener relationship wrong? I'm only posting relevant code, but I can post the rest if necessary.

Here's the code:

public static class GameTest extends JFrame {

    private static final int WINDOW_WIDTH = 800;
    private static final int WINDOW_HEIGHT = 500;
    public GamePanel gamePanel;


    public GameTest() throws IOException {
        super("Deep Fried Freedom");
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
        setLayout(new BorderLayout());
        gamePanel = new GamePanel();
        add(gamePanel);
        center(this);
        setVisible(true);
        this.addKeyListener(new aKeyListener());
        this.setFocusable(true);

    } // end constructor

    public void center(JFrame frame) {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        Point center = ge.getCenterPoint();

        int w = frame.getWidth();
        int h = frame.getHeight();

        int x = center.x - w / 2, y = center.y - h / 2;
        frame.setBounds(x, y, w, h);
        frame.validate();
    }//end of center method  

    public class aKeyListener implements KeyListener {

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

        @Override
        public void keyPressed(KeyEvent e) {
            switch (e.getKeyCode()) {
                case KeyEvent.VK_A:
                    Launcher.lRun = -20;
                    gamePanel.move(gamePanel);
                    break;
                case KeyEvent.VK_D:
                    Launcher.lRun = 20;
                    gamePanel.move(gamePanel);
                    break;
                case KeyEvent.VK_ENTER:
                        gamePanel.addShot();
                    break;
                default:
                    Launcher.lRun = 0;
            }

        }//end keyPressed method

        @Override
        public void keyReleased(KeyEvent e) {
        }//end empty keyReleased method

    }//end aKeyListener class

}//end GameTest class

解决方案

  1. Yours is likely a focus issue -- something in the GamePanel stealing focus perhaps, a very common problem with KeyListeners.
  2. General advice: favor using Key Bindings, not a KeyListener for this type of need.

Useful links:


Edit
For example:

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class GameTest extends JFrame {

   private static final int WINDOW_WIDTH = 800;
   private static final int WINDOW_HEIGHT = 500;
   public GamePanel gamePanel;

   public GameTest() {
      super("Deep Fried Freedom");
      setResizable(false);
      // setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      // setSize(WINDOW_WIDTH, WINDOW_HEIGHT); // never do this
      gamePanel = new GamePanel();
      setUpKeyBinding(gamePanel);
      add(gamePanel);
      pack();
      setLocationRelativeTo(null); // to center!
      setVisible(true);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT);
   }

   private void setUpKeyBinding(GamePanel gamePanel2) {

      // only need window to have focus 
      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; 

      // get the GamePanel's InputMap and ActionMap as these will be used to set
      // up our Key Bindings
      InputMap inputMap = gamePanel2.getInputMap(condition);
      ActionMap actionMap = gamePanel2.getActionMap();

      // bind the A key to move back 20 pixels
      KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0);
      inputMap.put(keyStroke, keyStroke.toString());
      actionMap.put(keyStroke.toString(), new MoveAction(gamePanel2, -20));

      // bind the D key to move forward 20 pixels
      keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_D, 0);
      inputMap.put(keyStroke, keyStroke.toString());
      actionMap.put(keyStroke.toString(), new MoveAction(gamePanel2, 20));

      // bind the ENTER key
      keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
      inputMap.put(keyStroke, keyStroke.toString());
      actionMap.put(keyStroke.toString(), new EnterAction(gamePanel2));

   }

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

   // our Action classes that will bound to key strokes
   private class MoveAction extends AbstractAction {
      private GamePanel gamePanel2;
      private int distance;

      public MoveAction(GamePanel gamePanel2, int distance) {
         this.gamePanel2 = gamePanel2;
         this.distance = distance;
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         gamePanel2.moveItem(distance);
      }
   }

   private class EnterAction extends AbstractAction {
      private GamePanel gamePanel2;

      public EnterAction(GamePanel gamePanel2) {
         this.gamePanel2 = gamePanel2;
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         gamePanel2.addShot();
      }
   }

}

// a trivial GamePanel class to just show that everything is working as expected
class GamePanel extends JPanel {

   public void moveItem(int i) {
      // your moveItem method will instead actually move something, a distance of i
      System.out.println("Move Item Method distance: " + i);
   }

   public void addShot() {
      // your addShot method will actually shoot
      System.out.println("Add Shot Method");
   }

}

这篇关于我有没有正确地构建这个关键监听器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆