Help coderanch get a
new server
by contributing to the fundraiser
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Dispatching keyPressed and keyReleased events in software.

 
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would like to have a JButton receive a KEY_PRESSED event when another JButton receives a MOUSE_PRESSED event, and to have that first JButton receive a KEY_RELEASED event when the second JButton receives a MOUSE_RELEASED event. The idea is to have one button be a "puppet" that the other button controls as a kind of "puppeteer." To do this, I've added a MouseListener to the puppeteer, and a KeyListener to the puppet. I've also provided an ActionListener to the puppet. When the puppet JButton has the focus, a press on the actual physical space-bar sends a KeyEvent to the puppet, with the KEY_PRESSED parameter. Subsequently releasing the space-bar sends a KeyEvent to the puppet, with the KEY_RELEASED parameter. Subsequent to that, the puppet's ActionListener is called, as I would expect it to be.

However, when I click and hold down the mouse button on the puppeteer, the puppeteer receives a MouseEvent sent to its mousePressed MouseListener method which, in turn, creates a KeyEvent with the KEY_PRESSED parameter that is given to the top-most JFrame's dispatchEvent method. This results in the puppet JButton receiving a keyPressed event with the KEY_PRESSED parameter, just as when it received such an event pursuant to having the focus and my pressing the keyboard's space-bar. But, rather than waiting for a KeyEvent with the KEY_RELEASED parameter, the puppet's ActionListener is called immediately. When I release the mouse button, the puppeteer receives a mouseReleased event, and its MouseListener sends a KeyEvent to the puppet, with the KEY_RELEASED parameter. But the puppet, already having called its ActionListener, doesn't call it again. I would have expected the puppet not to call its ActionListener until after the puppeteer had sent it a keyReleased event.

Even more confusing, the puppet alternates between waiting for the puppeteer to send it a keyReleased event before calling its ActionListener, and not waiting for that keyReleased event, on every other press of the mouse button on the puppeteer. Here is my output when I run the program, the puppet has the focus, and I simply press and release the space-bar:

Puppet key pressed:
ID=401
KeyCode=32
ParamString='KEY_PRESSED,keyCode=32,keyText=Space,keyChar=' ',keyLocation=KEY_LOCATION_STANDARD,rawCode=32,primaryLevelUnicode=32,scancode=57,extendedKeyCode=0x20'

Puppet key released:
ID=402
KeyCode=32
ParamString='KEY_RELEASED,keyCode=32,keyText=Space,keyChar=' ',keyLocation=KEY_LOCATION_STANDARD,rawCode=32,primaryLevelUnicode=32,scancode=57,extendedKeyCode=0x20'

Puppet action performed.


That's what I expected. The puppet's KeyListener receives the keyPressed event, then receives the keyReleased event, then calls its ActionListener. Here's what I get when I run the program and click once with the mouse on the puppeteer:

Puppeteer Mouse Pressed

Puppet key pressed:
ID=401
KeyCode=32
ParamString='KEY_PRESSED,keyCode=32,keyText=Space,keyChar=' ',keyLocation=KEY_LOCATION_STANDARD,rawCode=0,primaryLevelUnicode=0,scancode=0,extendedKeyCode=0x0'

Puppet action performed.

Puppeteer Mouse Released

Puppet key released:
ID=402
KeyCode=32
ParamString='KEY_RELEASED,keyCode=32,keyText=Space,keyChar=' ',keyLocation=KEY_LOCATION_STANDARD,rawCode=0,primaryLevelUnicode=0,scancode=0,extendedKeyCode=0x0'


The puppet does not wait to receive a keyReleased event before calling its ActionListener. In the same run of the program that generated the preceding output, here's the additional output I receive when I click with the mouse a second time on the puppeteer:

Puppeteer Mouse Pressed

Puppet key pressed:
ID=401
KeyCode=32
ParamString='KEY_PRESSED,keyCode=32,keyText=Space,keyChar=' ',keyLocation=KEY_LOCATION_STANDARD,rawCode=0,primaryLevelUnicode=0,scancode=0,extendedKeyCode=0x0'

Puppeteer Mouse Released

Puppet key released:
ID=402
KeyCode=32
ParamString='KEY_RELEASED,keyCode=32,keyText=Space,keyChar=' ',keyLocation=KEY_LOCATION_STANDARD,rawCode=0,primaryLevelUnicode=0,scancode=0,extendedKeyCode=0x0'

Puppet action performed.


On the second click, the puppet does wait until after it receives a keyReleased event before calling its ActionListener, which is what I had expected it would do on every such click-and-release with the mouse on the puppeteer.

Below is my code.

Can anyone help me understand why it behaves as it does, and not as I have outlined in my expectations?


 
Stevens Miller
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah, I think it has to do with the focus. If the puppet has received a keyPressed event and then loses the focus, it will call its ActionListener immediately.
 
Stevens Miller
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yup, that was it. Adding this to the Puppets constructor proves it:

Now the puppet never loses the focus as a result of the puppeteer being clicked, so it waits for the keyReleased event before calling its ActionListener.

Amazing how often just stating a problem in full gives one the fresh perspective needed to see how to solve it.
 
Bartender
Posts: 732
10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You might want to look at the Robot class.
 
Stevens Miller
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Fred Kleinschmidt wrote:You might want to look at the Robot class.


Hey, that's cool! Thanks for the pointer.
 
All of life is a contant education - Eleanor Roosevelt. Tiny ad:
We need your help - Coderanch server fundraiser
https://coderanch.com/t/782867/Coderanch-server-fundraiser
reply
    Bookmark Topic Watch Topic
  • New Topic