繁体   English   中英

Java KeyListener切换JPanel后未响应

[英]Java KeyListener not responding after switching JPanels

当我在JPanels之间切换时,KeyListener没有响应(由于未获得焦点)而出现问题。

我已经用过Google,并且知道要解决此问题,我需要使用KeyBindings,但是我不喜欢KeyBindings。 所以我想知道,还有其他方法吗?

这是具有不响应的KeyListener的JPanel的初始化代码:

    public void init()
{
    setFocusable(true);
    requestFocusInWindow();
    requestFocus();
    addMouseListener(new MouseInput());
    addMouseMotionListener(new MouseInput());
    addMouseWheelListener(new MouseInput());
    addKeyListener(new KeyInput(p));

    t = new Timer(10, this);
    t.start();
}

如果需要,请随时请求更多代码示例!

hacky解决方案是在JPanel上调用requestFocusInWindow()以确保它具有KeyListener / KeyAdapter焦点,只有在添加Componnet之后才应调用它(尽管要确保我的组件具有焦点,所以刷新JFrame之后我会调用它)通过revalidate()repaint() ),例如:

public class MyUI {

    //will switch to the gamepanel by removing all components from the frame and adding GamePanel
    public void switchToGamePanel() {
        frame.getContentPane().removeAll();

        GamePanel gp = new GamePanel();//keylistener/keyadapter was added to Jpanel here

        frame.add(gp);//add component. we could call requestFocusInWindow() after this but to be 98%  sure it works lets call after refreshing JFrame

        //refresh JFrame
        frame.pack();
        frame.revalidate();
        frame.repaint();

        gp.requestFocusInWindow();
    }

}
class GamePanel extends JPanel { 

      public GamePanel() {
          //initiate Jpanel and Keylistener/adapter
      }

}

但是,您应该使用Swing KeyBinding (+1到@Reimeus注释)。

在这里阅读以熟悉它们:

现在,您已经阅读了让我们展示另一个示例来帮助阐明的内容(尽管Oracle做得很好)

如果我们想将KeyBinding添加到某个JComponentEsc的 JButton ,则可以执行以下操作:

void addKeyBinding(JComponent jc) {
        jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false), "esc pressed");
        jc.getActionMap().put("esc pressed", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                System.out.println("Esc pressed");
            }
        });

        jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, true), "esc released");
        jc.getActionMap().put("esc released", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                System.out.println("Esc released");
            }
        });
}

上面的方法将被称为:

JButton b=..;//create an instance of component which is swing

addKeyBinding(b);//add keybinding to the component

请注意:

1)您不需要两个KeyBindings ,我只是演示了如何获取不同的键状态并使用Keybindings适当地操作。

2)此方法将添加一个Keybinding ,只要按下Esc并且该组件位于具有焦点的窗口中,就可以激活它,您可以通过指定另一个InputMap来更改它,即:

jc.getInputMap(JComponent.WHEN_FOCUSED).put(..);//will only activated when component has focus

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM