views:

307

answers:

6

I have a swing frame that contains embedded panels that contain other panels, etc. Deep down, there is a button. I want the button to get focus so that pressing the "enter" key would generate an actionPerformed event.

However, if I do myButton.requestFocus() or myButton.requestFocusInWindow() the whole window gets the focus, but nothing seems to happen in terms of keyboard.

I'm obviously missing something about the focus subsystem.

Update2: I explicitly added a KeyListener in addition to the ActionListener and now it works. This is really weird, since I thought that actionListener includes both key and mouse actions.

A: 

Sounds like requestFocus() is failing at some level. Try testing to see if any of the parent jPanels or other components can request focus, and work your way up to find out where the problem lies.

sangretu
A: 

There is a way to programatically specify the functionality of the tab ( you know when you press tab and the next widget gets selected )

By default it follows the way the components were added.

Using this custom mechanism will let you select your nested button as the first which receive the actionperformed event.

Unfortunately I don't remember what the name for this "mechanism" is, but is something like traversal or focus traversal

OscarRyz
You're thinking of FocusTraversalPolicy: http://java.sun.com/j2se/1.5.0/docs/api/java/awt/FocusTraversalPolicy.html
Joe Attardi
Ahh that one! thanks.
OscarRyz
A: 

First, don't use requestFocus() use requestFocusInWindow(). requestFocus has platform specific issues, while requestFocusInWindow is more consistent.

Your actual problem; the component (or one of its parents) is probably not visible, or has been render non-focusable.

Kevin Montrose
A: 

I want the button to get focus so that pressing the "enter" key would generate an actionPerformed event.

The is LAF dependents. Enter works in Windows, but not the Metal LAF. Check out Enter Key and Button for more inforation.

The requestFocusInWindow() method only works if the Component is currently visible on the frame. There are no other tricks so we are just making random guesses about what your are doing wrong. If you need further help you need to post a SSCCE demonstrating the problem.

camickr
+1  A: 

For the enter key to work you probably want to set the default button rather than the keyboard focus:

button.getRootPane().setDefaultButton(button);

If you really want the keyboard focus then your problem might be related to when you call requestFocus. Sometimes if it is called before a component is fully visible it can be ignored. To fix that you can delay the requestFocus call until after other events have been processed:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        button.requestFocus();
    }
});
Russ Hayward
A: 

You can get the rootPane of the frame and update the inputMap and actionMap. See the below code.

InputMap map = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ok");

ActionMap actionMap = getRootPane().getActionMap();
actionMap.put("ok", enterAction);

Here enterAction is a AbstractAction object whose actionPerformed() will be called when user presses Enter.