Results 1 to 16 of 16
Thread: AWT KeyListener Problem
- 10-30-2010, 11:03 AM #1
Member
- Join Date
- Aug 2010
- Posts
- 17
- Rep Power
- 0
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(); }
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.
-PLMLast edited by plm-pusik; 10-30-2010 at 11:07 AM.
- 10-30-2010, 11:26 AM #2
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 14,422
- Blog Entries
- 7
- Rep Power
- 28
- 10-30-2010, 11:34 AM #3
Member
- Join Date
- Aug 2010
- Posts
- 17
- Rep Power
- 0
I've tried that, maybe I did it wrong though. This is how I add the keylistener:
Java Code:addKeyListener(this);
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();
Did I do it wrong? I appreciate the quick answer.
-PLMLast edited by plm-pusik; 10-30-2010 at 11:41 AM.
- 10-30-2010, 11:45 AM #4
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 14,422
- Blog Entries
- 7
- Rep Power
- 28
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
- 10-30-2010, 12:03 PM #5
Member
- Join Date
- Aug 2010
- Posts
- 17
- Rep Power
- 0
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
Last edited by plm-pusik; 10-30-2010 at 12:21 PM.
- 10-30-2010, 12:10 PM #6
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 14,422
- Blog Entries
- 7
- Rep Power
- 28
- 10-30-2010, 12:43 PM #7
Member
- Join Date
- Aug 2010
- Posts
- 17
- Rep Power
- 0
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
- 10-30-2010, 12:55 PM #8
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 14,422
- Blog Entries
- 7
- Rep Power
- 28
-
- 10-30-2010, 05:13 PM #10
Member
- Join Date
- Aug 2010
- Posts
- 17
- Rep Power
- 0
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.
-PLMLast edited by plm-pusik; 10-30-2010 at 05:18 PM.
- 10-30-2010, 05:36 PM #11
- Join Date
- Sep 2008
- Location
- Voorschoten, the Netherlands
- Posts
- 14,422
- Blog Entries
- 7
- Rep Power
- 28
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
- 10-31-2010, 11:47 PM #12
Member
- Join Date
- Aug 2010
- Posts
- 17
- Rep Power
- 0
Bump, any other ideas?
-
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.
- 11-09-2010, 12:30 PM #14
Member
- Join Date
- Aug 2010
- Posts
- 17
- Rep Power
- 0
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); } }
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
- 11-09-2010, 03:18 PM #15
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); } }
db
- 11-10-2010, 04:38 PM #16
Member
- Join Date
- Aug 2010
- Posts
- 17
- Rep Power
- 0
Similar Threads
-
keyListener not doing anything
By imorio in forum AWT / SwingReplies: 10Last Post: 08-17-2010, 11:46 PM -
KeyListener problem
By siyi90 in forum AWT / SwingReplies: 7Last Post: 02-08-2010, 11:16 AM -
Problem with KeyListener in Jtable
By sandeepsai17 in forum New To JavaReplies: 0Last Post: 06-30-2009, 11:14 AM -
KeyListener Example
By Java Tip in forum SWT TipsReplies: 0Last Post: 07-11-2008, 05:46 PM -
how to add a KeyListener
By leonard in forum New To JavaReplies: 1Last Post: 08-06-2007, 05:44 PM
Bookmarks