Ted Mad
Ted Mad

Reputation: 75

KeyListener not triggering actions

The keyListener does not fire action though i registered the frame to the keyListener. In the other code, implementing the KeyListener interface, registering the JFrame and overriding the appropriate methods was all that was needed for the keyListener to work.

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Mains implements KeyListener {
    private static Point point = new Point();

    public Mains() {
        final JFrame frame = new JFrame();
        frame.setUndecorated(true);
        JButton button = new JButton("Close Me");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        frame.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                point.x = e.getX();
                point.y = e.getY();
            }
        });
        frame.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent e) {
                Point p = frame.getLocation();
                frame.setLocation(p.x + e.getX() - point.x, p.y + e.getY()
                        - point.y);
            }
        });

        frame.setSize(300, 300);
        frame.setLocation(200, 200);
        frame.setLayout(new BorderLayout());

        frame.getContentPane().add(button, BorderLayout.NORTH);
        frame.getContentPane().add(new JLabel("Drag Me", JLabel.CENTER),
                BorderLayout.CENTER);
        frame.setVisible(true);
        frame.addKeyListener(this);
    }

    public static void main(String[] args) {
        new Mains();
    }

    public void keyPressed(KeyEvent e) {
        System.out.println("pressed");
    }

    public void keyReleased(KeyEvent e) {
        System.out.println("released");
    }

    public void keyTyped(KeyEvent e) {

    }
}

Upvotes: 2

Views: 594

Answers (2)

Reimeus
Reimeus

Reputation: 159864

By default, JFrame window components are not focusable. Although you can call JFrame.setFocusable(true), it is far better to use Key Bindings.

KeyListener requires focus with components for the interaction with KeyEvents to work. In contrast, when using Key Bindings, you can map an Action to a KeyStroke even when a component doesn't have focus.

Upvotes: 4

MadProgrammer
MadProgrammer

Reputation: 347334

A KeyListerner is only capable of receiving key events if the component it is attached to can receive focus and has focus.

The problem with a JFrame is that it contains a JRootPane, which contains a content pane which occupies the entire surface of frame, which will prevent the frame from ever gaining focus, this, never be capable of receiving key events.

KeyListener is rarely the right API of choice, normally, it's better to use key bindings

You may also find How to use root panes of interest

Upvotes: 4

Related Questions