miércoles, 12 de septiembre de 2007

Programación de un timer en java

Como se puede programar una tarea repetitiva y automática en un aplicativo tipo Swing de java?, esta pregunta me la plantearon los alumnos de programación orientada a objetos, mi respuesta un Timer. Pero veamos como se hace esto.


La idea es generar una aplicación con una etiqueta que usaremos como display del contador y tres botones con las acciones de iniciar, parar y reset.


El contador se mantendrá contando una ves pulsemos el botón Iniciar y solo se detendrá al pulsar el botón Parar; si pulsamos el botón Reset su contador debe regresar a cero.


Para este fin utilizaremos la clase Timer de java.util, entonces nuestros imports quedaran de la siguiente manera:

import java.awt.*;

import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.*;


Para poder manejar una tarea de manera automática y repetitiva debemos sobre-escribir el método run de la clase TimerTask; para esto crearemos una clase interna que llamaremos RemindTask y nuestro método run quedara como sigue:


class RemindTask extends TimerTask {
public void run() {
segundos++;
lblTime.setText(String.valueOf(segundos));
if(frozen){
System.out.println("Terminamos la ejecucion del timer");
timer.cancel();
}
}
}


Este método lo único que hace es incrementar una variable segundos y cargar este valor en el display de nuestro contador. Recuerden que dijimos que era una clase interna, así que se debe declarar dentro del cuerpo de la clase de la interfaz gráfica con lo que el código total queda de la siguiente manera:


public class AppContadorSwing implements ActionListener{
JFrame frame;
JPanel panel;
JButton btnIniciar,btnParar,btnReset;
JLabel lblTime;
Timer timer;
int segundos;
//manejar el valor del contador
boolean frozen;
//manejar el estado del contador

public AppContadorSwing() {
frame = new JFrame("Contador Swing");
panel = new JPanel(new GridLayout(1,3));
btnIniciar = new JButton("Iniciar");
btnIniciar.addActionListener(this);
btnParar = new JButton("Parar");
btnParar.addActionListener(this);
btnReset = new JButton("Reset");
btnReset.addActionListener(this);
lblTime = new JLabel("0",SwingConstants.CENTER);

panel.add(btnIniciar);
panel.add(btnParar);
panel.add(btnReset);

frame.getContentPane().add(lblTime, BorderLayout.NORTH);
frame.getContentPane().add(panel, BorderLayout.SOUTH);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();
frame.setVisible(true);

frozen = true;
//iniciamos el estado en congelado
segundos = 0;
}

//clase interna que sobre-escribe el metodo run de TimerTask

class RemindTask extends TimerTask {
public void run() {
segundos++;
lblTime.setText(String.valueOf(segundos));
if(frozen){
System.out.println("Terminamos la ejecucion del timer");
timer.cancel();
//detenemos el timer
}
}
}

public void actionPerformed(ActionEvent a) {
System.out.println(a.getActionCommand());
if(a.getActionCommand().equals("Iniciar")){
frozen = false;
timer = new Timer();
//le asignamos una tarea al timer
timer.schedule(new RemindTask(),0, 1*100);
}
if(a.getActionCommand().equals("Parar")){
frozen = true;
}
if(a.getActionCommand().equals("Reset")){
frozen = true;
segundos = 0;
lblTime.setText(String.valueOf(segundos));
}
}

public static void main(String[] args){
JFrame.setDefaultLookAndFeelDecorated(true);
AppContadorSwing c = new AppContadorSwing();
}
}


En color verde van los comentarios que afectan la ejecución del timer como tal, el resto del código se refiere a la interfaz gráfica, que no es tema de esta guía.

18 comentarios:

Anónimo dijo...

Hola gracias por este programa me ha servido mucho por que estoy haciendo un programa que administre el tiempo de un billar y con esto me sacaste de apuros mil gracias

Kira dijo...

hola!... necesito hacer un programa en java que simule el mercado bursatil internacional.... con sus mercados, bolsas, indices bursatiles, que se modifique solo con el tiempo y los parametros de los mercados, por ejemplo.. aumenta el petroleo a algunos mercados eso los mejora en inversionistas y a otros tambien los afecta el comportamiento de los demas mercados... alguien puede resolver esto por lo menos dando un ejemplo? aqui esta el link que explica mas detalladamene el programa
http://www.ciens.ucv.ve/algoritmosyprogramacion/documentos/Alg_Proyecto2.pdf

Kira dijo...

hola!... necesito hacer un programa en java que simule el mercado bursatil internacional.... con sus mercados, bolsas, indices bursatiles, que se modifique solo con el tiempo y los parametros de los mercados, por ejemplo.. aumenta el petroleo a algunos mercados eso los mejora en inversionistas y a otros tambien los afecta el comportamiento de los demas mercados... alguien puede resolver esto por lo menos dando un ejemplo? aqui esta el link que explica mas detalladamene el programa
http://www.ciens.ucv.ve/algoritmosyprogramacion/documentos/Alg_Proyecto2.pdf

Anónimo dijo...

q paso boleta ese no es tu proyecto 2 de algoritmo??? el q vale 2 pts clarooooo si no hiciste el de cifra menos este jajaja coño se menos descarada digoooo no se....
atte Joel...

fdesantos dijo...

Muchas gracias por la aportación, me ah sido de mucha utilidad.

GeekZero dijo...

a mi tambien me has sacado del apuro, tenia otra implementacion hecha pero funcionaba a medias nomas.. GraX :D

Anónimo dijo...

Gracias man, me has ayudado estoy haciendo el juego buscaminas, pues me lo pidieron como proyecto de clases, y no tenia idea se usar un contador de tiempo.

Anónimo dijo...

muchas gracias por tu aporte
en verdad que me estaba rompiendo la cabeza con esto, y gracias a tu codigo puede entenderle mejor al manejo de algunos metodos de la clase Timer

Jairo dijo...

demasiado excelente este aporte brother, de veras que este codigo ayudo un monton!!!

cuando tenga la aplicacion te la enseño, ya que ni si quiera use el codigo para nada de numeros, sino para mover unos paneles y que se viera bastante animado!!!!

una vez mas muchas gracias

Salomón dijo...

Como se puedo hacer para colocar indices bursátiles en tiempo real?

Anónimo dijo...

Hola, gracias, me sirvió mucho este programa.. en realidad no tenía idea como hacerle q se repita un proceso, pero esto me ayudó enormemente..

Bridaroga dijo...

Hola. Gracias por el ejemplo, me sirvió muchísimo, estaba intentando hacer lo mismo pero de esta forma:

...
private TimerTask tarea = new TimerTask() {
...

pero al iniciar de nuevo el Timer y
escribir estas líneas de código:

...
conteoTiempo = new Timer();
conteoTiempo.scheduleAtFixedRate(tarea, 0, 1000);
...

me daba error al intentar ejecutar de nuevo estas líneas porque conteoTiempo ya tenía un schedule (programador), el que había instanciado anteriormente.

De todas formas tendré esto en cuenta y de nuevo muchas gracias por el ejemplo.

Anónimo dijo...

Cojonudo la explicación, tenia problemas con cancelar la tarea y estaba usando ahasta el purge pero va de lujo así.

Un saludo.

oscar dijo...

ok gracias !!!!!!!!!111

ACL dijo...

Te agradezco mucho la explicación.

Gracias.

GioLazarev dijo...

Buenas!!
una pregunta, soy novato (POLLO) en la programacion java, yo utilizo netbeans IDE para programar, y no tengo idea de como hacer para modificar y/o controlar un valor atravez de un JSlider, y que ese valor tenga como salida el puerto serial.

Oscar dijo...

Me sirvio mucho para mi proyecto "Reproductor MP3", el cual tenia una animacion con un JSlider que avanzaba a medida que la canción era reproducida. Muchas gracias por la explicación.

dukege dijo...

Ing. muchas gracias por su ejemplo me sirvió bastante para solucionar el problema que tenia con mi consulta automatica a postgresql