Creé un reloj mundial usando Java Swing. El reloj en sí no es muy complejo. La razón por la que hice este miniproyecto fue para ver si podía personalizar las zonas horarias.
Aquí está la GUI con las zonas horarias predeterminadas.
Aquí está el JDialog
que muestra las distintas zonas horarias del mundo.
Puede seleccionar tantas zonas horarias como desee, aunque sugeriría que 10 zonas horarias sea el límite práctico para la mayoría de las pantallas actuales.
Thw JDialog
le permite mover zonas horarias de la lista principal a la lista de visualización, y de la lista de visualización a la lista principal. Puede borrar todas las zonas horarias mostradas si desea comenzar de nuevo. Debe seleccionar al menos una zona horaria para mostrar,
La lista primaria permanece en orden alfabético. La lista de visualización muestra las zonas horarias en el orden en que las selecciona. Mantener presionada la tecla Ctrl
mientras hace clic con el botón izquierdo del mouse le permite seleccionar múltiples zonas horarias para agregarlas o eliminarlas de las listas.
Este código no guarda las zonas horarias que seleccione en un archivo de propiedades. Esto es algo que se puede agregar si desea utilizar este reloj mundial como un archivo JAR ejecutable.
Oracle tiene un tutorial útil, Creación de una GUI con Swing. Omita la sección Learning Swing con NetBeans IDE.
Cuando creo una aplicación Swing, uso el patrón modelo-vista-controlador (MVC). Este patrón me permite separar mis preocupaciones y concentrarme en una parte de la aplicación Swing a la vez. El nombre del patrón implica que primero se crea el modelo, luego la vista y finalmente el controlador. Este es un proceso iterativo, por lo que los cambios en la vista o el controlador pueden provocar cambios en el modelo.
Para una aplicación Swing, el patrón MVC significa:
La vista lee información del modelo.
La vista no actualiza el modelo.
El controlador actualiza el modelo y repinta/revalida la vista.
Por lo general, no hay un controlador que "los gobierne a todos". Cada Action
o ActionListener
actúa de forma independiente y actualiza su parte del modelo y vista.
Creé una clase de modelo, la clase WorldClockModel
. Esta clase contiene una fecha y hora actuales ZonedDateTime
, una java.util.List
de todas las zonas horarias y una java.util.List
de las zonas horarias que se mostrarán. Elegí ZonedDateTime
para tener que almacenar la hora actual solo una vez. Puedo pasar un ZoneId
a ZonedDateTime
para obtener la hora actual en cualquier zona horaria.
La List
de todas las zonas horarias proviene del método ZoneId
getAvailableZoneIds
. Filtro las zonas horarias que no están relacionadas con la ciudad.
Creé dos clases de vista, la clase WorldClockGUI
y la clase DisplayPanel
. La clase WorldClockGUI
crea el JFrame
y el JPanel
principal. El JPanel
principal se compone de instancias DisplayPanel
, una para cada zona horaria que se mostrará.
El JFrame
tiene un BorderLayout
predeterminado, así que coloqué el JPanel
principal en el centro del BorderLayout
. El JPanel
principal utiliza un GridLayout
para colocar las instancias DisplayPanel
en dos columnas espaciadas uniformemente.
JDialog
muestra la lista de todas las zonas horarias, la lista de zonas horarias mostradas y controla JButtons
para mover zonas horarias de una lista a otra. Utilizo dos DefaultListModels
, uno para cada lista.
La clase TimezoneDialogListener
copia la lista de visualización del DefaultListModel
de visualización a la clase de modelo de aplicación y actualiza la vista.
Un Swing Timer
actualiza la hora actual cada 20 segundos. Esto es lo suficientemente preciso para un reloj que muestra horas y minutos.
El resto de los JButtons
en JDialog
activan ActionListeners
anónimos para realizar sus tareas. Los oyentes son pocos, por lo que tenía sentido darles clases anónimas.