Saideira
Saideira

Reputation: 2404

JFrame/JDesktop not receving key focus

I would like my top level JFrame as well as the JDesktopPane to listen on key events at all times, no matter what component is currently focused/visible.

Currently, when this program is launched, the JFrame is receving the key events OK. However if a JinternalFrame is clicked, then events no longer reach the JFrame. Even if I do click outside the JInternalFrame, (which is supposed to be the JDesktop component), the events no longer reach the JFrame, like they did in the beginning. Why? Thx.

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class focus extends JFrame implements KeyListener {

    private focus() {
        JDesktopPane desktop = new JDesktopPane();
        setContentPane(desktop);

        addPane(this, "one");
        addPane(this, "two");
        addPane(this, "three");

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        setSize(400, 450);

        addKeyListener(this);
    }

    public static void main(String[] args) {
        focus t = new focus();
    }

    private void addPane(JFrame frame, String name) {
        JTextArea textArea = new JTextArea();
        textArea.setName(name);
        textArea.setEditable(false);

        addWindow(frame, textArea, name);
    }

    private JInternalFrame addWindow(JFrame frame, JComponent component,
            String name) {
        JScrollPane scrollablePane = new JScrollPane(component);

        JInternalFrame iframe = new JInternalFrame(name + " ", true, true,
                true, true);

        iframe.setSize(300, 300);
        iframe.setLocation((int) (100 * Math.random()),
                (int) (100 * Math.random()));
        iframe.setVisible(true);
        iframe.getContentPane().add(scrollablePane);
        frame.getContentPane().add(iframe);

        return iframe;
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub      
    }

    @Override
    public void keyPressed(KeyEvent e) {
        System.err.println(e.getKeyChar());
        // TODO Auto-generated method stub
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
    }
}

Upvotes: 1

Views: 1373

Answers (3)

AniDev
AniDev

Reputation: 1579

You might be interested in the java.awt.KeyboardFocusManager class. I believe it is the class that, among other things, dispatches KeyEvents to the focused component. It seems that the methods addKeyEventDispatcher and addKeyEventPostProcessor could be used to get KeyEvents before and after being sent to the focused component, respectively.

I have not ever used this class before, so I do not know if it does what I expect it to do.

Upvotes: 0

camickr
camickr

Reputation: 324108

Events are dispatched to the component that has focus.

Why would you want the frame to receive events when focus is on the internal frame? What is your actual requirement?

If you want to invoke an Action, then the easiest way is to use menu bars with menu items and then you can assign accelerators to each menu item to the Action can be invoked no matter with component has focus.

Upvotes: 1

Sathish
Sathish

Reputation: 4554

Since you would like your JFrame to be able to listen to all the key events no matter what element the focus is on, add that as the key listener to all the elements on which there can be focus. Like so,

textArea.setEditable(false);
**textArea.addKeyListener(this);**

and

iframe.getContentPane().add(scrollablePane);
**iframe.addKeyListener(this);**
frame.getContentPane().add(iframe);

Upvotes: 0

Related Questions