sexta-feira, 12 de fevereiro de 2010

KeyListener global no Java

Quem já fez controle de aplicações via teclado em Java/Swing sabe o quanto é chato tratar eventos de teclado: Tem que adicionar KeyListener em TODOS os componentes, porque se o componente que tiver o foco não tiver o listener, nada acontece.

A solução pra isso? Adicionar KeyListeners nos componentes e em seus filhos, recursivamente! Eis como:

1) Criamos a seguinte função no nosso JFrame (Como ele se baseia em Component, essa dica funciona com todas as classes que herdam dela, como JDialog, JPanel, etc):


private void addKeyAndContainerListenerRecursively(Component c) {
try {
c.addKeyListener(this);
if (c instanceof Container) {
Container cont = (Container) c;
cont.addContainerListener(this);
Component[] children = cont.getComponents();
for (int i = 0; i < children.length; i++) {
addKeyAndContainerListenerRecursively(children[i]);
}
}
} catch (Exception e) {
//Anuncie Aqui
}
}



2) Fazemos o JFrame implementar dois Listeners, o KeyListener e o ContainerListener:


public class MeuJFrameLegal extends JFrame implements KeyListener, ContainerListener {
//...
}


3) Temos que implementar as seguintes funções:


public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void componentAdded(ContainerEvent e) {}
public void componentRemoved(ContainerEvent e) {}


4) Na função keyPressed, colocamos nosso código legal e mágico:


public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_F1:
System.out.println("Parabéns, você pressionou F1");
break;
}
}


5) E pronto! Agora basta chamar a função addKeyAndContainerListenerRecursively no final do seu método de inicialização da parte gráfica (aquele que a gente adiciona os componentes ao Componente).


"Mas tio Preco, pra que serve o ContainerListener???"

O ContainerListener serve pro seguinte: Digamos que sua janela chame outra janela, e você quer que as funções que você atribuiu às teclas na janela pai também estejam disponíveis na janela filha. Então você faz o seguinte:


public void componentAdded(ContainerEvent e) {
addKeyAndContainerListenerRecursively(e.getContainer());
}


E pronto (de novo)! Agora todas as janelas que a janela pai chamar "herdarão" o Listener \o/



É isso, té o/

(Fonte: Java World)

Nenhum comentário: