Связывание ключей Java в JApplet: что я делаю не так? - PullRequest
1 голос
/ 19 декабря 2011

Я пытаюсь написать игровой апплет, который реагирует на клавиши, набранные игроком. Я пытаюсь использовать привязки клавиш для достижения этой цели. Но я не могу заставить его работать. Апплет (которого на данный момент мало) кажется правильно отображаемым в Appletviewer, но ничего не происходит, когда я нажимаю клавиши. Я не смог протестировать его в браузере, так как он не всегда правильно отображается в браузере.

Я использую Sun Java 6 в Ubuntu. Мне удалось найти упоминание об ошибке в 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");
   }
}

Единственное различие, которое я могу найти между тем, что я использовал, и рабочими примерами, найденными в разных местах, заключается в том, что они добавляют нажатие клавиш на карту ввода перед сопоставлением нажатия клавиш с действием. Я попытался изменить порядок, но, похоже, это не дало никаких результатов.

Кто-нибудь может увидеть, что я здесь делаю не так? Я просто знаю, что упускаю что-то очевидное.

1 Ответ

1 голос
/ 19 декабря 2011

Ваш код у меня тоже не работает (на mac), пока я не нажму внутри окна.Добавление следующего, как последнее, что в init (), кажется, помогает (но не совсем надежно ):

GlobalData.mainMap.requestFocus();

Ваше окно апплета, вероятно, не имеет фокуса, когда вы нажимаетеkeys.

Попробуйте добавить это в 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");
    }
}
...