keyevent question

Hi,

In my JOGL application (which is running on Linux) I have set up a KeyListener. When the user presses a . character several thousand GLDrawPixel() commands take place (within loops of course), positioning png images at critical points on my GLcanvas. Each successive press of . will cause these images to be displayed in completely different positions. This works ok, but the problem I have is that if the user holds the . key down for half a second, the canvas is still changing 3 seconds later, as the key events are queued. When the user releases the key, I would like the canvas to stop its updating immediately. Have tried removing the keylistener when the redrawing method starts and then adding it again as it finishes but this does not work (when I thought it would :frowning: )

Note that I DO want the user to be able to hold the . key down and watch the display change (as smoothly as possible) but the key release effect should be instantaneous else the user won’t feel in control of the program.

Any tips appreciated.
Tks

Sally

If you haven’t set up an Animator then all your drawing is done on the swing event thread. So removing the listener when you start displaying, and adding it when you finished doesn’t do anything, since the swing event loop will not be processing any events while you are displaying.

The way I would fix this problem would be to split the problem into 3 areas/threads. I would create an Animator that will run the display loop. The one that comes with JOGL just tries to draw as fast as possible, but you could modify it to support more of a repaint() style operation, but would still draw on its own thread. This way the swing event thread is free to respond to any events which should keep events from “backing up”. The final part would be to set up a Timer that fires x number of microseconds, and start it when the user presses your key, and then stop it when the user releases your key. In that Timer you could do the logic to change all of your points (just be careful not to re arange all the points while you are trying to draw them).

Or you could just install JInput and poll for the keys every time through the display method. =)

Thanks for that answer. There’s some useful ideas in there.

Just one question. I am getting a keyReleased event for each keyPressed event (even when the key is held down) - I have read that on windows systems you get a keyReleased when the user physically releases the key but on Linux you get a keyRelease for every keyPress (due to the way the os handles the requests). Is this likely to be a problem for stopping the timer correctly?

Txs

Sally

I don’t know if this will help. But if you take a look at:

http://nehe.gamedev.net/data/lessons/jogl/lesson10.jar

you can unjar/unzip the jar file and look at Lesson.java you’ll see how there is an array of booleans for the keycodes and they are set with keyPressed and unset with keyReleased. Then inside of display() the codes are examined.

I don’t know if this really helps or not. But I had a similar problem and it fixed it.

-Mike

Just for interest, I stumbled upon a good way of fixing this problem myself with only 3 lines of code in the keyPressed method (it’s got to be better than using threads and timers :D. … and it DOES work. I can’t believe I could not find this easy fix in any forums or from any search engines.

  public void keyPressed(KeyEvent e)
  {
    // gets the next key press in the event queue - if it is "null" then the current KeyEvent is the last in the queue
      KeyEvent nextPress = (KeyEvent) Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent(KeyEvent.KEY_PRESSED);
    if (nextPress != null)
      return;
      // else process key event 
   }