从另一个JFrame遍历时,Key Listener在JFrame中不起作用

Viv*_*vek 1 java swing keylistener

我有2节课.

一个扩展canvas和inside创建一个jframe并将画布添加到该jframe并添加另一个keyadapter类来接收键事件.我还有测试代码的主要功能.从main运行时,表单将显示并接收关键事件.

现在我创建了另一个扩展jframe的类,并实现了keylistener来接收这种形式的事件.

一旦在第二类中完成功能,我想关闭第二个表单并显示第一个表单.当从第二个类中的键事件函数显示它时,第一个类键侦听器不起作用.

请稍微瞥一眼我的代码并告诉我如何纠正我的问题.感谢您的时间和宝贵的建议.

1级

public class Test extends Canvas {

private JFrame container;

public Test() {

    container = new JFrame("Space Invaders");
    JPanel panel = (JPanel) container.getContentPane();
    panel.setPreferredSize(new Dimension(screenSize.width, screenSize.height));
    panel.setLayout(null);
    setBounds(0, 0, screenSize.width, screenSize.height);
    panel.add(this);
    container.pack();
    container.setResizable(false);
    container.setVisible(true);

    try {

        addKeyListener(new KeyInputHandler(this));
    } catch (Exception e) {
        e.printStackTrace();
    }
    requestFocus();
}

private class KeyInputHandler extends KeyAdapter {

public void keyPressed(KeyEvent e) {
    //Some Action
}
public void keyReleased(KeyEvent e) {
    //Some Action
}
public void keyTyped(KeyEvent e) {
    //Some Action
}
}

public static void main(String args[]){
    //Running this canvas here works perfectly with all added keylisteners
}
}
Run Code Online (Sandbox Code Playgroud)

2级

public class Sample extends JFrame implements KeyListener {

public Sample() {
    init();
    this.setSize(100, 100);
    this.setVisible(true);
    Sample.this.dispose();
            // Created a window here and doing some operation and finally redirecting
            // to the previous test window. Even now the test window works perfectly
            // with all keylisteners
    new Test();
}

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

}

private void init() {
    addKeyListener(this);
}

@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void keyPressed(KeyEvent e) {
    removeKeyListener(this);
    Sample.this.dispose();
            // But when calling the previous Test window here, the window 
            // gets displayed but the keylistener is not added to the 
            // window. No keys are detected in test window.
    new Test();
}

@Override
public void keyReleased(KeyEvent e) {

}
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*amp 5

简单的不使用KeyListener/ KeyAdapter用于AWT组件,并且在与Swing一起使用时具有已知的焦点问题.

通过确保您的组件可以通过setFocusable(true)而不是requestFocusInWindow()在添加/可见组件后进行调用来解决问题.

而是使用KeyBindings进行Swing.

比如说现在我们想听听D压力和释放:

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

    jc.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, true), "D released");
    jc.getActionMap().put("D released", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            System.out.println("D released");
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

我们将此方法称为:

JPanel ourPanel=new JPanel();

...

addKeyBindings(ourPanel);//adds keybindings to the panel
Run Code Online (Sandbox Code Playgroud)

关于代码的其他建议

  • 始终Event Dispatch Thread通过SwingUtilities.invokeLater(Runnable r)块创建和操作Swing组件

  • 不要JFrame不必要地扩展课程

  • 不要在类上实现接口,除非该类将用于此目的,或者其他类需要访问接口方法.

  • 正如@AndrewThompson所提到的,不要使用多个JFrames,要么交换其余的JDialog,要么使用CardLayout.请看这里的例子.

  • 答案,副本***&***替代(`CardLayout`).帽子戏法!很顺利.:) (2认同)