Using KeyListener in a Loop

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • zakwiz
    New Member
    • Oct 2008
    • 3

    Using KeyListener in a Loop

    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?
  • JosAH
    Recognized Expert MVP
    • Mar 2007
    • 11453

    #2
    Originally posted by zakwiz
    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

    Comment

    • zakwiz
      New Member
      • Oct 2008
      • 3

      #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!

      Comment

      • sukatoa
        Contributor
        • Nov 2007
        • 539

        #4
        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(execu ted). 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,minimizin g the frame,keyboard press,released etc and etc) and then return/fire/show/updates the equivalent response(method s 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

        Comment

        • chaarmann
          Recognized Expert Contributor
          • Nov 2007
          • 785

          #5
          Originally posted by zakwiz
          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:
          Code:
          Scanner keyboard = new Scanner(System.in);
          do
          {
             String input = keyboard.nextLine();
             System.out.println("You just typed:" + input);
          } while (! input.equals("END"))
          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:
          Code:
          public class KeyEventDemo ...  implements KeyListener ... {
              ...//where initialization occurs:
          	typingArea = new JTextField(20);
          	typingArea.addKeyListener(this);
              ...
           
              /** Handle the key-pressed event from the text field. */
              public void keyPressed(KeyEvent e) {
          	System.out.println(("You just typed:" + e.getKeyChar());
              }
          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.

          Comment

          • zakwiz
            New Member
            • Oct 2008
            • 3

            #6
            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.

            Comment

            • chaarmann
              Recognized Expert Contributor
              • Nov 2007
              • 785

              #7
              Originally posted by zakwiz
              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:

              Code:
              public class KeyEventDemo ... { 
                  ... 
                  static String typedCharacters = "";
                  ...
                  public void keyTyped(KeyEvent e) {
                    int keyCode = keyEvent.getKeyCode();      
                    if (keyCode == 13) { // 13 = return-key
                       System.out.println("You just typed:" + typedCharacters);
                       typedCharacters = "";
                    }
                    else typedCharacters +=  e.getKeyChar();
                  }
              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.

              Comment

              • Sarii
                New Member
                • Oct 2008
                • 7

                #8
                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.

                Comment

                • JosAH
                  Recognized Expert MVP
                  • Mar 2007
                  • 11453

                  #9
                  Originally posted by Sarii
                  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

                  Comment

                  • Sarii
                    New Member
                    • Oct 2008
                    • 7

                    #10
                    Code:
                    switch(key)
                    		{
                    			case 'a': System.out.println("You typed A");
                    			break;
                    			case 'b': System.out.println("You typed B");
                    			break;
                    			case 'c': System.out.println("You typed C");
                    			break;
                    			case 'e': System.out.println("You typed E");
                    			break;
                    			default: System.out.println("Invalid key type");
                    			break;
                    I was thinking along the lines of this...but maybe not..? Lol.

                    Comment

                    Working...