0

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
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
Ben
  • 141
  • 2
  • 12

1 Answers1

3
  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");
   }

}
Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Thanks, I really appreciate the help. I made this post and then decided it would be better to ask all my questions at once and so I made my other post, intending to delete this one but then I saw your example and started reading and time got away from me. That's why I had the second one up at the same time, sorry. I didn't know it was gauche to ask bigger questions at the same time, I'll keep that in mind for the future. I deleted the second post and I'm working through your advice now. Do you have a good textbook recommendation that covers keybinding? My intro text doesn't and I'm the kind – Ben Apr 23 '14 at 22:33
  • of person who needs lots of examples and thorough explanations if I'm going to actually learn something and not just mimic examples I find online. – Ben Apr 23 '14 at 22:33
  • @Ben: no, I don't know of any decent book on it, other than 1) the tutorials (see link in my answer), and studying key binding code examples on this site. Search the site for the term, and you'll find lots, much written by me. As for your other problems, you will want to ask specific individual questions for each specific problem you're encountering, and you'll need to put in a little more effort when asking the questions, including isolating the code of interest and posting a small self-contained testable runnable program, similar to what I've posted above. – Hovercraft Full Of Eels Apr 23 '14 at 22:37