Java Applet游戏设计:键盘焦点

时间:2012-08-25 13:14:40

标签: java swing applet keyboard focus

我把它发布在错误的地方(GameDev)并且没有回复。所以我在这里再次发布它。

我正在制作applet游戏,它正在渲染,游戏循环正在运行,动画正在更新,但键盘输入无法正常工作。这是一个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类。当作为applet运行时,它不起作用,当我将Game类添加到框架时,它可以正常工作。

由于

现在解决了。见我的解决方案

3 个答案:

答案 0 :(得分:4)

一种可能的解决方案是使用JApplet的contentPane来设置焦点而不是JApplet本身。但我更喜欢使用Key Bindings。您可能需要使用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();
      }
   }
}

答案 1 :(得分:1)

如果您在浏览器中运行,则可能需要单击小程序以使其专注。出于安全考虑,大多数浏览器都不会让applet只是抓住键盘焦点,而无需用户点击它。

所以,我会添加一个鼠标监听器而不是直接在init()中抓取焦点:

addMouseListener(new MouseAdapter() {
   public void onMousePress(MouseEvent e) {
      requestFocus();
   }
});

答案 2 :(得分:0)

现在我有两个选择,

  • 使用JWS
  • 不要制作小程序模式

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

The GApplet class

现在它的工作方式与webstart类似,实际上是一个applet。