Java - JFrame全屏keylisteners不起作用

时间:2014-06-11 08:11:19

标签: java swing

我正在尝试通过玩一些不同的东西自己学习Java和游戏编程。但是现在我遇到了这个问题,当我的java应用程序通过GraphicsDevice全屏显示时,KeyListeners无效。当我按下键盘上的按钮时,它就像没有注册任何东西。当应用程序不是全屏时,一切都按预期工作。

我正在使用Mac。

代码有点乱,但它应该有点容易导航等。

Game.class

public class Game extends Canvas implements Runnable {
    private static final long serialVersionUID = 1L;

    // Render Vars
    public static final int WIDTH = 1280;
    public static final int HEIGHT = 800; //WIDTH / 16 * 
    public static final int SCALE = 1;
    public final static String TITLE = "Test Game - inDev 1.0.0";
    public static boolean fullscreen = false;

    public static JFrame window = new JFrame(TITLE);

    public static Font defaultFont = new Font("Dialog", Font.PLAIN, 12);
    public static Color defaultColor = Color.gray;

    // Thread Vars
    public static boolean running = false;
    private static Thread thread;
    private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

    // Mechanic Vars
    public static boolean mouseDown;
    public static int mouseX;
    public static int mouseY;

    // Game Vars
    public static GameState gameState = new Play();
    public static boolean keyPressed;

    public static Game game = new Game();

    public static void main(String arghs[]) {
        game.setSize(new Dimension(WIDTH, HEIGHT));
        game.setPreferredSize(new Dimension(WIDTH, HEIGHT));

        fullscreen = true;

        window.add(game);
        window.setUndecorated(true);
        window.pack();
        window.setLocationRelativeTo(null);
        window.setResizable(false);
        window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        window.setVisible(true);

        // HERE I GO FULLSCREEN
        GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(window);

        game.addKeyListener(new KeyEventListener());
        game.addMouseListener(new MouseEventListener());

        game.start();
    }

    public void run() {

        init();

        long lastTime = System.nanoTime();
        final double numTicks = 100.0;
        double ns = 1000000000 / numTicks;
        double delta = 0;
        int updates = 0;
        int frames  = 0;
        long timer = System.currentTimeMillis();

        while (running) {
            long now = System.nanoTime();
            delta += (now - lastTime) / ns;
            lastTime = now;
            if (delta >= 1) {
                update();
                updates++;
                delta--;
            }
            render();
            frames++;

            if (System.currentTimeMillis() - timer > 1000) {
                timer += 1000;
                System.out.println(updates + " Ticks, FPS: " + frames);
                updates = 0;
                frames = 0;
            }
        }
        stop();
    }

    private synchronized void start() {
        if (running) {
            return;
        }
        running = true;

        thread = new Thread(this);
        thread.setName("My Game");
        thread.start();
    }
    public synchronized static void stop() {
        if (!running) {
            return;
        }
        running = false;

        thread = null;
        System.exit(1);
    }

    private void init() {
        gameState.init();
    }

    private void update() {
        gameState.update();
    }

    private void render() {
        BufferStrategy bs = this.getBufferStrategy();
        if (bs == null) {
            createBufferStrategy(3);
            return;
        }
        Graphics g = bs.getDrawGraphics();

        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

        g.setColor(defaultColor);
        g.drawImage(image, 0, 0, getWidth(), getHeight(), this);

        // Draw Content
        gameState.render(g);

        // Draw to Screen;
        g.dispose();
        bs.show();
    }

    public static void setGameState(GameState state) {
        gameState = state;
        gameState.init();
    }
}

KeyEventListener.class

public class KeyEventListener extends KeyAdapter {
    public void keyPressed(KeyEvent e) {
        if (!Game.keyPressed) {
            Game.gameState.keyPressed(e);
        }
        Game.keyPressed = true;
    }
    public void keyReleased(KeyEvent e) {
        Game.gameState.keyReleased(e);
        Game.keyPressed = false;
    }
}

MouseEventListener.class(仅用于记录鼠标位置)

public class MouseEventListener extends MouseAdapter {

    public void mousePressed(MouseEvent e) {
        Game.mouseDown = true;
    }
    public void mouseReleased(MouseEvent e) {
        Game.mouseDown = false;
    }
    public void mouseMoved(MouseEvent e) {
        Game.mouseX = e.getX();
        Game.mouseY = e.getY();
    }
    public void mouseDragged(MouseEvent e) {
        Game.mouseX = e.getX();
        Game.mouseY = e.getY();
    }
}

GameState.class

public abstract class GameState {

    public abstract void init();
    public abstract void update();
    public abstract void render(Graphics g);
    public void keyPressed(KeyEvent e) {

    }
    public void keyReleased(KeyEvent e) {

    }

}

我的Play.class是当前的gameState

public class Play extends GameState {

    public static int key;

    public void init() {

    }

    public void update() {

    }   

    public void render(Graphics g) {
        g.drawString("Key: " + key, 100, 100);
    }

    public void keyPressed(KeyEvent e) {
        key = e.getKeyCode();
    }

    public void keyReleased(KeyEvent e) {

    }

}

2 个答案:

答案 0 :(得分:2)

KeyListener仅在注册组件时才会响应关键事件,并且具有焦点。

将窗口设置为全屏后,请尝试添加...

game.requestFocusInWindow();

您可能还需要使用game.setFocusable(true)

如果不是因为您使用的是Canvas,我建议您使用key bindings API来解决所有这些焦点问题

<强>更新

我补充说......

window.addWindowFocusListener(new WindowAdapter() {

    @Override
    public void windowGainedFocus(WindowEvent e) {
        System.out.println("gainedFocus");
        if (!game.requestFocusInWindow()) {
            System.out.println("Could not request focus");
        }
    }

});

window可见之后但在全屏显示之前

<强>更新

哦,你会爱上这个......

基于这个问题:FullScreen Swing Components Fail to Receive Keyboard Input on Java 7 on Mac OS X Mountain Lion

在将窗口设置为全屏模式后,我添加了setVisible(false)后跟setVisible(true),它似乎修复了它...

GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(window);
window.setVisible(false);
window.setVisible(true);

使用Java 7验证在Mac上运行

答案 1 :(得分:0)

试试这个:      game.addKeyListener(本);