aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes Need some help with key bindings Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Need some help with key bindings" Watch "Need some help with key bindings" New topic
Author

Need some help with key bindings

Claudiu Bele
Greenhorn

Joined: Mar 07, 2013
Posts: 3
All the code bits that i see that involves key bindings are 100-ish lines of code that are hard to read when you don't get the idea of them.Also the Oracle files don't seem to help as much as i would've wanted.
The reason that i wanted to switch to key bindings ( from just Keylisteners with a switch for the keyCode) is that for example, when i press UP ARROW , my character goes up . But when i press for example J ( to shoot bulets to the left ), my character interrupts going up and freezes for a bit, afterwards starting when i press buttons again.
Can someone give a simple example for 2 keys actions mapping with key bindings ( or as many as you want as long as your message is understood) ? (for example keyCode 37 the action being x-=5 (left arrow ) and keyCode 39 ( right arrow )the action being x+=5 .Something simple.
Also if anyone has better suggestions on how to handle this ordeal, feel free to contact me on this thread or on my inbox.
If anyone is interested , this is the game i am currently working on and need help with : http://imgur.com/9kgl9OC
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2289
    
  49
Welcome to the Ranch.

The reason that i wanted to switch to key bindings ( from just Keylisteners with a switch for the keyCode) is that for example, when i press UP ARROW , my character goes up . But when i press for example J ( to shoot bulets to the left ), my character interrupts going up and freezes for a bit, afterwards starting when i press buttons again.

You can't solve that with key bindings. You can only generate events for 1 key at any one time so if you are holding down the up arrow key and then press the J key the arrow up key pressed event will stop being generated and the J key pressed event will be generated. If you want the character to keep moving up when you press other keys you need to keep moving up until you receive a key event from a key that tells the character to move in a different direction.
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2182
    
    7
Relying on repeat key event is generally not a good idea for the reasons given above. Also, the repeat rate of key events can be different on every computer. So you usually want to take control of of the repeat speed. This is typically done by starting a Timer when a key is pressed and then stopping the Timer when the key is released. This can be done with key bindings.

This approach works well on windows. When you hold a key down in windows it generates events like keyPressed, keyPressed, keyPressed.... keyReleased.

Unfortunately on a Mac I believe the order of events is keyPressed, keyRelease, keyPressed, keyReleased, keyPressed, keyReleased. So you end up effectively starting/stopping the Timer frequently.
Claudiu Bele
Greenhorn

Joined: Mar 07, 2013
Posts: 3
Thanks for the replies guys ! At least now i understand why it doesn't work . Can you care to give a very very short example on the implementations of key bindings? I always seem to find 100+ lines of codes in which key bindings are a part of but they are hard to read . Thanks a lot and have a great weekend
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2182
    
    7
Here is my example code that does everything I suggested. You can hold down multiple keys to get diagonal movement.



Note how easy it is to make any key an action key? Note how there is no if/else logic. This makes the code far easier to maintain and much more flexible.

Actually I was just looking at the code and you could make it even more flexible by passing in a KeyStroke, instead of a key code. Using this approach then you could use the modifier keys. For example the "left" key moves the image left and "Control+left", zooms the image left (ie. set the xDelta to be 10).

I'll let you add this change
Claudiu Bele
Greenhorn

Joined: Mar 07, 2013
Posts: 3
Thanks for the answer. I may come off as an idiot but it all got foggy for me ever since i started learning about methods that are being called automatically and we don't need to call them ( like Paint ). I kind of got the big picture of it but it would be great if you could guide me by answering this questions:

1. Basically the if statements tests and the code being ran if the test is true are all equivalent to the addAction method ( in a way ), right ?


2. What does the timer do, check every 'delay' miliseconds if we pressed anything? Why does it start again when we passed the test for pressing a button and why does it stop when you aren't pressing any?


3. I have problems understanding completely the functionality of this piece of code ( a huge composite question ):




What is the Action's name ? super(name) makes an action with the parameter being name and that is the one we use ? What is 'this' action in the actionMap? Does 'this' go into the actionPerformed below ?
Is component.getActionMap().put a way of specifically attributing actions for a component? Same like component.addActionListener(this) ?
Also those lines:


I get the first 2 lines (from a syntax point of view ) but why and where are we using it ( i am referring now to releasedKeyStroke )? Follow up question to that, when are we ( if ever) using the input from inputMap.put(releasedKeyStroke, getValue(Action.NAME)); ? We use it to trigger going into the ActionPerformed a last time when we release a button to eventually listen to keys ?



5. When do we call KeyBoardNavigation's ActionPerformed ? Or what is the line of code that triggers it to it. Whenever a NavigationAction is triggered, also a KeyBoardNavigation action is triggered?



If you could answer those questions it would be great and it would help me a lot. This reply helped me a lot aswell because as i was writing i started to understand the whole concept better.
Thanks a ton and have a great weekend !
Rob Camick
Ranch Hand

Joined: Jun 13, 2009
Posts: 2182
    
    7
Lots of questions. I think you need to play with the basics before trying to fully understand the code I gave you.

Start by reading the Swing tutorial on How to Use Actions. Basically the actionPerformed() method of the Action is invoked when a certain event occurs. In the tutorial they use a buttons and menus to demonstrate the use of an Action. So when you click on a button, the Action is invoked.

The next step is for you to modify the demo program to add Key Bindings to one of the Actions. So start by making the text area editable. Then try adding the LeftAction to the left arrow key. Read the swing tutorial on Key Bindings

Once you get this working then maybe you will understand my code better. A brief summary. The KeyboardNavigation class is responsible for moving the image deltaX/Y. The NavigationAction class is responsible for changing the deltaX/Y of the KeyboardNavigation class and for starting the Timer of the KeyboardNavigation class. When the Timer fires the actionPerformed method of the KeyboardNaviagation class is invoked to move the image. The Swing tutorial also has a section on "How to Use Timers". I can understand your confusion with the example since it reallly uses 3 different concepts. However all these concepts are basic to Swing programming so its worth the effort to understand them individually first, then hopefully the example makes more sense.

The Timer is used so you have full control over when the image is moved. In the demo code try changing 24 to 500 when the KeyboardNavigation class is created and notice the difference. The NavigationAction could be changed to directly tell the KeyboardNavigation class to move the image every time a keyPressed event is recieved, but then you are at the mercy of the keyboard repeate rate which can be different for every user.

Hope that helps.

Edit:

I replaced my code with a new version. Basically I moved all the Timer code out of the NavigationAction class. So now the NavigationAction just notifies the KeyboardNavigation class when a key has been pressed/released. The KeyboardNavigation then manages the Timer and the moving of the image. Hope this is simpler to understand.
 
Consider Paul's rocket mass heater.
 
subject: Need some help with key bindings