javax.swing.jframe setText () en un bucle? + retraso intencional?
-
22-10-2019 - |
Pregunta
Soy muy nuevo en Java (solo lo ha estado usando durante aproximadamente una semana) y estoy trabajando en un simulador de la tienda. Básicamente, solo quiero hacer cosas básicas en este momento, como tener un tiempo hasta el cierre y un tiempo desde que se muestra la variable de apertura en la pantalla.
He realizado las siguientes funciones en mi simulación se extiende javax.swing.jframe clase:
public void incOpenTime() {
timeOpen++;
int hours = timeOpen / 3600;
int minutes = (timeOpen % 3600) / 60;
int seconds = (timeOpen % 3600) % 60;
this.openTime.setText((hours < 10 ? "0" : "") + hours
+ ":" + (minutes < 10 ? "0" : "") + minutes
+ ":" + (seconds < 10 ? "0" : "") + seconds);
decTimeLeft();
}
public void decTimeLeft() {
int remainingTime = 28800 - timeOpen;
int hours = remainingTime / 3600;
int minutes = (remainingTime % 3600) / 60;
int seconds = (remainingTime % 3600) % 60;
this.timeLeft.setText((hours < 10 ? "0" : "") + hours
+ ":" + (minutes < 10 ? "0" : "") + minutes
+ ":" + (seconds < 10 ? "0" : "") + seconds);
}
Las variables OpenTime y Timeleft utilizando el método setText () son parte de la propia GUI.
En Main, llamo Incopentime así:
while(this.timeOpen < 28800)
{
incOpenTime();
}
En primer lugar, cuando ejecuto esto básicamente pasa por el bucle y sale solo la última vez a la pantalla. ¿Cómo lo haría para que los tiempos cambien constantemente?
En segundo lugar, me gustaría retrasarlo ligeramente ... tal vez aproximadamente 1 m por segundo, por lo que la simulación se ejecuta más lento y otros datos que se emiten a la pantalla (más tarde) es más legible. He probado hilo.sleep (1); en el bucle pero no muestra los números a medida que se cambian.
Por favor ayuda.
Gracias
EDITAR:
Esto es lo que hice para que funcionara. En Main:
timer = new Timer();
for(int i=1; i<= 28800; i++)
{
timer.schedule(new task(), 1*i);
}
Hizo una nueva clase:
class task extends TimerTask {
@Override
public void run() {
incOpenTime();
}
}
Solución
Tu necesitas un java.util.Timer
Editar: Como esta es la respuesta aceptada, es importante tener en cuenta que el TimerTask
Debería ejecutar su Runnable
en el hilo de despacho del evento. La variación correcta de esto Acercarse se observa en @mkorbel's responder. Hay un breve ejemplo a continuación y uno más elaborado aquí. Se ve un enfoque algo más simple, sugerido por @Hovercraft aquí.
class Task extends TimerTask {
@Override
public void run() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
incOpenTime();
}
});
}
}
Otros consejos
javax.swing.Timer
puede ser una buena opción, como "los controladores de eventos de acción para Timers
Ejecutar en ... el hilo de disco de eventos. "Hay un ejemplo aquí.
Su salida de la tarea o el hilo de Backgroung a la GUI no se publica correctamente en el EDT,
tiene que envolver cualquiera de la salida a la GUI (desde la tarea o el hilo de Backgroung) hasta el
invokeLater()
Si el método podría ser sincronizado, entonces
invokeAndWait()
Por favor lea más sobre Concurencia en el swing