[ACCEPTED]-Unresponsive KeyListener for JFrame-keylistener

Accepted answer
Score: 134

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);
    }
}
Score: 50

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);
Score: 16

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);
Score: 12

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

Score: 10

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.

Score: 9

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;
}
Score: 4

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;
    }
}
Score: 3

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

Score: 2

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);
    }
}
Score: 1

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