1

我在错误的地方(GameDev)发布了这个并且没有得到任何回应。所以我在这里再次发布。

我正在制作一个小程序游戏,它正在渲染,游戏循环正在运行,动画正在更新,但键盘输入不起作用。这是一个SSCCE。

public class Game extends JApplet implements Runnable {

    public void init(){
        // Initialize the game when called by browser
        setFocusable(true);
        requestFocus();
        requestFocusInWindow();  // Always returning false
        GInput.install(this);    // Install the input manager for this class
        new Thread(this).start();
    }

    public void run(){
        startGameLoop();
    }

}

这是 GInput 类。

public class GInput implements KeyListener {

    public static void install(Component c){
        new GInput(c);
    }

    public GInput(Component c){
        c.addKeyListener(this);
    }

    public void keyPressed(KeyEvent e){
        System.out.println("A key has been pressed");
    }

    ......

}

这是我的 GInput 类。当作为小程序运行时,它不起作用,当我将 Game 类添加到框架时,它可以正常工作。

谢谢

现在解决了。查看我的解决方案

4

3 回答 3

4

一种可能的解决方案是使用 JApplet 的 contentPane,将焦点设置在它而不是 JApplet 本身上。但我的偏好是改用键绑定。您可能需要使用 Swing Timer 才能工作:

我的SSCCE:

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;

import javax.swing.*;

@SuppressWarnings("serial")
public class AppletKeyListen extends JApplet {
   @Override
   public void init() {
      try {
         SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
               setFocusable(true);

               int timerDelay = 100;
               Timer myTimer = new Timer(timerDelay , new ActionListener() {

                  @Override
                  public void actionPerformed(ActionEvent arg0) {
                     boolean focusObtained = requestFocusInWindow();
                     System.out.println("focusObtained for JApplet: " + focusObtained);

                     Container contentPane = getContentPane();
                     contentPane.setFocusable(true);

                     focusObtained = contentPane.requestFocusInWindow();
                     System.out.println("focusObtained for contentPane: " + focusObtained);


                  }
               });
               myTimer.setRepeats(false);
               myTimer.start();
//               boolean focusObtained = requestFocusInWindow();
//               System.out.println("focusObtained: " + focusObtained);
//               
//               Container contentPane = getContentPane();
//               contentPane.setFocusable(true);
//               
//               focusObtained = contentPane.requestFocusInWindow();
//               System.out.println("focusObtained: " + focusObtained);

            }
         });
      } catch (InvocationTargetException | InterruptedException e) {
         e.printStackTrace();
      }
   }
}
于 2012-08-25T13:29:23.597 回答
1

如果您在浏览器中运行,您可能需要单击小程序以使其获得焦点。出于安全原因,大多数浏览器不会让小程序在用户不点击的情况下直接获取键盘焦点。

因此,我将添加一个鼠标侦听器,而不是直接在以下位置进行焦点抓取init()

addMouseListener(new MouseAdapter() {
   public void onMousePress(MouseEvent e) {
      requestFocus();
   }
});
于 2012-08-25T13:21:24.343 回答
0

现在我有两个选择,

  • 使用 JWS
  • 不要做小程序模式

现在我试图创建一个名为GApplet. 它将游戏加载到一个新的 JFrame 中,该 JFrame 可以从 applet 运行。现在我也可以从网络访问全屏模式。这是该课程的链接。

GApplet班级_

现在它就像 webstart 一样工作,实际上是一个小程序。

于 2012-08-27T01:45:17.930 回答