Autor
|
Tema: Duda manejando eventos de teclado en Java (Leído 2,316 veces)
|
niano
Desconectado
Mensajes: 20
|
Hola. Soy algo novato en todo esto de las interfaces gráficas y animaciones y tengo algunas dudas con un código en Java que estoy confeccionando. Necesito crear una animación controlada por cuatro teclas del teclado que empiece o se detenga cuando se aprieta un botón con el ratón. Para eso defino utilizo una clase a la que he llamado Panel: //Atributos: private int ancho, alto; //el alto y el ancho del panel private boolean play=false;//Variable que nos indica si la animación ha comenzado o no. //... Más atributos. En general, objetos que deben ser pintados. Y variables que indican lo que //tienen que hacer esos objetos durante la animación //Constructor: public Panel(int anch, int alt ) { ancho=anch; alto=alt; play=false; //Se construyen los demás atributos } { //Aquí se pintan algunos de los atributos del objeto utilizando técnicas de doble bouffering } { paint (G); } public void actualizar() { //Nada.. Aquí se actualiza la posición de los objetos (atributos de Panel) que deben ser //pintados durante la animación } public void run() { while (play) { actualizar(); repaint(); try { } {} //Y más cosas que no creo que vengan a cuento. } } public void Iniciar() { play=true; hilo.start(); } public void Detener() { play=false; } //Metodos de KeyListener } { if (e.getKeyChar()=='a') { //Se modifican los atributos necesarios para que la animación haga lo que tiene que //hacer cuando se pulsa una 'a' } if (e.getKeyChar()=='s') { //Lo mismo para la 's' } if (e.getKeyChar()=='l') { //... } if (e.getKeyChar()=='ñ') { //... } } @Override { if (e.getKeyChar()=='a') { //Se modifican los atributos necesarios para que la animación haga lo que tiene que //hacer cuando se suelta la 'a' } if (e.getKeyChar()=='s') { //... } if (e.getKeyChar()=='l') { //... } if (e.getKeyChar()=='ñ') { //... } } }
Y otra clase, la clase Juego2: { private boolean play=false; private int anchoP=900, altoP=700; //El constructor. No creo que tenga mucho interés para lo de mi duda pero lo pongo por si //acaso: public Juego2() { P =new Panel (anchoP,altoP ); setBackground (new Color(240, 240, 240)); setLayout(null); boton.addActionListener(this); getContentPane().add(boton); boton.setBounds(20,330,250,30); getContentPane().add(P); P.setBounds(300, 30, anchoP, altoP); P.setVisible(true); } }); } //el main public static void main (String[] args ) { final Juego2 F = new Juego2(); F.setBounds(0, 0, 1300, 800); F.setVisible(true); } //El actionPerformed de la clase ActionListener if (e.getSource()==boton) { if (play) { play=false; boton.setText("play"); P.Detener(); } else { play=true; boton.setText("pause"); P.Iniciar(); } } } }
A continuación explicaré el fenómeno que me crea dudas.Cuando el código está listo hago lo siguiente: 1) Ejecuto el código. La cosa va bien, todo se construye y se visualiza correctamente. 2) Le doy al play. Y la animación comienza correctamente. 3) Le doy a una de las teclas controladoras y no ocurre nada. ¡Nada de nada! 4) Hago un 'click' de ratón sobre el panel y desde entonces ya sí funciona todo bien. El 'click' tiene que ser sobre el panel, si lo hago sobre otro punto de la ventana o fuera de ella las teclas controladoras siguen inactivas. ¿Alguien sabe por qué pasa esto y cómo puedo solucionarlo? Es decir, me gustaría que las teclas controladoras funcionasen desde que le doy al play, que no fuese necesario hacer ese 'click'. Muchas gracias de antemano por vuestro tiempo. Un saludo.
|
|
|
En línea
|
|
|
|
rub'n
Desconectado
Mensajes: 1.217
(e -> λ("live now")); tatuar -> λ("α");
|
Tu Panel extiende de Canvas, debería ser de JPanel, ambos se aplica lo mismo para obtener el foco, cuando haces click obtienes el foco del panel que contiene los eventos del KeyListener dog.
Aqui la parte azul representa a ese Pseudo Panel que tienes Por ningun lado vi a addKeyListener(this);
lo añadí en el método iniciar, entonces al darle click se habilita el KeyListener y el foco de ese Panel con requestFocus();
quedando //Atributos: private int ancho, alto; //el alto y el ancho del panel private boolean play = false;//Variable que nos indica si la animación ha comenzado o no. //... Más atributos. En general, objetos que deben ser pintados. Y variables que indican lo que //tienen que hacer esos objetos durante la animación private int espera = 1000; //Constructor: public Panel(int anch, int alt ) { ancho = anch; alto = alt; play = false; //Se construyen los demás atributos setBackground (Color. BLUE); } //Aquí se pintan algunos de los atributos del objeto utilizando técnicas de doble bouffering } paint(G); } public void actualizar() { //Nada.. Aquí se actualiza la posición de los objetos (atributos de Panel) que deben ser //pintados durante la animación } @Override public void run() { while (play) { actualizar(); repaint(); try { } //Y más cosas que no creo que vengan a cuento. } } public void iniciar() { play = true; addKeyListener(this); requestFocus(); hilo.start(); } public void detener() { play = false; removeKeyListener(this); } //Metodos de KeyListener } if (e.getKeyChar() == 'a') { //Se modifican los atributos necesarios para que la animación haga lo que tiene que //hacer cuando se pulsa una 'a' info("Letra A"); } if (e.getKeyChar() == 's') { //Lo mismo para la 's' info("Letra S"); } if (e.getKeyChar() == 'l') { //... info("Letra L"); } if (e.getKeyChar() == 'ñ') { //... info("Letra Ñ"); } } @Override if (e.getKeyChar() == 'a') { //Se modifican los atributos necesarios para que la animación haga lo que tiene que //hacer cuando se suelta la 'a' info("Letra A soltada"); } if (e.getKeyChar() == 's') { //... info("Letra s soltada"); } if (e.getKeyChar() == 'l') { //... info("Letra l soltada"); } if (e.getKeyChar() == 'ñ') { //... info("Letra ñ soltada"); } } }
Juego2 private boolean play = false; private int anchoP = 900, altoP = 700; //El constructor. No creo que tenga mucho interés para lo de mi duda pero lo pongo por si //acaso: public Juego2() { panel = new Panel(anchoP, altoP ); setBackground (new Color(240, 240, 240)); setLayout(null); setDefaultCloseOperation (JFrame. DO_NOTHING_ON_CLOSE); setBounds(0, 0, 1300, 800); setVisible(true); boton.addActionListener(this); getContentPane().add(boton); boton.setBounds(20, 330, 250, 30); getContentPane().add(panel); panel.setBounds(300, 30, anchoP, altoP); panel.setVisible(true); @Override "Información", "Desea salir?", 0); if(opc == 0) { } } }); } //el main public static void main (String[] args ) { new Thread(Juego2 ::new). start(); } //El actionPerformed de la clase ActionListener if (e.getSource() == boton) { if (play) { play = false; boton.setText("play"); panel.detener(); } else { play = true; boton.setText("pause"); panel.iniciar(); } } } }
Y una interface para los logs /** * logs */ public interface ShowData { default Logger getLogger() { return LoggerFactory.getLogger(getClass().getSimpleName()); } default <T> void info(final T s) { getLogger().info(s.toString()); } default <T> void error(final T s) { getLogger().warn(s.toString()); } }
|
|
« Última modificación: 11 Julio 2019, 21:24 pm por rub'n »
|
En línea
|
If you don't have time to read, you don't have the time (or the tools) to write, Simple as that. Stephen king
|
|
|
niano
Desconectado
Mensajes: 20
|
Hola rub'n. Antes de nada muchas gracias por tu respuesta, me ha sido muy útil. He hecho los cambios que me has indicado y ya funciona todo perfectamente. No obstante, me gustaría hacer un par de preguntas y observaciones si no te importa. Tu Panel extiende de Canvas, debería ser de JPanel, ambos se aplica lo mismo para obtener el foco, cuando haces click obtienes el focu del panel que contiene los eventos del KeyListener dog.
¿Te importaría indicarme, aunque sea por encima, qué ventajas tiene la clase JPanel sobre la Canvas? Según tengo entendido la clase JPanel es más nueva y todo eso. Además, es cierto que con la Canvas sigue sin funcionar el asunto. Lo que sucede es que la clase JPanel creo que no la controlo demasiado. Tampoco sé lo que es un dog En otro ejercicio que me planteé parecido a este, si utilizaba la clase JPanel me empezaban a salir componentes como botones y cuadros de texto sobre el panel si hacía algo con ellos, cuando en un principio debían estar fuera. ¿Qué te parece?¿Sabrías decirme por qué me podía estar pasando eso? Con la Canvas no me pasaba y por eso renegué de la clase JPanel. Leeré algo más sobre la JPanel a ver si me familiarizo un poco más con ella. Por ningun lado vi a addKeyListener(this);
lo añadí en el método iniciar, entonces al darle click se habilita el KeyListener y el foco de ese Panel con requestFocus();
Sí, tienes toda la razón, se me olvidó lo del addKeyListener cuando escribí el mensaje, aunque sí que lo tenía en mi código, dentro del constructor de la clase Panel. Supongo que la clave para solucionar el problema está en lo del requestFocus(). No conocía ese método. Si lo quito los métodos de la KeyListener no se activan, por muchos 'clicks' que haga. Sin embargo, si utilizo una Canvas, es indiferente ponerlo o no ponerlo. Para que se ejecuten los métodos del KeyListener hay que hacer 'click'. ¿Sabes por qué? ¿O sabes dónde puedo encontrar información sobre todo esto? Me temo que el material que tengo es bastante corto para responderme a todas las preguntas que me surgen cuando pongo las cosas en práctica. Por otro lado, dentro del detener: . public void detener() { play = false; removeKeyListener(this); }
¿Qué hace ese removeKeyListener? ¿Es necesario? No lo había visto nunca, en mi corta experiencia en estos asuntos. Y para finalizar, añadir que me has dado una buena idea con la modificación del windowClosing para que el programa confirme que realmente se quiere salir. Empiezo ahora también con los cuadros de diálogo. A ver si poco a poco me voy aclarando. Y eso, que muchísimas gracias por todo, en serio. Un saludo.
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Keylogger sin Eventos del teclado
Programación Visual Basic
|
hackper
|
1
|
2,198
|
14 Diciembre 2005, 21:48 pm
por Slasher-K
|
|
|
Ayuda, eventos de Teclado no es escuchado en JPANEL
Java
|
DarkSorcerer
|
5
|
8,302
|
6 Mayo 2013, 17:02 pm
por sapito169
|
|
|
Diferenciar eventos según teclado C#
.NET (C#, VB.NET, ASP)
|
kondrag_X1
|
3
|
3,437
|
22 Abril 2015, 15:50 pm
por kondrag_X1
|
|
|
Ayuda con eventos del teclado
Java
|
sebast345
|
3
|
2,542
|
18 Noviembre 2016, 13:22 pm
por Orubatosu
|
|
|
Comparar eventos de teclado con strings (C#)
.NET (C#, VB.NET, ASP)
|
Alejovsq
|
3
|
2,907
|
9 Agosto 2019, 01:34 am
por Alejovsq
|
|