Setar um contador de segundos em um jTextField

Olá a todos. Sou novo nesta comunidade e sou novo também em programação, estou aprendendo por conta própria a programar e esta sendo uma tarefa árdua. Estou tentando setar um contador regressivo de 5 segundos em um jTextField e não estou conseguindo, ele roda no programa principal, porém não no gráfico, desde já agradeço a atenção:

Esta é a classe que crie o contador, coloquei apenas o método principal:

public void setStart(boolean start) {
        this.start = start;
        segundos=5;
        while(this.getStart()==true){
        try{Thread.sleep(1000);} catch (InterruptedException ex) {
              Logger.getLogger(Cronometro.class.getName()).log(Level.SEVERE, null, ex);
          }
        segundos--;
            
            //System.out.println(this.getSegundos());  
          
          if(segundos==0){
              segundos=5;
}

Abaixo é a parte gráfica onde um botão start e um jtextField, coloquei apenas o Action do botão:

private void jStartActionPerformed(java.awt.event.ActionEvent evt) {                                       
        Cronometro cr1 = new Cronometro();
        cr1.setStart(true);
        jVisor.setText(String.valueOf(cr1.getSegundos()));
        // TODO add your handling code here:

E por fim o programa principal:

public static void main(String[] args) {
       jVisible vis1 = new jVisible();
        Cronometro n1=new Cronometro();
        n1.setStart(true);
        vis1.setVisible(true);

Você está pensando ao contrário :stuck_out_tongue:

Não faz sentido você ficar perguntando pro cronometro quanto tempo passou.

Imagina o mundo real, você colocou seu despertador pra despertar amanhã cedo e foi dormir.
Numa situação saudável, sem estresse e preocupações, você não vai ficar acordando a cada minuto pra ver se já está na hora de levantar.
Você vai dormir numa boa e esperar que o despertador acorde você.

O mesmo acontece na programação orientada a objeto, você tenta modelar o problema da forma mais parecida com o mundo real.

Veja um exemplo de como fazer um campo texto ser atualizado a cada segundo:

Primeiro cria uma interface para os objetos que queiram ser notificados pelo seu cronometro:

public interface TimerListener {

	// o cronometro vai chamar este método
	public void onTimeElapsed(long millis);
}

Agora a classe que representa o cronometro em si

public class Timer {

	// objeto a ser notificado
	private final TimerListener listener;

	// quantos milisegundos é para contar
	private final long time;

	// de quantos em quantos milissegundos é pra notificar o objeto
	private final long frequence;

	// flag pra saber se está em execução
	private boolean running;

	public Timer(TimerListener listener, long time, long frequence) {
		this.listener = listener;
		this.time = time;
		this.frequence = frequence;
	}

	public void start() {
		if (running) {
			return;
		}
		running = true;
		// dispara uma Thread pra chamar o método execute
		// senão o método start vai ficar "travado" até que o timer tenha executado até o fim
		Thread thread = new Thread(new Runnable() {

			@Override
			public void run() {
				execute();
			}

		}, "Timer");
		thread.start();
	}

	public void stop() {
		running = false;
	}

	private void execute() {
		// guardar o momento de inicio, pra poder calcular quanto tempo passou
		long start = System.currentTimeMillis();

		// enquanto tiver que executar, executa
		while (running) {
			try {
				// espera o tempo configurado
				Thread.sleep(frequence);

				// agora notifica o objeto ouvinte avisando quanto tempo passou
				long elapsed = System.currentTimeMillis() - start;
				listener.onTimeElapsed(elapsed);

				// tá na hora de parar a execução?
				if (elapsed >= time) {
					// sim, então pára!
					stop();
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

E finalmente, uma telinha pra mostrar o negócio funcionando

public class Janela extends JFrame {

	public static void main(String[] args) {
		try {
			Janela janela = new Janela();
			janela.setDefaultCloseOperation(EXIT_ON_CLOSE);
			janela.setSize(new Dimension(300, 100));
			janela.setLocationRelativeTo(null);
			janela.disparaCronometro();
			janela.setVisible(true);
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}

	private JTextField campo;
	private Timer cronometro;

	public Janela() {
		super("Exemplo");
		campo = new JTextField();
		campo.setPreferredSize(new Dimension(50, 30));
		Container container = getContentPane();
		container.setLayout(new FlowLayout(FlowLayout.CENTER));
		container.add(campo);

		long tempo = 5000; // cronometro vai contar 5 segundos
		long frequencia = 1000; // e a cada 1 segundo vai notificar o objeto ouvinte
		TimerListener ouvinte = new TimerListener() {

			@Override
			public void onTimeElapsed(long millis) {
				// quando o cronometro chamar este método
				// atualiza o campo de texto com quantos segundos se passaram
				int segundos = (int) millis / 1000;
				campo.setText(String.valueOf(segundos));
			}
		};
		cronometro = new Timer(ouvinte, tempo, frequencia);
	}

	public void disparaCronometro() {
		cronometro.start();
	}
}
1 curtida

Agradeço muito pela resposta, porém terei que passar um tempo estudando sua logica. Grato pela atenção

1 curtida