Olá galera do GUJ!
Gostaria de tirar uma duvida.Eu tenho um JPanel que recebe entradas de teclado perfeitamente e um JFrame que recebe esse JPanel.
Porém em determinada condicao eu tenho que remover o JPanel do JFrame e adicionar outro (JPanel), só que quando faco isso o JPanel final nao consegue receber as entradas.
Por eliminatoria mechi nos metodos .setFocusable() das classes, alterando pra que uma fique sem o foco e outra receba esse foco, porém nada deu certo.Algum de voces sabe como resolver isso:?:
Obrigado a todos!!!
Depende do que você fez no seu código…
Postarei o codigo aqui para a duvida ficar mais clara…lembrando que no actionPerformed ele nao só pinta, este codigo é apenas uma parte bem simplificada do meu, fiz isso para diminuir o tempo de analise
Retirei o JPanel inicial e deixei só com o defeituoso
public class Principal {
public static void main(String args[]){
JFrame frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 500);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
frame.setTitle("Naruto: fight shinobi");
PainelLuta painelLuta=new PainelLuta();
frame.getContentPane().add(painelLuta);
}
}
Agora a classe do JPanel defeituoso
public class PainelLuta extends JPanel implements ActionListener{
Image imagem;
Timer tempo;
public PainelLuta(){
this.setFocusable(true);
this.setBounds(0, 0, 800, 500);
imagem=(new ImageIcon(getClass().getResource("fundo.png"))).getImage();
this.setLayout(new BorderLayout());
addKeyListener(new AdaptadorTeclado());
Iniciar();
}
public void Iniciar() {
tempo = new Timer(100,this);
tempo.start();
}
public class AdaptadorTeclado extends KeyAdapter{
public void keyPressed(KeyEvent e){
int key=e.getKeyCode();
if(key==KeyEvent.VK_RIGHT){
System.out.println("Direita");
}
if(key==KeyEvent.VK_LEFT){
System.out.println("Esquerda");
}
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(imagem,0,0,null);
}
public void actionPerformed(ActionEvent arg0) {
repaint();
}
}
Obrigado pela ajuda
Você está fazendo um jogo? Se estiver, é uma péssima idéia usar painéis.
Para capturar eventos independente do componente que os gerou, use o KeyMap e o InputMap:
http://www.guj.com.br/java/140986-como-acionar-os-bots-de-uma-calculadora-atrav-do-teclado
Indo com calma vamos entender o uso so InputMap e ActionMap…
Pelo que observei do codigo, voce cria acoes e depois faz a atribuicao de cada tecla a cada acao (que é so uma mas varia).
Se for isso mesmo, entao no meu codigo eu só modificaria a forma de capturar essas entradas, Estou certo?
com "Você está fazendo um jogo? Se estiver, é uma péssima idéia usar painéis."
O que voce quer dizer? Esta falando da forma de como eu pego as entradas ou do painel mesmo?
Obrigado e aguardo resposta!!!
Oi, é isso mesmo, só mudar o mecanismo de captura.
E, no caso, estou falando do painel mesmo. Se você quiser ter uma movimentação fluída no jogo, e uma taxa de FPS decente, não pode contar com o uso do Swing. Deve usar o Java2D direto, preferencialmente através da classe BufferStrategy, como descrito aqui:
http://www.pontov.com.br/site/index.php/java/48-java2d/124-desenho-direto-active-rendering
Também é importante ter um controle de gameloop decente:
http://www.pontov.com.br/site/index.php/java/48-java2d/121-o-loop-de-animacao
Só assim vc consegue fazer jogos com muitos agentes, que rodem de maneira suave e alta taxa de FPS, como esse demo de partículas aqui:
http://www.pontov.com.br/files/outros/vinigodoy/particles/particles.html
Entao vinicius, no meu caso eu uso as imagens que ja tenho em maos entao o que preciso fazer é somente calcular posicoes, e a FPS nao pode ser alta, pois traria uma velocidade que por incrivel que pareca (no meu caso) é ruim, entao considerando estes requisitos voce me indica continuar com os JPanel’s ou realmente dominar a tecnica contida nos links
Obs: Ficou muito bom aquele demo!!!
E só para tirar a duvida…
Voce sabe o que esta errado no meu codigo?Por que ele nao consegue pegar as entradas?
Obrigado novamente!!
Por que o KeyListener só responde a quem tem foco. E descobrir quem tem foco é uma coisa exotérica.
Você até pode tentar chamar um requestFocusInWindow() depois que sua janela se tornar visível, mas as experiências com KeyListeners geralmente são mesmo traumáticas, a menos que não haja nenhum componente na tela. Não é à toa que o JTextField, por exemplo, recomenda que vc trate entrada do teclado pelo Document e pelo InputVerifier, e que o Swing criou coisas como o ActionMap e o InputMap.
Esse “traumaticas” veio bem na situacao!Vou te falar viu, que busca mais cansativa pra fazer funcionar…e nada…
Mas faz assim vou tentar fazer pelo KeyMap e InputMap, aí se tiver dificuldade posto aqui pra obter ajuda!
Obrigado pelos exclarecimentos!
Consegui Vinicius!!!
Agora sim!
Valeu demais a ajuda…vou postar como que ficou o meu teste para talvez servir de exemplo para as outras pessoas
Muito Obrigado!
public class PainelLuta extends JPanel implements ActionListener{
Image imagem;
Timer tempo;
private BotaoNumericoAction acao = new BotaoNumericoAction();
public PainelLuta(){
ActionMap actionMap = this.getActionMap();
actionMap.put("Entrada", acao);
this.setActionMap(actionMap);
InputMap imap = this.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
imap.put(KeyStroke.getKeyStroke("ENTER"), "Entrada"); //acao esta associada a tecla enter
this.setBounds(0, 0, 800, 500);
imagem=(new ImageIcon(getClass().getResource("fundo.png"))).getImage();
this.setLayout(new BorderLayout());
this.setVisible(true);
Iniciar();
}
public void Iniciar() {
tempo = new Timer(100,this);
tempo.start();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(imagem,0,0,null);
}
private class BotaoNumericoAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
System.out.println("Voce conseguiu!!!!Yahhhh");
}
}
public void actionPerformed(ActionEvent arg0) {
repaint();
}
}