JFrame / JDesktop没有收到关键焦点

时间:2011-02-25 21:14:12

标签: java swing keylistener

我希望我的顶级JFrame以及JDesktopPane能够随时监听关键事件,无论当前聚焦/可见哪个组件。

目前,当启动此程序时,JFrame正在接收关键事件OK。但是,如果单击JinternalFrame,则事件不再到达JFrame。即使我在JInternalFrame外部点击(它应该是JDesktop组件),事件也不再像在开始时那样到达JFrame。为什么? 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
    }
}

3 个答案:

答案 0 :(得分:1)

将事件分派给具有焦点的组件。

为什么当焦点在内部帧上时,您希望帧接收事件?你的实际要求是什么?

如果要调用Action,那么最简单的方法是使用带有菜单项的菜单栏,然后​​可以为每个菜单项分配加速器,无论组件是否具有焦点,都可以调用Action。

答案 1 :(得分:0)

由于您希望JFrame能够监听所有关键事件而不管焦点是什么元素,因此将其作为关键侦听器添加到可以聚焦的所有元素上。像这样,

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

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

答案 2 :(得分:0)

您可能对java.awt.KeyboardFocusManager课感兴趣。我相信这是一个类,除其他外,它将KeyEvents调度到焦点组件。似乎可以使用方法addKeyEventDispatcher和addKeyEventPostProcessor分别在被发送到聚焦组件之前和之后获取KeyEvent。

我之前从未使用过这门课程,所以我不知道它是否符合我的预期。