Dúvidas com InputMap/ActionMap - Obter tecla pressionada

1 resposta
dudaskank

Boa tarde pessoal

Andei lendo no guj uns tópicos sobre ActionMap e InputMap e eles pareciam que resolveriam meus problemas. Li os seguintes tópicos:

Dúvida - ActionMap e InputMap
ActionListener x KeyListener

Porém não consegui. Coloquei um InputMap em um JPanel e associei alguns nomes, e esses nomes coloquei também no ActionMap, sempre enviando para a mesma ação.

Meu problema é que, quando a ação é executada, eu não consigo saber qual a tecla que o usuário apertou, nem o KeyStroke e nem o nome que usei para mapear a tecla para a ação, e é exatamente disso que preciso, para poder atualizar alguns contadores que se referem as teclas em si.

Outro problema é que preciso da tecla independente dos modificadores, ou seja se apertar a, shift+a, ctrl+a, vou saber que ele apertou a tecla a. Inclusive, preciso saber também se ele apertou só os modificadores (shit, ctrl, etc).

Atualmente, faço tudo isso utilizando KeyListener e funciona bem, só que aí fica complicado caso eu venha incluir alguns outros componentes que aceitam foco no meu JPanel.

Espero que não tenha ficado complicado de entender, daqui a pouco devo colocar algum código de como estou fazendo atualmente.

Valeu

1 Resposta

dudaskank

Pessoal, separei o código aqui pra tentar dar uma explicada melhor no meu problema, quem sabe isso ajuda.

Criando o JFrame e colocando o JPanel nele:

screen = new JFrame(gc);
screen.setIgnoreRepaint(true);
screen.setResizable(false);
screen.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
panelScreen = new JPanel();
panelScreen.setOpaque(false);
panelScreen.setIgnoreRepaint(true);
panelScreen.setFocusable(true);
screen.getContentPane().add(panelScreen);
panelScreen.requestFocus();

E aqui o meu KeyListener:

public void keyPressed(KeyEvent e) {
	GameAction gameAction = getKeyAction(e);
	if (gameAction != null) {
		gameAction.press();
	}
	// make sure the key isn't processed for anything else
	//e.consume();
}

public void keyReleased(KeyEvent e) {
	GameAction gameAction = getKeyAction(e);
	if (gameAction != null) {
		gameAction.release();
	}
	// make sure the key isn't processed for anything else
	//e.consume();
}

public void keyTyped(KeyEvent e) {
	// make sure the key isn't processed for anything else
	//e.consume();
}

O getKeyAction ali retorna a minha classe de ação associada com a tecla, e press() incrementa em 1 o valor da quantidade de vezes que ela foi pressionada. Esta classe verifica esse valor para dizer se ela está ou não sendo pressionada. O método release() seta esse valor com 0.

Aqui é onde faço o mapeamento:

public void mapToKey(GameAction gameAction, int keyCode) {
	keyActions[keyCode] = gameAction;
	comp.getInputMap().put(KeyStroke.getKeyStroke(keyCode, 0, true), gameAction.getName());
	comp.getActionMap().put(gameAction.getName(), action);
}

Onde action é:

action = new AbstractAction(getClass().getName()) {
	private static final long serialVersionUID = 1L;

	public void actionPerformed(ActionEvent e) {
		logger.debug("ParamString: " + e.paramString());
	}
};

Usando o InputMap + ActionMap no componente que tem um listener como esse, o que aparece no debug ao apertar a letra a sozinha é apenas

[DEBUG] ParamString: ACTION_PERFORMED,cmd=a,when=1196357497730,modifiers=

Sem nenhum sinal do número da tecla que eu preciso.

Criado 29 de novembro de 2007
Ultima resposta 29 de nov. de 2007
Respostas 1
Participantes 1