[Resolvido] Timer regressivo, como implementar?

9 respostas
Bruno_M_Gasparotto

Boa noite,

Preciso implementar um timer que receba um valor de uma outra variável, e comece uma contagem regressiva em cima desse valor, sendo exibido na tela.

Andei fazendo uma busca no fórum e achei algo para iniciar um timer progressivo a partir do 0, mas não esse que eu preciso.

Alguem pode me ajudar?

Abraços,

9 Respostas

Rodrigo_Sasaki

ja pensou em fazer um for que vai diminuindo o valor dessa variável a cada loop?

deve haver alguma classe utilitária pra isso, mas não conheço hehehe…

a idéia básica é: public static void main(String[] args){ int segundos = 10; try{ for (int i = segundos; i > 0; i--){ System.out.println(i + " segundos"); Thread.sleep(1000); // 1 segundo } System.out.println("Terminei!"); } catch (InterruptedException e){ System.out.println("Interromperam meu sono!"); } }Sei que dizem que usar Thread.sleep() é péssimo, mas foi o jeito mais simples que encontrei pra criar um exemplo :slight_smile:

InicianteJavaHenriqu

Fiz um exemplo:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

/**
 *
 * @author Henrique Ferreira da Silva
 */
public class Cronometro {

    private Timer cronometro;
    private DateFormat formato = new SimpleDateFormat("HH:mm:ss");
    private Calendar calendario = Calendar.getInstance();
    private final byte contagem;
    public static final byte PROGRESSIVA = 1;
    public static final byte REGRESSIVA = -1;

    public Cronometro(int ano, int mes, int dia, int horas, int minutos, int segundos, byte tipoContagem) {
        this.cronometro = new Timer();
        calendario.set(ano, mes, dia, horas, minutos, segundos);
        this.contagem = tipoContagem;
    }

    public void cronometro() {
        TimerTask tarefa = new TimerTask() {

            @Override
            public void run() {
                System.out.println(getTime());
            }
        };
        cronometro.scheduleAtFixedRate(tarefa, 0, 1000);
        this.cronometro = null;
    }

    public String getTime() {
        calendario.add(Calendar.SECOND, contagem);
        return formato.format(calendario.getTime());
    }

    public static void main(String[] args) {
        Cronometro contagem = new Cronometro(0, 0, 0, 10, 30, 5, REGRESSIVA);
        contagem.cronometro();
    }
}

Note que no construtor da classe você pode passar como parâmetro: o ano, mês, dia, horas, minutos e segundos para iniciar o timer e ainda escolher se deseja contagem regressiva ou progressiva.

No exemplo, o cronometro inicia em 10 horas, 30 minutos e 5 segundos.

:thumbup:

ByIvo

segue solução

ByIvo

Amigo, esses dois códigos acima funcionam, mas pelo que eu entendi da sua necessidade, esse timer terá de roda em paralelo com uma outra aplicação certo?

O melhor é criar uma Thread.

Observe o código:
Talvez tenha algum erro de sintaxe, mas basicamente é isso:

class Timer {


  public static void main(String[] argumentos){
    // instancia uma thread, passando como construtor uma implementação de runnable.
    //runnable é uma interface, que implementa o metodo run, quando a thread é statada(.start();), o método run() é executado.
    // o parâmetro do construtor da classe ExecucaoDoThread é o número que vai ser decrescido até 0
    Thread t = new Thread(new ExecucaoDoThread(10));
    t.start();
  }




  class ExecucaoDoThread implements Runnable{
    
    private int num;      

    public ExecucaoDoThread(int num){
      //o num vai receber o numero que vai ser descrescido até 0;
      this.num = num;
    }
    
    @Override
    public void run(){
      //aqui vai o código que será executado pela thread
      //cria um jframe e seta seu tamanho
      JFrame frame = new JFrame();
      frame.setSize(200,200);

      //cria uma jlabel, adiciona no frame e chama o metodo do, passando essa label como parametro
      JLabel label = new JLabel();
      frame.add(label);
      go(label);
    }

    public void go(JLabel label){
      //faz um for que vai de num até 0, no passo -1.
      //cada loop do for, troca o valor do label por i, e espera 1 segundo ( utilizando o metodo static Thread.sleep(); e passando o tempo em millis que deverá aguardar
      for(int i = num;i>=0;i--){
        try{
          label.setText(i+"");
          Thread.sleep(1000);
        }catch(Exception ex){}
      }
    }

  }


}

Acho que vai funcionar…
qualquer dúvida, procure tutoriais sobre Threads ou me mande uma mensagem que eu volto a explicar.

Bruno_M_Gasparotto

digaoneves:
ja pensou em fazer um for que vai diminuindo o valor dessa variável a cada loop?

deve haver alguma classe utilitária pra isso, mas não conheço hehehe…

a idéia básica é: public static void main(String[] args){ int segundos = 10; try{ for (int i = segundos; i > 0; i--){ System.out.println(i + " segundos"); Thread.sleep(1000); // 1 segundo } System.out.println("Terminei!"); } catch (InterruptedException e){ System.out.println("Interromperam meu sono!"); } }Sei que dizem que usar Thread.sleep() é péssimo, mas foi o jeito mais simples que encontrei pra criar um exemplo :)

ByIvo:
Amigo, esses dois códigos acima funcionam, mas pelo que eu entendi da sua necessidade, esse timer terá de roda em paralelo com uma outra aplicação certo?

O melhor é criar uma Thread.

Observe o código:
Talvez tenha algum erro de sintaxe, mas basicamente é isso:

class Timer {


  public static void main(String[] argumentos){
    // instancia uma thread, passando como construtor uma implementação de runnable.
    //runnable é uma interface, que implementa o metodo run, quando a thread é statada(.start();), o método run() é executado.
    // o parâmetro do construtor da classe ExecucaoDoThread é o número que vai ser decrescido até 0
    Thread t = new Thread(new ExecucaoDoThread(10));
    t.start();
  }




  class ExecucaoDoThread implements Runnable{
    
    private int num;      

    public ExecucaoDoThread(int num){
      //o num vai receber o numero que vai ser descrescido até 0;
      this.num = num;
    }
    
    @Override
    public void run(){
      //aqui vai o código que será executado pela thread
      //cria um jframe e seta seu tamanho
      JFrame frame = new JFrame();
      frame.setSize(200,200);

      //cria uma jlabel, adiciona no frame e chama o metodo do, passando essa label como parametro
      JLabel label = new JLabel();
      frame.add(label);
      go(label);
    }

    public void go(JLabel label){
      //faz um for que vai de num até 0, no passo -1.
      //cada loop do for, troca o valor do label por i, e espera 1 segundo ( utilizando o metodo static Thread.sleep(); e passando o tempo em millis que deverá aguardar
      for(int i = num;i>=0;i--){
        try{
          label.setText(i+"");
          Thread.sleep(1000);
        }catch(Exception ex){}
      }
    }

  }


}

Acho que vai funcionar…
qualquer dúvida, procure tutoriais sobre Threads ou me mande uma mensagem que eu volto a explicar.

Então, esse timer roda em paralelo sim, é uma tabela com diversas linhas, onde cada uma levará um contador próprio, e um dos horários para esse cálculo será o horário atual.

Estava verificando essa solução utilizando threads, porém não seria até mais seguro utilizar um servidor que seta o relógios dos computadores (para o usuário não mexer) e usar o horário do pc como base pra cada cálculo?

Bruno_M_Gasparotto

InicianteJavaHenrique:
Fiz um exemplo:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

/**
 *
 * @author Henrique Ferreira da Silva
 */
public class Cronometro {

    private Timer cronometro;
    private DateFormat formato = new SimpleDateFormat("HH:mm:ss");
    private Calendar calendario = Calendar.getInstance();
    private final byte contagem;
    public static final byte PROGRESSIVA = 1;
    public static final byte REGRESSIVA = -1;

    public Cronometro(int ano, int mes, int dia, int horas, int minutos, int segundos, byte tipoContagem) {
        this.cronometro = new Timer();
        calendario.set(ano, mes, dia, horas, minutos, segundos);
        this.contagem = tipoContagem;
    }

    public void cronometro() {
        TimerTask tarefa = new TimerTask() {

            @Override
            public void run() {
                System.out.println(getTime());
            }
        };
        cronometro.scheduleAtFixedRate(tarefa, 0, 1000);
        this.cronometro = null;
    }

    public String getTime() {
        calendario.add(Calendar.SECOND, contagem);
        return formato.format(calendario.getTime());
    }

    public static void main(String[] args) {
        Cronometro contagem = new Cronometro(0, 0, 0, 10, 30, 5, REGRESSIVA);
        contagem.cronometro();
    }
}

Note que no construtor da classe você pode passar como parâmetro: o ano, mês, dia, horas, minutos e segundos para iniciar o timer e ainda escolher se deseja contagem regressiva ou progressiva.

No exemplo, o cronometro inicia em 10 horas, 30 minutos e 5 segundos.

:thumbup:

neste caso:

ele recebe data/hora do sistema como se fosse um Date data = new Date(); ?

Agradeço a resposta de todos e desculpem a demora para responder, me enrolei no resto do dia e fiquei sem acesso ao pc em casa.

ByIvo

pois é, Calendar cal = Calendar.getInstance(); e Date dat = new Date() pegam a hora do sistema do usuario.

você poderia criar um metodo no lado servidor:

tipo:

public Calendar(ou Date) getHoraAtual(){

return Calendar.getInstance() ou new Date();

}

Vc pode escolher qual usar :slight_smile:

Bruno_M_Gasparotto

agora entendi, pena que não vou poder testar agora, to envolvido com outra etapa do processo que é bem mais urgente, mas logo mais dou um feedback aqui de como foi implementado.

Valeu mesmo a ajuda :slight_smile:

Bruno_M_Gasparotto

Consegui implementar o que eu queria, usando Timer e TimerTask, só acho que preciso dar uma melhorada na passagem de parâmetro pro construtor.

Espero que funcione, pois na aplicação que possui o método main eu soh preciso instanciar e chamar o método calculaTempo().

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
  
/** 
* 
* @author NBruno 
*/  
public class TimerAcompanhamento { 
    private Timer cronometro = new Timer();
    
    private Calendar horarioAtual;
    private Calendar horarioLimite;
    private Calendar horarioInicial;
        
    TimerAcompanhamento(int ano, int mes, int dia, int hora, int minuto, int segundo) {
        
        horarioInicial = Calendar.getInstance();
        horarioInicial.set(ano, mes, dia, hora, minuto, segundo);
        System.out.println("Hora Inicial: " + horarioInicial.getTime());
        
        horarioLimite = Calendar.getInstance();
        horarioLimite.set(ano, mes, dia, hora, minuto, segundo);
        horarioLimite.add(Calendar.HOUR, 20);
        System.out.println("Hora Limite: " + horarioLimite.getTime());

    }
  
    private String getTempo(long minutos){   
        return String.format ("%02d:%02d", (minutos / 60), (minutos % 60));   
    }
    
    public void calculaTempo() {  
        TimerTask tarefa = new TimerTask() {  
  
            @Override  
            public void run() {
                horarioAtual = Calendar.getInstance();
                
                if (horarioAtual.getTimeInMillis() < horarioLimite.getTimeInMillis()) {
                    long milisegundoRestante = horarioLimite.getTimeInMillis() - horarioAtual.getTimeInMillis();
                    long minutoRestante = (long)milisegundoRestante/60000;
                    System.out.println("Hora Restante: " + getTempo(minutoRestante));
                } else {
                    long milisegundoExcedido = horarioAtual.getTimeInMillis() - horarioLimite.getTimeInMillis();
                    long minutoExcedido = (long)milisegundoExcedido/60000;
                    System.out.println("Tempo Excedido: " + getTempo(minutoExcedido));
                }
            }  
        };  
        cronometro.scheduleAtFixedRate(tarefa, 0, 1000);  
        this.cronometro = null;
    } 
}

Agradeço a ajuda de todos, pra variar :)

Criado 26 de abril de 2012
Ultima resposta 1 de mai. de 2012
Respostas 9
Participantes 4