Results 1 to 16 of 16
  1. #1
    plm-pusik is offline Member
    Join Date
    Aug 2010
    Posts
    17
    Rep Power
    0

    Default AWT KeyListener Problem

    Hey, I've been working on the game "Hangman" for school and it works great. But I'm having some trouble with the keylistener. Whenever the player fails on guessing a word I want the game to display the correct word and then wait for 3 seconds before continuing again.
    Java Code:
    } else if(!window.nextImage()) { //Ask the window to display the next picture, if false is returned it's the last image and the player failed
        for(char a: wordAnalyze.keySet()) //Displays the correct word
            for(int b: wordAnalyze.get(a))
                window.put(Character.toString(a), b);
        window.update(window.getGraphics()); //Force updates the window before sleep is called
        try{Thread.sleep(3000L);}catch(Exception e){}
        initThings();
    }
    That works fine but it still listens to my keyboard after I've put it sleep, and I don't want that. Because if the player for example clicks 'A', 'B' and 'C' while it's sleeping those keystrokes counts as pressed once the game wakes up again and a new round has begun. I've tried removing the listener before calling sleep but that had no effect, I've also tried adding like a if(shouldListenToKeystrokes) in the keylistener method that I set to false before I put it to sleep, but that had no effect either. It seems like it writes all the keystrokes to some kind of list or w/e while it's sleeping and then when it wakes up it sends them to my program.

    To summarize: How do I stop it from listening to my keystrokes while it's sleeping or, how do I make it ignore my keystrokes while it's sleeping?

    Hope I made myself clear. Let me know if you need any more information about my code or if you need some more code snippets.
    -PLM
    Last edited by plm-pusik; 10-30-2010 at 10:07 AM.

  2. #2
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,371
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by plm-pusik View Post
    To summarize: How do I stop it from listening to my keystrokes while it's sleeping or, how do I make it ignore my keystrokes while it's sleeping?
    Remove the KeyListener while the program is displaying the answer so nothing will listen for key strokes ...

    kind regards,

    Jos

  3. #3
    plm-pusik is offline Member
    Join Date
    Aug 2010
    Posts
    17
    Rep Power
    0

    Default

    Quote Originally Posted by JosAH View Post
    Remove the KeyListener while the program is displaying the answer so nothing will listen for key strokes ...

    I've tried that, maybe I did it wrong though. This is how I add the keylistener:
    Java Code:
    addKeyListener(this);
    I call that in the constructor of the class that handles the graphics window. The keylistener method is in the same class.

    Then I remove it in the class that handles the gameplay by calling:
    Java Code:
    window.removeKeyListener(window);
    for(char a: wordAnalyze.keySet()) //Displays the correct word
        for(int b: wordAnalyze.get(a))
            window.put(Character.toString(a), b);
    window.update(window.getGraphics()); //Force updates the window before sleep is called
    try{Thread.sleep(3000L);}catch(Exception e){}
    window.addKeyListener(window);
    initThings();
    Where window is the instance that handles the window.

    Did I do it wrong? I appreciate the quick answer.
    -PLM
    Last edited by plm-pusik; 10-30-2010 at 10:41 AM.

  4. #4
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,371
    Blog Entries
    7
    Rep Power
    20

    Default

    So what is happening now? You could add a System.out.println( ... ) in the key handler itself and see if your program responds to key presses.

    kind regards,

    Jos

  5. #5
    plm-pusik is offline Member
    Join Date
    Aug 2010
    Posts
    17
    Rep Power
    0

    Default

    Quote Originally Posted by JosAH View Post
    So what is happening now? You could add a System.out.println( ... ) in the key handler itself and see if your program responds to key presses.

    This is how the code looks like now:
    Java Code:
    window.removeKeyListener(window);
        for(char a: wordAnalyze.keySet()) //Displays the correct word
            for(int b: wordAnalyze.get(a))
                window.put(Character.toString(a), b);
    window.update(window.getGraphics()); //Force updates the window before sleep is called
    
    System.out.println("Going to sleep...");
    try{Thread.sleep(3000L);}catch(Exception e){}
    System.out.println("Woke up!");
    
    window.addKeyListener(window);
    initThings();
    Java Code:
    public void keyReleased(KeyEvent key) { //If a keyboard button was released
        System.out.println("The user pressed the key "+key.getKeyChar());
        
        char pressedKey = Character.toUpperCase(key.getKeyChar());
        if(pressedKey >= 'A' && pressedKey <= 'Z' && charButtons.getComponent(pressedKey-'A').isEnabled()) { //If the key pressed was valid and if it hasn't been pressed before
            charButtons.getComponent(pressedKey - 'A').setEnabled(false); //Set the button to disabled
            GubbeClass.goFigure(Character.toString(pressedKey)); //Figure what to do with the inputed letter (calls the method containing the code snippet above)
        }
    }

    Gives the output:
    Java Code:
    /* I click some random buttons so that I fail on guessing the word */
    The user pressed the key a
    The user pressed the key b
    The user pressed the key c
    The user pressed the key d
    The user pressed the key e
    The user pressed the key f
    The user pressed the key g
    The user pressed the key h
    Going to sleep...
    /* I press the keys i, j, k, l, m, n, o, while it's sleeping. */
    Woke up!
    The user pressed the key i
    The user pressed the key j
    The user pressed the key k
    The user pressed the key l
    The user pressed the key m
    The user pressed the key n
    The user pressed the key o
    -PLM
    Last edited by plm-pusik; 10-30-2010 at 11:21 AM.

  6. #6
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,371
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by plm-pusik View Post
    Gives the output:
    Java Code:
    /* I click some random buttons so that I fail on guessing the word */
    The user pressed the key a
    The user pressed the key b
    The user pressed the key c
    The user pressed the key d
    The user pressed the key e
    The user pressed the key f
    The user pressed the key g
    The user pressed the key h
    Going to sleep...
    /* I press the keys i, j, k, l, m, n, o, while it's sleeping. */
    Woke up!
    The user pressed the key i
    The user pressed the key j
    The user pressed the key k
    The user pressed the key l
    The user pressed the key m
    The user pressed the key n
    The user pressed the key o
    -PLM
    Grmph, it seems that those key strokes are buffered. The KeyEvent inherits the getWhen() method; it returns the time stamp when the event was fired. If it was fired while your thread is asleep, ignore the event.

    kind regards,

    Jos

  7. #7
    plm-pusik is offline Member
    Join Date
    Aug 2010
    Posts
    17
    Rep Power
    0

    Default

    Alright I'll try that when I come back. I can't help feeling like there should be a different way of getting around this. I'll let you know if it worked or not (though it probably will) when I come back.

    -PLM

  8. #8
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,371
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by plm-pusik View Post
    Alright I'll try that when I come back. I can't help feeling like there should be a different way of getting around this. I'll let you know if it worked or not (though it probably will) when I come back.
    I'm not happy with this solution/hack either but I lack the imagination to come up with something else; I give it a second thought and in the mean time we have to wait until one of the Swing magicians shows up (Darryl, Camickr ...)

    kind regards,

    Jos

  9. #9
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by JosAH View Post
    ... I give it a second thought and in the mean time we have to wait until one of the Swing magicians shows up (Darryl, Camickr ...)
    We don't know yet if we're dealing with Swing or AWT, and it would probably be a good thing for the OP to clarify things. If this were Swing, I'd probably do things very differently.

  10. #10
    plm-pusik is offline Member
    Join Date
    Aug 2010
    Posts
    17
    Rep Power
    0

    Default

    Quote Originally Posted by Fubarable View Post
    it would probably be a good thing for the OP to clarify things. If this were Swing, I'd probably do things very differently.
    Ah of course. Well, the GUI things are all Swing (except for layouts, Dimension, Container and Font which are all AWT). My class that handles the GUI is a subclass of JFrame and this is the class that also handles the events. The events are AWT (ActionListener for GUI buttons and KeyListener for keyboard buttons). The "structure" of my program is as following:

    - One class that handles all the gameplay stuff, e.g reads the file containing words, decides if the player won/lost, initializes everything(including the GUI window), detects if the letter pressed was in the word etc. This is the class that in my code calls Thread.sleep. All methods are static.
    - One class that handles the GUI. This class is a subclass of Swing JFrame and contains the buttons, the hangman image etc. This class itself does not make any gameplay decisions (except if the keyboard button pressed was A -> Z). This is the class that listens for key strokes and for GUI buttons which are then passed over to the class above. I listen to key strokes by calling addKeyListener(this); (it listens to itself). To get keyboard focus I call requestFocus(); .No methods are static (an object of this class is created by the class above).

    If it's to little information then let me know ... hope you understand as I probably didn't use fancy programming words.

    The time stamp idea worked by the way, but I'd prefer a different way.

    -PLM
    Last edited by plm-pusik; 10-30-2010 at 04:18 PM.

  11. #11
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,371
    Blog Entries
    7
    Rep Power
    20

    Default

    Quote Originally Posted by plm-pusik View Post
    The time stamp idea worked by the way, but I'd prefer a different way.
    The problem is that your thread may be sleeping, the AWT event dispatching thread isn't, and better so because a sleeping event dispatch thread freezes the entire gui. You don't want to process those key events but I know of no way to 'block' the keyboard. The hack was to ignore those events while your thread is sleeping but I'm also very curious to know a more elegant solution.

    kind regards,

    Jos

  12. #12
    plm-pusik is offline Member
    Join Date
    Aug 2010
    Posts
    17
    Rep Power
    0

    Default

    Bump, any other ideas?

  13. #13
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Recommend you create and post an SSCCE that reproduces your problem. Please check out the 3rd link in my signature links to see what this means.

  14. #14
    plm-pusik is offline Member
    Join Date
    Aug 2010
    Posts
    17
    Rep Power
    0

    Default

    Java Code:
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    
    
    
    
    /*
     * This class handles the gameplay.
     * How do I properly "pause" the program?
     */
    public class MyProblem {
      public static void putToSleep() {
        System.out.println("Going to sleep, press some keys now.");
        try{Thread.sleep(5000);}catch(Exception e){}
        System.out.println("Woke up.");
      }
      public static void main(String[] args) {
        new MyProblemWindow();
      }
    }
    
    
    
    
    /*
     * This class handles the window and all its components.
     * When the button is pressed I want this class to call
     * "MyProblem" which then "pauses" the entire program. 
     * While the program is paused I do not want the program
     * to listen for keystrokes, but as you can see  by the 
     * output, it does it anyway.
     */
    class MyProblemWindow extends JFrame implements 
                                  KeyListener, ActionListener {
      private static final long serialVersionUID = 1L;
      @Override
      public void actionPerformed(ActionEvent e) {
        //If the button was pressed
        MyProblem.putToSleep();
      }
      @Override
      public void keyReleased(KeyEvent key) {
        //If a keyboard key was pressed
        System.out.println("Key released: "+key.getKeyChar());
      }
      @Override
      public void keyPressed(KeyEvent key) {}
      @Override
      public void keyTyped(KeyEvent key) {}
      
      public MyProblemWindow() {
        JButton myButton = new JButton("Go to sleep");
        myButton.addKeyListener(this);
        myButton.addActionListener(this);
        add(myButton);
        setPreferredSize(new Dimension(100,100));
        pack();
        setVisible(true);
      }
    }
    I hope that works fine.

    As you can see by the output, it prints out the keys you pressed during the time it slept (apparently, it still listens to the keyboard while it's asleep). I don't want this to happen. The main questions here are:

    - How can I keep it from listening to the keyboard while the program is sleeping? Without using the timestamp method mentioned in a previous post.
    - Is there any other way to "pause" a program?

    -PLM

  15. #15
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,184
    Rep Power
    19

    Default

    You're calling sleep(...) on the EDT. That's a BIG no-no.

    Recommended reading: Lesson: Concurrency in Swing (The Java™ Tutorials > Creating a GUI With JFC/Swing)

    And yes, the pending events will be added to the event queue regardless of whether the EDT is sleeping or not. I suggest you show the 'correct word' in a modal JDialog that is dismissed by a Timer (which of course must be started before displaying the dialog).

    Alternatively, and if you want the word displayed on the same JFrame, remove the listener, show the word and start a Timer. When the Timer triggers, its actionPerformed should re-add the listener.
    Java Code:
    import java.awt.Dimension;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class NoProblem {
    
      public static void main(String[] args) {
        new MyProblemWindow();
      }
    }
    
    class MyProblemWindow extends JFrame implements
            KeyListener, ActionListener {
    
      private static final long serialVersionUID = 1L;
      private JButton myButton;
    
      @Override
      public void actionPerformed(ActionEvent e) {
        //If the button was pressed
        putToSleep();
      }
    
      public void putToSleep() {
        myButton.removeKeyListener(this);
        myButton.setEnabled(false);
        System.out.println("Going to sleep, press some keys now.");
        Timer timer = new Timer(5000, new ActionListener() {
    
          @Override
          public void actionPerformed(ActionEvent e) {
            System.out.println("Woke up.");
            myButton.addKeyListener(MyProblemWindow.this);
            myButton.setEnabled(true);
          }
        });
        timer.setRepeats(false);
        timer.start();
      }
    
      @Override
      public void keyReleased(KeyEvent key) {
        //If a keyboard key was pressed
        System.out.println("Key released: " + key.getKeyChar());
      }
    
      @Override
      public void keyPressed(KeyEvent key) {
      }
    
      @Override
      public void keyTyped(KeyEvent key) {
      }
    
      public MyProblemWindow() {
        myButton = new JButton("Go to sleep");
        myButton.addKeyListener(this);
        myButton.addActionListener(this);
        add(myButton);
        setPreferredSize(new Dimension(100, 100));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
      }
    }
    About your SSCCE -- good, devoid of extraneous factors that detract from the problem, which is a good motivation to more experienced members to offer help. Just this: in future, as a courtesy to those who will run your program in order to try and fix it, set the defaultCloseOperation of a JFrame so that the program does actually terminate when the frame is closed.

    db

  16. #16
    plm-pusik is offline Member
    Join Date
    Aug 2010
    Posts
    17
    Rep Power
    0

    Default

    Thanks Darryl, that worked great.

    Quote Originally Posted by Darryl.Burke View Post
    Just this: in future, as a courtesy to those who will run your program in order to try and fix it, set the defaultCloseOperation of a JFrame so that the program does actually terminate when the frame is closed.
    Will do.

    -PLM

Similar Threads

  1. keyListener not doing anything
    By imorio in forum AWT / Swing
    Replies: 10
    Last Post: 08-17-2010, 10:46 PM
  2. KeyListener problem
    By siyi90 in forum AWT / Swing
    Replies: 7
    Last Post: 02-08-2010, 10:16 AM
  3. Problem with KeyListener in Jtable
    By sandeepsai17 in forum New To Java
    Replies: 0
    Last Post: 06-30-2009, 10:14 AM
  4. KeyListener Example
    By Java Tip in forum SWT
    Replies: 0
    Last Post: 07-11-2008, 04:46 PM
  5. how to add a KeyListener
    By leonard in forum New To Java
    Replies: 1
    Last Post: 08-06-2007, 04:44 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •