[ACCEPTED]-Unresponsive KeyListener for JFrame-keylistener
If you don't want to register a listener 1 on every component,
you could add your own KeyEventDispatcher
to the KeyboardFocusManager
:
public class MyFrame extends JFrame {
private class MyDispatcher implements KeyEventDispatcher {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
System.out.println("tester");
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
System.out.println("2test2");
} else if (e.getID() == KeyEvent.KEY_TYPED) {
System.out.println("3test3");
}
return false;
}
}
public MyFrame() {
add(new JTextField());
System.out.println("test");
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new MyDispatcher());
}
public static void main(String[] args) {
MyFrame f = new MyFrame();
f.pack();
f.setVisible(true);
}
}
You must add your keyListener to every component 8 that you need. Only the component with the 7 focus will send these events. For instance, if 6 you have only one TextBox in your JFrame, that 5 TextBox has the focus. So you must add a 4 KeyListener to this component as well.
The 3 process is the same:
myComponent.addKeyListener(new KeyListener ...);
Note: Some components 2 aren't focusable like JLabel.
For setting 1 them to focusable you need to:
myComponent.setFocusable(true);
InputMaps and ActionMaps were designed to 14 capture the key events for the component, it 13 and all of its sub-components, or the entire 12 window. This is controlled through the 11 parameter in JComponent.getInputMap(). See 10 How to Use Key Bindings for documentation.
The beauty of this design 9 is that one can pick and choose which key 8 strokes are important to monitor and have 7 different actions fired based on those key 6 strokes.
This code will call dispose() on 5 a JFrame when the escape key is hit anywhere 4 in the window. JFrame doesn't derive from 3 JComponent so you have to use another component 2 in the JFrame to create the key binding. The 1 content pane might be such a component.
InputMap inputMap;
ActionMap actionMap;
AbstractAction action;
JComponent component;
inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
actionMap = component.getActionMap();
action = new AbstractAction()
{
@Override
public void actionPerformed(ActionEvent e)
{
dispose();
}
};
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dispose");
actionMap.put("dispose", action);
I got the same problem until i read that 5 the real problem is about FOCUS the your 4 JFrame has already added Listeners but tour 3 frame is never on Focus because you got 2 a lot of components inside your JFrame that 1 also are focusable so try:
JFrame.setFocusable(true);
Good Luck
KeyListener
is low level and applies only to a single 8 component. Despite attempts to make it more 7 usable JFrame
creates a number of component components, the 6 most obvious being the content pane. JComboBox
UI 5 is also often implemented in a similar manner.
It's 4 worth noting the mouse events work in a 3 strange way slightly different to key events.
For 2 details on what you should do, see my answer 1 on Application wide keyboard shortcut - Java Swing.
Deion (and anyone else asking a similar 4 question), you could use Peter's code above 3 but instead of printing to standard output, you 2 test for the key code PRESSED, RELEASED, or 1 TYPED.
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
} else if (e.getID() == KeyEvent.KEY_TYPED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
}
return false;
}
in order to capture key events of ALL text 3 fields in a JFrame, one can employ a key event 2 post processor. Here is a working example, after 1 you add the obvious includes.
public class KeyListenerF1Demo extends JFrame implements KeyEventPostProcessor {
public static final long serialVersionUID = 1L;
public KeyListenerF1Demo() {
setTitle(getClass().getName());
// Define two labels and two text fields all in a row.
setLayout(new FlowLayout());
JLabel label1 = new JLabel("Text1");
label1.setName("Label1");
add(label1);
JTextField text1 = new JTextField(10);
text1.setName("Text1");
add(text1);
JLabel label2 = new JLabel("Text2");
label2.setName("Label2");
add(label2);
JTextField text2 = new JTextField(10);
text2.setName("Text2");
add(text2);
// Register a key event post processor.
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addKeyEventPostProcessor(this);
}
public static void main(String[] args) {
JFrame f = new KeyListenerF1Demo();
f.setName("MyFrame");
f.pack();
f.setVisible(true);
}
@Override
public boolean postProcessKeyEvent(KeyEvent ke) {
// Check for function key F1 pressed.
if (ke.getID() == KeyEvent.KEY_PRESSED
&& ke.getKeyCode() == KeyEvent.VK_F1) {
// Get top level ancestor of focused element.
Component c = ke.getComponent();
while (null != c.getParent())
c = c.getParent();
// Output some help.
System.out.println("Help for " + c.getName() + "."
+ ke.getComponent().getName());
// Tell keyboard focus manager that event has been fully handled.
return true;
}
// Let keyboard focus manager handle the event further.
return false;
}
}
This should help
yourJFrame.setFocusable(true);
yourJFrame.addKeyListener(new java.awt.event.KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
System.out.println("you typed a key");
}
@Override
public void keyPressed(KeyEvent e) {
System.out.println("you pressed a key");
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("you released a key");
}
});
0
Hmm.. what class is your constructor for? Probably 6 some class extending JFrame? The window 5 focus should be at the window, of course 4 but I don't think that's the problem.
I expanded 3 your code, tried to run it and it worked 2 - the key presses resulted as print output. (run 1 with Ubuntu through Eclipse):
public class MyFrame extends JFrame {
public MyFrame() {
System.out.println("test");
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
System.out.println("tester");
}
public void keyReleased(KeyEvent e) {
System.out.println("2test2");
}
public void keyTyped(KeyEvent e) {
System.out.println("3test3");
}
});
}
public static void main(String[] args) {
MyFrame f = new MyFrame();
f.pack();
f.setVisible(true);
}
}
I have been having the same problem. I followed 9 Bruno's advice to you and found that adding 8 a KeyListener just to the "first" button 7 in the JFrame (ie, on the top left) did 6 the trick. But I agree with you it is kind 5 of an unsettling solution. So I fiddled 4 around and discovered a neater way to fix 3 it. Just add the line
myChildOfJFrame.requestFocusInWindow();
to your main method, after 2 you've created your instance of your subclass 1 of JFrame and set it visible.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.