The professional, friendly Java community. 21,500 members and growing!

The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.

KeyListeners: Automatic Focus?

There are three grids of buttons on my JFrame. Each of those grids has its own JPanel. Right now, the buttons are stored in ArrayLists and each one gets an actionListener and keyListener assigned to it through a for loop.

My problem is that the keys don't register until you click one of the buttons. How can I make the keys have the focus for the entire JFrame regardless of which grid they are in?

If you would like to see a certain portion of code, just specify which part and I will post it.

The buttons are located in array lists. Their actionPerformed methods use getSource to find the source, find the reference in the ArrayList, get that object as a button, and get the text to identify the button for the rest of the program.

How would I add KeyBindings to a situation like this with the ArrayList approach?

Re: KeyListeners: Automatic Focus?

A suggestion on your code. When I see regular code like you have I think array. Put the text for the buttons in an array in the order you want to index them:
String[] btnTexts = new String[] {"7", "8", "9", "4", ...".", "-"};
Then get the desired text:
b.setText(btnTexts[i]); // get text for this button

How would I add KeyBindings to a situation like this with the ArrayList approach?

The key bindings would replace the addActionListener method call. The actionPerformed() method calls would be the same.

Re: KeyListeners: Automatic Focus?

Originally Posted by Norm

A suggestion on your code. When I see regular code like you have I think array. Put the text for the buttons in an array in the order you want to index them:
String[] btnTexts = new String[] {"7", "8", "9", "4", ...".", "-"};
Then get the desired text:
b.setText(btnTexts[i]); // get text for this button

The key bindings would replace the addActionListener method call. The actionPerformed() method calls would be the same.

Erm.... Seeing as the amount of code that is in this program involving the ArrayLists I would rather not go back and completely change that unless you REALLY think there is no other way.

Like I said, how do I add KeyBindings to a situation with the ArrayList approach?

Oh and just out of curiosity, what exactly is "regular code"?

EDIT: And by how I mean I don't understand ActionMaps. If you could help with that, I would appreciate it. Thanks!

I am having trouble adding your example of KeyBindings to the program. If I want the same thing to happen with that key binding as when the buttons are pressed, can I just do this?

[CODE]
addKeyAccelerator(mainFrame, new ListenForMain(), "0",'0',0)//Is there a way to bind all of the NumPad numbers or something? I'm lazy...publicvoid addKeyAccelerator(JComponent c,AbstractAction action, String keyName, int keyCode, int mask){//Rest of the method code...[/CODE]

If I make the ListenForMain method extend AbstractAction will it work with KeyBindings?

And what do I need to add to the actionPerformed method in ListenForMain?

Does the addKeyAccelerator method need to have something like this?

[CODE]//this is the rest of the method code...KeyStroke ks =KeyStroke.getKeyStroke(keyCode,mask);//Here I want the buttons to respond to the key stroke. If this is wrong and it needs to use the same "c" reference or the "JButton" class name, let me know.
c.getInputMap(b.WHEN_IN_FOCUSED_WINDOW).put(ks,actionName);
c.getActionMap().put(actionName, action);[/CODE]

Re: KeyListeners: Automatic Focus?

I am having trouble adding your example of KeyBindings to the program.

What I posted was for a quick and easy demo. I was hoping that you could copy and paste it as is.
Then test it by executing your code and pressing Ctrl-Z or the Y and have a message printed.
Did you try that? Did it print out?

can I just do this?

Try it and see what happens.

If I make the ListenForMain method extend AbstractAction will it work with KeyBindings?

Re: KeyListeners: Automatic Focus?

Originally Posted by Norm

What I posted was for a quick and easy demo. I was hoping that you could copy and paste it as is.
Then test it by executing your code and pressing Ctrl-Z or the Y and have a message printed.
Did you try that? Did it print out?

Try it and see what happens.

Try it and see.

No doesn't work. I'm pretty sure I need something in the actionPerformed method to process the key event. But I don't know what.

And do you mean copy it into my current program as is? There is no "player1" reference existing inside of it...

Re: KeyListeners: Automatic Focus?

Originally Posted by Norm

What I posted was for a quick and easy demo. I was hoping that you could copy and paste it as is.
Then test it by executing your code and pressing Ctrl-Z or the Y and have a message printed.
Did you try that? Did it print out?

Try it and see what happens.

Try it and see.

Do you mean copy it into my program? Some of those variables don't exist in it... I'm not sure now that would work.

And I have tried those things. They don't work. I'm pretty sure I need something added to those actionPerformed methods in order for them to recognize the KeyStrokes.

Re: KeyListeners: Automatic Focus?

If you use key bindings you may be able to bind the key events to the container that all the components are in.

how do I integrate the key binding into the buttons' action performed method?

The key binding's actionPerformed method could call the actionPerformed method used by the buttons.
Or the key binding's AbstractAction could be the same actionPerformed method as the one the buttons use.

Can you make a small simple program that compiles and executes with a few buttons in a panel to demonstrate this problem?

Re: KeyListeners: Automatic Focus?

The program you wrote throws this exception at runtime (it's an Array Index out of bounds):

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException:
-1
at java.util.ArrayList.get(ArrayList.java:324)
at KeyTime$ListenForButtons.actionPerformed(KeyTime.java:64)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1639)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2851)
at javax.swing.KeyboardManager.fireBinding(KeyboardManager.java:267)
at javax.swing.KeyboardManager.fireKeyboardAction(KeyboardManager.java:2
16)
at javax.swing.JComponent.processKeyBindingsForAllComponents(JComponent.
java:2928)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2920)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2814)
at java.awt.Component.processEvent(Component.java:6065)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4651)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.ja
va:1850)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboard
FocusManager.java:712)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeybo
ardFocusManager.java:990)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeybo
ardFocusManager.java:855)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFoc
usManager.java:676)
at java.awt.Component.dispatchEventImpl(Component.java:4523)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessCo
ntrolContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessCo
ntrolContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:616)
at java.awt.EventQueue$2.run(EventQueue.java:614)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessCo
ntrolContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThre
ad.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.
java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
ad.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

What did you do? That didn't happen in my version...

And to answer your question, the program was supposed to activate the "Click Me!" button when 0 is pressed. Click Me! and Me too! display different messages.

Re: KeyListeners: Automatic Focus?

Ok. There were no comments in the code, so all I could do was have the key press go to the action listener. I didn't know what to do then. The listener needs to recognize how it was called (button click or key press) and react accordingly. Right now it assumes that it is ONLY called by button press. It doesn't know what to do when called with the key press.

Re: KeyListeners: Automatic Focus?

Originally Posted by Norm

Ok. There were no comments in the code, so all I could do was have the key press go to the action listener. I didn't know what to do then. The listener needs to recognize how it was called (button click or key press) and react accordingly. Right now it assumes that it is ONLY called by button press. It doesn't know what to do when called with the key press.

Would it maybe be easier to have separate key listeners in the main frame that respond by calling the doClick method on their respective buttons? That would fire the actionPerformed method right?

(Btw I'm not in any class I'm doing Java on my own so you aren't doing my homework by giving me answers )