JApplet 中的 Java 键绑定:我做错了什么?

发布于 2024-12-21 21:02:01 字数 2825 浏览 2 评论 0原文

我正在尝试编写一个游戏小程序来响应玩家键入的按键。我正在尝试使用键绑定来完成此任务。但我无法让它发挥作用。小程序(目前只有很少的一部分)似乎在 Appletviewer 中正确显示,但当我按键时没有任何反应。我无法在浏览器中测试它,因为它并不总是在浏览器中正确显示。

我在 Ubuntu 上运行 Sun Java 6。我设法发现了一个 Ubuntu 错误,其中 iBus 会阻止小程序的键盘输入。但是,我没有运行 iBus,并且我已经能够使用其他小程序(不是我编写的)键盘输入。

这是到目前为止的代码

public class AlxTestVersion extends JApplet {
   private GridBagLayout layout;
   private GridBagConstraints layoutConstraints;
   private JPanel mainPanel;

   public void init() {
      this.setLayout ( new FlowLayout(FlowLayout.LEFT) );
      //Main frame.
      mainPanel = new JPanel();
      layout = new GridBagLayout();
      layoutConstraints = new GridBagConstraints();
      layoutConstraints.anchor = GridBagConstraints.NORTHWEST;
      layoutConstraints.fill = GridBagConstraints.NONE;
      mainPanel.setLayout(layout);
      mainPanel.setBackground(Color.pink);
      getContentPane().add(mainPanel);
      //Map display
      JPanel leftPanel = new JPanel();
      GlobalData.mainMap = new MapCanvas(9);
      addComponent(GlobalData.mainMap, 0, 0, 1, 1);
      /*
         Define other components...
      */
   }

public class MapCanvas extends JPanel {
   private int tileSize;
   private int mapTileWidth;
   private int mapOffset;
   private int mapDim;

   private MapSquare screenTiles[];

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      ImageIcon testImage = new ImageIcon("tiles/test_land.gif");
      int x,y;
      for (x=0;x<mapTileWidth;x++) {
         for (y=0;y<mapTileWidth;y++) {
            g.drawImage(testImage.getImage(), x*tileSize + mapOffset, y*tileSize + mapOffset, this);
         }
      }
   }

   public MapCanvas(int numTiles) {
      //Set up window
      tileSize = 48;
      mapTileWidth = numTiles;
      mapOffset = 4;
      mapDim = (tileSize * mapTileWidth) + (2 * mapOffset);
      Dimension dim = new Dimension(mapDim, mapDim);
      this.setPreferredSize(dim);
      this.setMinimumSize(dim);
      this.setMaximumSize(dim);
      this.setLayout( new GridLayout(numTiles, numTiles, 0, 0) );
      this.setBackground(Color.black);
      screenTiles = new MapSquare[numTiles^2];

      //Map-related actions
      InputMap im = this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
      ActionMap am = this.getActionMap();

      AbstractAction north = new AbstractAction() {
         public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(null, "Just for testing", "testing",
            JOptionPane.PLAIN_MESSAGE);
         }
      };
      am.put("North", north);

      im.put(KeyStroke.getKeyStroke('2'), "North");
      im.put(KeyStroke.getKeyStroke('i'), "North");
   }
}

关于我所使用的代码和在不同地方找到的工作示例之间的唯一区别是它们在将击键映射到操作之前将击键添加到输入映射。我尝试改变顺序,但似乎没有任何效果。

有人能看到我在这里做错了什么吗?我只知道我错过了一些明显的东西。

I'm trying to write a game applet that responds to keys typed by the player. I'm trying to use key bindings to accomplish this. But I can't get it to work. The applet (what little of it there is, at the moment) seems to display correctly in Appletviewer, but nothing happens when I press keys. I haven't been able to test it in a browser, as it doesn't always display correctly in a browser.

I'm running Sun Java 6 on Ubuntu. I managed to find mention of a Ubuntu bug where iBus would block keyboard input to applets. However, I don't have iBus running, and I've been able to use keyboard input with other applets (not written by me).

Here is the code so far

public class AlxTestVersion extends JApplet {
   private GridBagLayout layout;
   private GridBagConstraints layoutConstraints;
   private JPanel mainPanel;

   public void init() {
      this.setLayout ( new FlowLayout(FlowLayout.LEFT) );
      //Main frame.
      mainPanel = new JPanel();
      layout = new GridBagLayout();
      layoutConstraints = new GridBagConstraints();
      layoutConstraints.anchor = GridBagConstraints.NORTHWEST;
      layoutConstraints.fill = GridBagConstraints.NONE;
      mainPanel.setLayout(layout);
      mainPanel.setBackground(Color.pink);
      getContentPane().add(mainPanel);
      //Map display
      JPanel leftPanel = new JPanel();
      GlobalData.mainMap = new MapCanvas(9);
      addComponent(GlobalData.mainMap, 0, 0, 1, 1);
      /*
         Define other components...
      */
   }

public class MapCanvas extends JPanel {
   private int tileSize;
   private int mapTileWidth;
   private int mapOffset;
   private int mapDim;

   private MapSquare screenTiles[];

   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      ImageIcon testImage = new ImageIcon("tiles/test_land.gif");
      int x,y;
      for (x=0;x<mapTileWidth;x++) {
         for (y=0;y<mapTileWidth;y++) {
            g.drawImage(testImage.getImage(), x*tileSize + mapOffset, y*tileSize + mapOffset, this);
         }
      }
   }

   public MapCanvas(int numTiles) {
      //Set up window
      tileSize = 48;
      mapTileWidth = numTiles;
      mapOffset = 4;
      mapDim = (tileSize * mapTileWidth) + (2 * mapOffset);
      Dimension dim = new Dimension(mapDim, mapDim);
      this.setPreferredSize(dim);
      this.setMinimumSize(dim);
      this.setMaximumSize(dim);
      this.setLayout( new GridLayout(numTiles, numTiles, 0, 0) );
      this.setBackground(Color.black);
      screenTiles = new MapSquare[numTiles^2];

      //Map-related actions
      InputMap im = this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
      ActionMap am = this.getActionMap();

      AbstractAction north = new AbstractAction() {
         public void actionPerformed(ActionEvent e) {
            JOptionPane.showMessageDialog(null, "Just for testing", "testing",
            JOptionPane.PLAIN_MESSAGE);
         }
      };
      am.put("North", north);

      im.put(KeyStroke.getKeyStroke('2'), "North");
      im.put(KeyStroke.getKeyStroke('i'), "North");
   }
}

About the only difference I can find between what I've used and working examples found in various places is they add the keystroke to the inputmap before mapping the keystroke to the action. I tried switching the order, but it didn't seems to have any effect.

Can anyone see what I'm doing wrong here? I just know I'm missing something obvious.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柒七 2024-12-28 21:02:01

你的代码也不适合我(在Mac上),直到我在窗口内单击。添加以下内容作为 init() 中的最后一件事似乎有帮助(但 不完全可靠):

GlobalData.mainMap.requestFocus();

当您按键时,您的小程序窗口可能没有焦点。

尝试将其添加到您的 init() 中:

GlobalData.mainMap.addFocusListener(new FocusDebugger("canvas"));
this.addFocusListener(new FocusDebugger("applet"));

这是 FocusDebugger:

public static class FocusDebugger implements FocusListener {
    private final String name;

    public FocusDebugger(String name) {
        this.name = name;
    }

    public void focusGained(FocusEvent focusEvent) {
        System.out.println(name + ".focusGained");
    }

    public void focusLost(FocusEvent focusEvent) {
        System.out.println(name+".focusLost");
    }
}

Your code doesn't work for me either (on a mac), until I click inside the window. Adding the following as the last thing in init() seems to help (but is not totally reliable):

GlobalData.mainMap.requestFocus();

Your applet window probably does not have the focus when you press the keys.

Try adding this to your init():

GlobalData.mainMap.addFocusListener(new FocusDebugger("canvas"));
this.addFocusListener(new FocusDebugger("applet"));

Here's FocusDebugger:

public static class FocusDebugger implements FocusListener {
    private final String name;

    public FocusDebugger(String name) {
        this.name = name;
    }

    public void focusGained(FocusEvent focusEvent) {
        System.out.println(name + ".focusGained");
    }

    public void focusLost(FocusEvent focusEvent) {
        System.out.println(name+".focusLost");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文