Связывание ключей Java в JApplet: что я делаю не так?
Я пытаюсь написать игровой апплет, который реагирует на клавиши, набранные игроком. Я пытаюсь использовать привязки клавиш для достижения этой цели. Но я не могу заставить его работать. Апплет (которого сейчас мало), кажется, правильно отображается в 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 ответ
Ваш код также не работает для меня (на 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");
}
}