Foros aprenderaprogramar.com
Aprender a programar => C, C++, C#, Java, Visual Basic, HTML, PHP, CSS, Javascript, Ajax, Joomla, MySql y más => Mensaje iniciado por: caludo en 17 de Noviembre 2015, 00:45
-
Hola! Estoy practicando/aprendiendo en Java y he hecho un pequeño ejercicio que consta de poder mover una bola con el teclado(con las flechas de direccion), si dejo de pulsar las flechas del teclado, la bola sigue su curso, y si llega al borde del panel la bola rebota y cambia de direccion. Hasta aquí todo correcto, de hecho me funciona correctamente.....
.... PERO mi duda es como lo puedo hacer mediante la clase Thread. En este ejercicio uso basicamente la clase Timer para el movimiento de la pelota y las clases keyReleased y keyPressed para poder cambiar la direccion de la pelota por teclado. Pero mi intensión es hacerlo con Thread en lugar de con Timer y mantener keyReleased y keyPressed para poder dirigir la direccion de la bola.
Además tengo otra duda, tengo entendido que(sobre eventos) la clase ActionListener solo sirve para llevar a cabo una accion en componentes (por ejemplo botones) o sea no podría usarlo para hacer click en la bola( o imagen, o lo que sea que esté dibujado y no sea un componente como un botón) y que esta pudiera "responder" a ese click(por ejemplo al hacer click en la bola, esta cambia de color).¿Qué tipo de eventos puedo usar para esto?Supongo que hacer "click" sobre un dibujo o imagen en movimiento no será muy complicado, pero no se como hacerlo.
El código es:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.*;
import javax.swing.*;
public class Bola1 extends JFrame{
Panell panel=new Panell();
public Bola1(){
super("Bola Movimientoo");
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(panel);
setVisible(true);
}
public static void main(String[]args){
Bola1 bolita=new Bola1();
}
}
class Panell extends JPanel implements ActionListener{
BolaMovimientos bolaMov=new BolaMovimientos(this);
Timer timer;
public Panell(){
setFocusable(true);
addKeyListener(new teclado());
timer=new Timer(15,this);
timer.start();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
g2.setColor(Color.red);
g2.fillOval(bolaMov.getX(), bolaMov.getY(), 30, 30);
}
@Override
public void actionPerformed(ActionEvent e) {
bolaMov.mover();
repaint();
}
private class teclado extends KeyAdapter{
public void keyReleased(KeyEvent e){
bolaMov.keyReleased(e);
}
public void keyPressed(KeyEvent e){
bolaMov.keyPressed(e);
}
}
}
class BolaMovimientos{
Panell panel1;
int x=1;
int y=1;
int dx=0;
int dy=0;
public BolaMovimientos(Panell panelito){
this.panel1=panelito;
}
public void mover(){
x=x+dx;
y=y+dy;
if((x+dx)>panel1.getWidth()-30){
dx=-1;
}else if((x+dx)<0){
dx=1;
}else if((y+dy)>panel1.getHeight()-30){
dy=-1;
}else if((y+dy)<0){
dy=1;
}
}
public void keyPressed(KeyEvent e){
int key=e.getExtendedKeyCode();
if(key==KeyEvent.VK_LEFT){
dx=-1;
dy=0;
}
if(key==KeyEvent.VK_RIGHT){
dx=1;
dy=0;
}
if(key==KeyEvent.VK_UP){
dx=0;
dy=-1;
}
if(key==KeyEvent.VK_DOWN){
dx=0;
dy=1;
}
}
public void keyReleased(KeyEvent e){
int key=e.getExtendedKeyCode();
if(key==KeyEvent.VK_LEFT){
}
if(key==KeyEvent.VK_RIGHT){
}
if(key==KeyEvent.VK_UP){
}
if(key==KeyEvent.VK_DOWN){
}
}
public int getX(){
return x;
}
public int getY(){
return y;
}
}
Espero que se pueda entender el codigo! :P
Muchisimas Gracias por todo y saludos!!
-
Hola!
Aunque es más complejo que esto, thread a la hora de controlar una animación se usuaría para definida la animación al completo por ejemplo mediante un bucle, detener la ejecución cada cierto intervalo de tiempo de modo que podamos ver cómo evoluciona la situación. Aquí hay un ejemplo con una animación de un cohete en lanzamiento https://www.aprenderaprogramar.com/foros/index.php?topic=1699.0
Los Timers son objetos que se usan para establecer que algo debe ejecutarse una única vez después de cierta demora, o bien para establecer que algo debe ejecutarse repetidamente, aquí una aplicación típica sería actualizar la visualización-estado de un componente periódicamente.
Una regla aproximada que puede seguirse es:
- Usar Timer siempre que se trate de una aplicación con interfaz gráfica (como en este caso) que deba detectar eventos. Si se usa Thread.sleep lo que haríamos sería "detener" el programa por unos instantes, de modo que no se detectaría por ejemplo una pulsación de tecla y parecería que el programa no funciona. Esto con Timer no ocurre.
Para cambiar el color de una figura cuando hagas click sobre ella te puedes guiar por este ejemplo: https://www.aprenderaprogramar.com/foros/index.php?topic=3530.0
Saludos!
-
Hola Cesar!Gracias por la respuesta y por los ejemplos.Creo que lo he entendido perfectamente.
Quería preguntarte un par de cosas para ver si realmente lo he entendido.
O sea, por tu explicacion deduzco que:
-Si yo quiero que las figuras geometricas de tu codigo se muevan y cambien de color al pulsarlas, entonces usaría timer, y no thread.
-Si simplemente creo 2 o mas figuras(por ejemplo un circulo, o una imagen) en movimiento...lo hago usando Thread...si quiero que ocurra algo(como que cambien de color, desaparezcan,etc) al pulsar un botón, también usaría Thread...PERO si quiero que ocurra algo(que cambien de color, desaparezcan,etc) al pulsar sobre la misma figura(y no a traves de un botón) entonces usaría Timer
Es esto correcto? Gracias por todo y saludos!!!
PS. Supongo que las animaciones además de Thread y Timer se puede hacer con otras clases, pero de momento lo desconozco
-
Hola!
Yo lo que te recomendaría es que uses Timer para desarrollar tus programas, con eso vas a poder resolverlo casi todo y puedes olvidarte de Thread. Sólo deberías usar Thread cuando la ejecución concurrente de eventos genere conflictos y esto haga recomendable mantener dos hilos de ejecución. A veces se usa Thread.sleep con un solo hilo para forzar la detención del programa, digamos que una pausa de ejecución, pero esto realmente no es uso de hilos, sino simplemente pausar el hilo único que está en ejecución.
Saludos!
-
Muchas gracias Cesar!