I have a JFrame, which contains a JPanel and a JTextPane separated by a
JSplitPane.
The outer JFrame implements KeyListener, and whenever that JFrame or any of the
components within it have focus, I want the JFrame's Keylistener to process the
keystrokes.
When I add the JTextPane however, it gains focus. How can I make it so that the
outer JFrame is the one that gets to process key events? I can call
requestFocus() to make that happen, but as soon as someone clicks inside the text
frame, the outer frame stops listening to key events.
Eventually I want to be able to open new windows, and have them handle their own
events, so I cant force the JFrame to keep taking focus when it loses it.
I know there must be an elegant solution to this, but I cant seem to find one.
Thanks for any help.
Thomas Hawtin - 24 Jul 2005 02:16 GMT
> The outer JFrame implements KeyListener, and whenever that JFrame or any of the
> components within it have focus, I want the JFrame's Keylistener to process the
> keystrokes.
When a listener is applied to a component, that prevents the event
getting rippled up through its ancestors. Expecting events to ripple up
isn't a good idea. Adding event listeners may prevent any existing
listeners on ancestors from functioning (as it happens, I've just spent
the last couple of hours fixing such a bug in the Metal PL&F).
It so happens that for key events there is so special machinery.
JComponent input and action maps are what you want. JComponent has
better documentation under the obsolete (but easier to use and not
deprecated) registerKeyboardAction than getInputMap/getActionMap.
Essentially you want something along the lines of (off the top of my head):
component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(
'N', InputEvent.CTRL_DOWN_MASK
), "mycommand"
);
component.getActionMap(true).put(
"mycommand", new AbstractAction() {
public void actionPerformed(ActionEvent evt) {
...
}
}
);
or the obsolete way
component.registerKeyboardAction(
new ActionListener() {
public void actionPerformed(ActionEvent evt) {
...
}
},
KeyStroke.getKeyStroke(
'N', InputEvent.CTRL_DOWN_MASK
),
JComponent.WHEN_IN_FOCUSED_WINDOW
);
Tom Hawtin

Signature
Unemployed English Java programmer