This discussion is archived
8 Replies Latest reply: Nov 14, 2009 6:23 PM by gimbal2 RSS

Questions about KeyListeners

795507 Newbie
Currently Being Moderated
I'm trying to get this code to work for my program, which will just have a basic sprite wandering around the screen. For now, it is supposed to take a key then print out which key was pressed:
public class CTFMain extends JPanel implements KeyListener
{
    public CTFMain()
    {
        super();

        this.addKeyListener(this);
    }

    public static void main(String[] args)
    {
        JFrame frame = new JFrame("Capture the Flag");
        CTFMain game = new CTFMain();

        frame.add(game);
        frame.pack();
        frame.setResizable(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        while(true)
        {
            game.tic();

            try
            {
                Thread.sleep(1000/60);
            }
            catch(Exception e)
            {

            }
        }
    }

    public void keyPressed(KeyEvent e)
    {
        switch(e.getKeyCode())
         {
              case KeyEvent.VK_DOWN:          System.out.println("Down is being pressed.");
                              break;
          case KeyEvent.VK_UP:          System.out.println("Up is being pressed.");
                              break;
          case KeyEvent.VK_LEFT:          System.out.println("Left is being pressed.");
                              break;
          case KeyEvent.VK_RIGHT:          System.out.println("Right is being pressed.");
                              break;
          default:               break;
         }
    }
    
    public void keyReleased(KeyEvent e)
    {
         switch(e.getKeyCode())
         {
              case KeyEvent.VK_DOWN:          System.out.println("Down got released.");
                              break;
          case KeyEvent.VK_UP:          System.out.println("Up got released.");
                              break;
          case KeyEvent.VK_LEFT:          System.out.println("Left got released.");
                              break;
          case KeyEvent.VK_RIGHT:          System.out.println("Right got released.");
                              break;
          default:               break;
         }
    }
    
    public void keyTyped(KeyEvent e)
    {
         System.out.println(e.getKeyChar() + " was pressed");
    }
}
My problem is that my program won't recognize any key commands at all. I have it implemented as seen above (minus the code for the graphics update, sprite controls, etc.), and nothing happens when I press a key. I've tried running my code in the shell. I've tried running with my code dependent on a MouseListener and it works fine, so it has nothing to do with the update code. I've even tried fixing the KeyListener to a JTextField and getting the commands off of that, but nothing happens, not even errors (in the JTextField thing, I got letters in the field, but they didn't trigger the KeyEvents). Is there something I am doing wrong? Is there a comprehensive tutorial for KeyListeners somewhere?
  • 1. Re: Questions about KeyListeners
    843853 Newbie
    Currently Being Moderated
    Your program implements KeyListener, but you don't actually add a key listener to your object.
    CTFMain game = new CTFMain(); // new isnstance of CTFMain--no listener added
    game.addKeyListener(this);  // should fix your problems
  • 2. Re: Questions about KeyListeners
    gimbal2 Guru
    Currently Being Moderated
    You should make sure that the component with the key listener has the focus, or else it won't receive keyboard input.
    frame.add(game);
    game.requestFocus();
    Note: typed from memory. I don't remember if it was requestFocus() or requestFocusInWindow().
  • 3. Re: Questions about KeyListeners
    843853 Newbie
    Currently Being Moderated
    I always just use something like this:

    frame.addKeyListener(new KeyListener() {
    public void keyPressed(KeyEvent e) {

    }

    public void keyReleased(KeyEvent e) {

    }

    public void keyTyped(KeyEvent e) {

    }
    });

    gimbal2 you were right, it's requestFocus().

    Edited by: b1nary on Nov 10, 2009 8:53 AM
  • 4. Re: Questions about KeyListeners
    795507 Newbie
    Currently Being Moderated
    The focus thing isn't helping. I tried adding it inside the main method and inside the constructor, and neither worked.
  • 5. Re: Questions about KeyListeners
    795507 Newbie
    Currently Being Moderated
    Never mind. I got it to work. Thanks, all.
  • 6. Re: Questions about KeyListeners
    gimbal2 Guru
    Currently Being Moderated
    good job, but please post what was wrong and how you fixed it. The answer might help other people with the same or a similar problem.
  • 7. Re: Questions about KeyListeners
    843853 Newbie
    Currently Being Moderated
    I know this question has already been answered but if you are programming in java then you should be trying to adhere to an OO model as closely as possible. As such you should not have all that code in the main method. you main should only instantiate objects needed to start the program, then those objects should take it from there. as an example:
    public class game extends JFrame implements KeyListener
    {
       //declare variables here, eg:
       Dimension screenSize;
       public game()
       {
          //here is where you initialise everything, eg:
          this.screenSize = Toolkit.getDefaultToolkit().screenSize;
          this.add(game);
          this.pack;
          this.addKeyListener(this);
          this.setVisible(true);
          //etc
          //now here is where you can either start your while(true) loop, or call a method called update or something which contains your while(true), eg:
          while(true)
          {
             game.tic;
             //etc
          }
       }
       //keylistener methods here
    }
    hope that helps you a bit
    btw i can't remember if for the toolkit its .getScreenSize(); or .screenSize;
    sutasman
  • 8. Re: Questions about KeyListeners
    gimbal2 Guru
    Currently Being Moderated
    Sutasman wrote:
    I know this question has already been answered but if you are programming in java then you should be trying to adhere to an OO model as closely as possible. As such you should not have all that code in the main method. you main should only instantiate objects needed to start the program, then those objects should take it from there. as an example:
    public class game extends JFrame implements KeyListener
    {
    //declare variables here, eg:
    Dimension screenSize;
    public game()
    {
    //here is where you initialise everything, eg:
    this.screenSize = Toolkit.getDefaultToolkit().screenSize;
    this.add(game);
    this.pack;
    this.addKeyListener(this);
    this.setVisible(true);
    //etc
    //now here is where you can either start your while(true) loop, or call a method called update or something which contains your while(true), eg:
    while(true)
    {
    game.tic;
    //etc
    }
    }
    //keylistener methods here
    }
    hope that helps you a bit
    btw i can't remember if for the toolkit its .getScreenSize(); or .screenSize;
    sutasman
    You make a (valid) comment about the main() method, and then you give an example where you cram everything into the constructor. That is bad enough, but you have an example with an endless loop in the constructor, which is a terribly crime in itself.

    If you want to give an example, at least make it one that is worth it. Don't have the experience or the willpower to do this? Then don't post advice or answers. This is simply misinformation you are giving.