一旦窗口失去焦点并重新获得焦点,如何修复KeyAdapter不再起作用

时间:2019-06-12 10:47:14

标签: java swing awt keypress

我正在用Java为学校项目制作一个简单的游戏,并且我在结合使用JFrame和扩展KeyAdapter的类来监听输入。但是,一旦我将焦点更改到另一个窗口(例如Snipping Tool),然后又回到了游戏窗口,KeyAdapter似乎不再能够识别按键。

我曾经尝试在编译后运行此代码,而在Eclipse中,两次都遇到相同的问题。我正在运行Windows 10(如果有所作为),并使用Eclipse 4.11.0版和可用的最新Java软件包。我过去从未使用过JFrames等,并且发现的内容很少以初学者友好的方式描述它们的使用。

import java.awt.*;
import javax.swing.*;

public class GWindow extends Canvas {
    public GWindow() {
        frame = new JFrame("Dungeon120");
        frame.addKeyListener(new GInputs());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(1000, 650);
        frame.add(this);
        frame.pack();
        frame.setVisible(true);
        this.setBackground(Color.black);
    }
}
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class GInputs extends KeyAdapter {
    public void keyPressed(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.VK_SPACE) {
            Main.MainGame.TurnQueue.nextGUnit();
            System.out.println("SPACE KEY PRESSED");
        }
    }
}

首次运行该程序时,它将按预期运行,同时按空格键打印“ SPACE KEY PRESSED”并执行nextGUnit()方法。但是,一旦程序丢失并重新获得焦点,任何按键都不会发生。

1 个答案:

答案 0 :(得分:0)

您应该避免将AWT组件与Swing组件(在您的情况下是Canvas与JFrame)混合使用。 根据我过去的经验,将KeyListener / KeyAdapter与JFrame和JPanel一起使用是行不通的。相反,要侦听输入,可以放置屏幕外的JTextField来侦听键。

import java.awt.*;
import javax.swing.*;

public class GWindow extends Canvas {
    public GWindow() {
        frame = new JFrame("Dungeon120");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(1000, 650);
        frame.add(this);
        JTextField listener = new JTextField();
        listener.addKeyListener(new GInputs());
        //add it to the frame using any layout of your choice
        this.add(listener);
        frame.pack();
        frame.setVisible(true);
        //set focus to JTextField
        listener.requestFocusInWindow();
        this.setBackground(Color.black);
    }
}

如果您不熟悉布局,请参见以下代码摘录:

import javax.swing.*;
import java.awt.*;

public class GWindow extends Canvas {
    public GWindow() {
        JFrame frame = new JFrame("Dungeon120");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //set layout to SpringLayout
        SpringLayout layout = new SpringLayout();
        frame.setLayout(new SpringLayout());
        this.setSize(1000, 650);
        frame.add(this);
        JTextField listener = new JTextField();
        listener.addKeyListener(new GInputs());
        //position it offscreen
        layout.putConstraint(SpringLayout.SOUTH, listener, 0, SpringLayout.NORTH, frame.getContentPane());
        frame.add(listener);
        frame.pack();
        frame.setVisible(true);
        //set focus to JTextField
        listener.requestFocusInWindow();
        this.setBackground(Color.black);
    }
}

此外,尝试将JFrame置于GWindow构造函数之外。