469,352 Members | 2,145 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,352 developers. It's quick & easy.

Using KeyListener in a Loop

3
I am relatively new to Java, so please excuse me if I'm not specific enough. I am making a program where a large portion of it is just one big while loop, and I want to be able to read specific keys being pushed to invoke different commands and methods, but apparently KeyListener doesn't work inside of a loop. Is there another, relatively simple way for me to read keyboard input?
Oct 26 '08 #1
9 13287
JosAH
11,448 Expert 8TB
I am relatively new to Java, so please excuse me if I'm not specific enough. I am making a program where a large portion of it is just one big while loop, and I want to be able to read specific keys being pushed to invoke different commands and methods, but apparently KeyListener doesn't work inside of a loop. Is there another, relatively simple way for me to read keyboard input?
If you're using Swing you have to 'invert' your logic, i.e. your program is not in
control as long as the user doesn't do anything. Your program doesn't wait or
run in a while loop. It's one special thread the EDT (Event Dispatch Thread) that
does the waiting (and painting of visual components if needed) and fires an
event to a registered Listener when the user causes that event.

Basically you register your KeyListener to some component and don't do anything
at all. When the user presses a key the EDT fires an event and your Listener will
be activated. Only then does your program do something: it should quickly do
something as long as it runs in the EDT or start another thread that does the job.

A lot of people make that mistake: they process whatever they have to process
in the EDT which ties that thread to your business logic; it is supposed to check
for events and repaint visual components instead. As long as its busy for your
purposes it can't pay any attention to user gestures and your application seems
to respond sluggish.

kind regards,

Jos
Oct 27 '08 #2
zakwiz
3
Thank you a lot for your help, but unfortunately I am VERY new to Java, and though you obviously know what you're talking about, I don't really get it. I would really appreciate it if you or someone else explained it in simpler terms. Thanks!
Oct 28 '08 #3
sukatoa
539 512MB
when using Graphical User Interface in your application,

let say, that component(Frame,Dialog etc) throws another thread that handles a while loop started after it was activated(executed). Its job is to show whatever instructions you've setup(coded GUI, unless you call the dispose() method, where that method stops showing the interface and not the thread itself),waits for any event(clicking the mouse,minimizing the frame,keyboard press,released etc and etc) and then return/fire/show/updates the equivalent response(methods under the specific listeners that implements the EventListener are called directly after any event is fired, ex. clicked)....see the Java API Documentation.

I prefer to code directly with the sample code from java tutorials with the API Documentation and OBSERVE its behavior if i don't understand what the book says than trying to grasp what the content(book) says to the readers.... (some theories are came from experiments)....

regards,
sukatoa
Oct 28 '08 #4
chaarmann
785 Expert 512MB
Thank you a lot for your help, but unfortunately I am VERY new to Java, and though you obviously know what you're talking about, I don't really get it. I would really appreciate it if you or someone else explained it in simpler terms. Thanks!
It is called "polling" what you are trying to do:
Expand|Select|Wrap|Line Numbers
  1. Scanner keyboard = new Scanner(System.in);
  2. do
  3. {
  4.    String input = keyboard.nextLine();
  5.    System.out.println("You just typed:" + input);
  6. } while (! input.equals("END"))
  7.  
Here, the running thread waits inside the loop until you inserted a line and pressed return. Only then it executes the next command.

It is called "interrupt" what you need to do. This is the common case in event handling:
That means, the system itself looks from outside at your functions you have written and whenever it detects one that handles the keyboard input, it just calls it. You only have to write the function, nothing else. And if you press a second button while your first function is still running, your function is called again and runs in parallel to your first one (as a second thread). This parallel run is not possible if you use "polling" as written above.
Look at this example:
Expand|Select|Wrap|Line Numbers
  1. public class KeyEventDemo ...  implements KeyListener ... {
  2.     ...//where initialization occurs:
  3.     typingArea = new JTextField(20);
  4.     typingArea.addKeyListener(this);
  5.     ...
  6.  
  7.     /** Handle the key-pressed event from the text field. */
  8.     public void keyPressed(KeyEvent e) {
  9.     System.out.println(("You just typed:" + e.getKeyChar());
  10.     }
  11.  
Please note that the function keyPressed() is called by the system. You don't call it yourself!

I hope this explanation makes it clearer for you.
Oct 28 '08 #5
zakwiz
3
chaarmann, I think you have it backwards, I'm doing it the way you show it called interrupting, as I have and have added a KeyListener and have code in the keyTyped method. It works fine elsewhere in the program, but within a while loop it just doesn't respond at all to typing, even if i press enter afterwards.
Oct 28 '08 #6
chaarmann
785 Expert 512MB
chaarmann, I think you have it backwards, I'm doing it the way you show it called interrupting, as I have and have added a KeyListener and have code in the keyTyped method. It works fine elsewhere in the program, but within a while loop it just doesn't respond at all to typing, even if i press enter afterwards.
I don't get it. Why do you need a while loop if you use KeyListener? The whole point in my explanation is that you don't need a while loop there at all.

Do you want to concatenate all the typed letters to a string and then only print it if a user pressed return? For that you don't need a while loop. You can do it with a static variable. Like here:

Expand|Select|Wrap|Line Numbers
  1. public class KeyEventDemo ... { 
  2.     ... 
  3.     static String typedCharacters = "";
  4.     ...
  5.     public void keyTyped(KeyEvent e) {
  6.       int keyCode = keyEvent.getKeyCode();      
  7.       if (keyCode == 13) { // 13 = return-key
  8.          System.out.println("You just typed:" + typedCharacters);
  9.          typedCharacters = "";
  10.       }
  11.       else typedCharacters +=  e.getKeyChar();
  12.     } 
REMARK:
This code does not take in mind parallel threads. So it only works if you don't type too fast. If you want to make it thread-save, then you have to use synchronisation mechanisms, which would make this sample code more complicated and less understandable.

I am curious what you want to achieve in your while-loop. Did I guess right?
It would be of great help if you show us your while-loop you have written so far.
Oct 29 '08 #7
Sarii
7
You could always just use a switch case. I don't know much about java, but that's what I would do! Even though the code would be relatively long and repetitive, it'll work out the way you want it to.
Oct 29 '08 #8
JosAH
11,448 Expert 8TB
You could always just use a switch case. I don't know much about java, but that's what I would do! Even though the code would be relatively long and repetitive, it'll work out the way you want it to.
I'm sorry, I don't see any use for a switch() statement here; care to elaborate?

kind regards,

Jos
Oct 29 '08 #9
Sarii
7
Expand|Select|Wrap|Line Numbers
  1. switch(key)
  2.         {
  3.             case 'a': System.out.println("You typed A");
  4.             break;
  5.             case 'b': System.out.println("You typed B");
  6.             break;
  7.             case 'c': System.out.println("You typed C");
  8.             break;
  9.             case 'e': System.out.println("You typed E");
  10.             break;
  11.             default: System.out.println("Invalid key type");
  12.             break;
  13.  
I was thinking along the lines of this...but maybe not..? Lol.
Dec 4 '08 #10

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

4 posts views Thread by pankajs | last post: by
3 posts views Thread by Humakt | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
1 post views Thread by Marylou17 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.