Hola, bienvenidos a este nuevo post!!!
En esta ocasión veremos como implementar una clase que nos permita agregar un reloj que se actualiza segundo a segundo y que además muestre la hora actual.
Yo para este post voy a explicar como hacerlo con una clase que extienda de jLabel para que así hacen la clase una vez y luego pueden volver a usarla una y otra vez para todas las aplicaciones en las que deseen implementar este reloj, ya luego con un poco de ingenio pueden usar el código a su manera, agregandolo como deseen a sus proyectos.
Lo primero que haremos es una nueva clase, yo en este caso le llamé "Reloj":
===================================
public class Reloj{
}
==================================
Como vamos a hacer que nuestro reloj se muestre en un j Label haremos que nuestra clase herede de la clase JLabel para que así pueda ser agregada a nuestros proyectos como cualquier otro Label:
==================================
import javax.swing.JLabel;
public class Reloj extends JLabel{
}
==================================
Bien, ahora, dijimos que nuestro reloj actualizará sus datos segundo a segundo, motivo x el cual debemos hacer que nuestra clase implemente su propio hilo de ejecución, para esto hacemos que nuestra clase implemente la "interfaz" Runnable, y nos vemos obligados a sobreescribir el método run:
==================================
import javax.swing.JLabel;
public class Reloj extends JLabel implements Runnable{
public void run( ){
}
}
==================================
Hasta aquí todo perfecto, nuestra clase está casi pronta, solo debemos crear unas variables y algunos objetos y un método para calcular la hora y fecha actuales.
Primero creamos las variables que tomarán valor de la hora y fecha, estas serán de tipo String (les puse private xq una vez instanciada la clase no las precisamos para nada... :
==================================
import javax.swing.JLabel;
public class Reloj extends JLabel implements Runnable{
private String dia, mes, año, hora, minutos, segundos;
public void run( ){
}
}
==================================
Ahora crearemos un objeto de la clase Calendar y le damos formato con gregorianCalendar:
==================================
import javax.swing.JLabel;
public class Reloj extends JLabel implements Runnable{
private String dia, mes, año, hora, minutos, segundos;
private Calendar calendario = new GregorianCalendar();
public void run( ){
}
}
==================================
y también creamos el hilo de ejecución sin iniciarlo (lo iniciaremos en el constructor de nuestra clase):
==================================
import javax.swing.JLabel;
public class Reloj extends JLabel implements Runnable{
private String dia, mes, año, hora, minutos, segundos;
private Calendar calendario = new GregorianCalendar();
Thread hilo;
public void run( ){
}
}
==================================
Y creamos un constructor para nuestra clase, el cual será usado cada vez que instanciemos nuestra clase, a este constructor se me ocurrió pasarle como parámetros cuatro variables de tipo int, que le daran posición y tamaño al label que contiene nuestro reloj, para que sea todo con la menor cantidad de código posible, cuando instanciemos nuestra clase reloj en un jFrame (x Ej.) sólo debemos pasarle los valores de Posición espacial y tamaño (como si hicieramos jLabel.setBounds( x,y,ancho,altura) ; ).
En este mismo constructor iniciamos el hilo de ejecución y damos tamaño al reloj con nuestros parámetros:
==================================
import javax.swing.JLabel;
public class Reloj extends JLabel implements Runnable{
private String dia, mes, año, hora, minutos, segundos;
private Calendar calendario = new GregorianCalendar();
Thread hilo;
public Reloj( int x, int y, int p, int p1) { //Constructor
setBounds(x, y, p, p1);
hilo = new Thread(this);
hilo.start();
} //fin constructor
public void run( ){
}
}// fin clase Reloj
==================================
Antes de sobreescribir nuestro método run (donde sucede la acción de nuestra clase, creamos un método de tipo void (sin retorno) que se me ocurre ponerle de nombre "actualiza", en dicho método setearemos constantemente la fecha y la hora a las actuales.
La clase Calendar de java nos devuelve los datos en forma de variables int con métodos como:
int hora = calendario.get( Calendar.HOUR_OF_DAY ) ;
Pero como también devuelve el formato de hora militar (x Ej para las 7 de la tarde 19), si la hora es x Ej las dos de la mañana con 7 minutos y 4 segundos obtenemos: "2,7,4" lo que no queda muy bonito para un reloj, x lo que le agregamos con un condicional que si los minutos y/o segundos son menores a 10 le agregue un "0" adelante.
En este caso por una cuestión de usar el menor código posible (ya lo dijo un profesor mio: "menos código, menos probabilidad de errores" ) , usaremos el condicional ternario, que es como un if pero mas sencillo...
===============================================================================
public void actualiza() {
Date fechaHoraActual = new Date();
calendario.setTime(fechaHoraActual);
hora = String.valueOf(calendario.get(Calendar.HOUR_OF_DAY));
minutos = calendario.get(Calendar.MINUTE) > 9 ? "" + calendario.get(Calendar.MINUTE) : "0" + calendario.get(Calendar.MINUTE);
segundos = calendario.get(Calendar.SECOND) > 9 ? "" + calendario.get(Calendar.SECOND) : "0" + calendario.get(Calendar.SECOND);
dia = calendario.get(Calendar.DATE) > 9 ? "" + calendario.get(Calendar.DATE) : "0" + calendario.get(Calendar.DATE);
mes = calendario.get(Calendar.MONTH) > 9 ? "" + calendario.get(Calendar.MONTH) : "0" + calendario.get(Calendar.MONTH);
año = calendario.get(Calendar.YEAR) > 9 ? "" + calendario.get(Calendar.YEAR) : "0" + calendario.get(Calendar.YEAR);
}
===============================================================================
Y ahora si podemos comenzar a sobreescribir el método run que hara que suceda la "magia":
En este método lo único que hacemos es corregir el mes, que si x Ej. es enero, java devuelve "0", entonces le sumamos uno con otra variable, mostramos los datos en nuestra clase (que no es ni mas ni menos que un JLabel personalizado) y hacemos una pausa de un segundo para la actualización la que arroja una excepción de tipo "InterruptedException" que debe ser capturada con try-catch:
Notarán que para mostrar los datos uso el formato "<html>", esto lo hice para poder hacer un salto de linea y mostrar la fecha y la hora en lineas distintas, cuando instancien la clase y le den tamaño y/o cambien el tamaño de la letra deben pasarle los parametros adecuados.
Todo dentro de un while que compara a este hilo con uno que es igual a el mismo, (nunca será falso...?)...
Insisto Uds. son libres de modificar esta clase a su gusto y/o necesidades
===============================================================================
public void run() {
Thread ct = Thread.currentThread();
while (ct == hilo) {
try {
actualiza();
int mesE;
mesE = Integer.valueOf(mes) + 1;
setText("<html><center>" + dia + " / " + mesE + " / " + año + "<br>" + hora + ":" + minutos + ":" + segundos);
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
}
}
===============================================================================
Y está pronto, nuestra clase debería verse así:
===============================================================================
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.swing.JLabel;
public class Reloj extends JLabel implements Runnable {
private String dia, mes, año, hora, minutos, segundos;
private Calendar calendario = new GregorianCalendar();
Thread hilo;
public Reloj( int x, int y, int p, int p1) { //Constructor
setBounds(x, y, p, p1);
hilo = new Thread(this);
hilo.start();
} //fin constructor
@ Override
public void run() {
Thread ct = Thread.currentThread();
while (ct == hilo) {
try {
actualiza();
int mesE;
mesE = Integer.valueOf(mes) + 1;
setText("<html><center>" + dia + " / " + mesE + " / " + año + "<br>" + hora + ":" + minutos + ":" + segundos);
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
}
}
public void actualiza() {
Date fechaHoraActual = new Date();
calendario.setTime(fechaHoraActual);
hora = String.valueOf(calendario.get(Calendar.HOUR_OF_DAY));
minutos = calendario.get(Calendar.MINUTE) > 9 ? "" + calendario.get(Calendar.MINUTE) : "0" + calendario.get(Calendar.MINUTE);
segundos = calendario.get(Calendar.SECOND) > 9 ? "" + calendario.get(Calendar.SECOND) : "0" + calendario.get(Calendar.SECOND);
dia = calendario.get(Calendar.DATE) > 9 ? "" + calendario.get(Calendar.DATE) : "0" + calendario.get(Calendar.DATE);
mes = calendario.get(Calendar.MONTH) > 9 ? "" + calendario.get(Calendar.MONTH) : "0" + calendario.get(Calendar.MONTH);
año = calendario.get(Calendar.YEAR) > 9 ? "" + calendario.get(Calendar.YEAR) : "0" + calendario.get(Calendar.YEAR);
}
}
===============================================================================
Bueno, está todo pronto, solo debemos agregar nuestro reloj a alguna ventana, x ejemplo un JFrame:
El jFrame cada uno lo crea a su manera, x código o con el asistente de creación de GUI de NetBeans, yo creé uno básico sólo como ejemplo:
=================================================================================
import javax.swing.JFrame;
public class Frame{
public static void creaFrame() {//Metodo que agrega un muestra un Frame con reloj incluido
Reloj reloj = new Reloj(0, 0, 0, 0);//Instancia de nuestra clase Reloj
//(0,0,0,0 ya que el layout es x defecto)
//Sino aquí es donde dan locación y tamaño
reloj.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);//Centrado del texto
reloj.setFont(new java.awt.Font("Arial", 1, 18));//tipo de letra y tamaño
JFrame ventana = new JFrame();//Instancia de la clase JFrame
ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//Botón de cerrar
ventana.setBounds(0, 0, 200, 100);//Tamaño
ventana.getContentPane().add(reloj);//Agregado del reloj
ventana.setLocationRelativeTo(null);//Lo centramos en la pantalla
ventana.setVisible(true);//Lo hacemos visible
}
public static void main(String[] args) {
creaFrame();//Llamada al método que muestra un jFrame
}
}
===========================================================================
Aquí el video del resultado con el código tal cual está en este post:
Otros posts propios sobre el tema que pueden interesarte:
Gracias x la visita, como siempre puntos, dudas, comentarios o sugerencias bienvenidos!!!