Dúvida sobre como utilizar Thread.[RESOLVIDO]

Seguinte pessoal, dúvida de iniciante.
Eu tava fazendo uma GUI no NetBeans e gostaria de ter uma label que mostrasse a hora e ficasse atualizando todo tempo. Utilizei uma Thread pra isso. Porém minha label criada (labelHora) para mostrar a hora não atualiza e não consegui entender o porquê. Quem puder me ajuda!
Ah, e só pra esclarecer: como vocês podem ver eu utilizei a mesma variável também para mostrar a data atual.

Date hoje = new Date(); public TelaPrincipal() { initComponents(); labelData.setText(String.format("%ta, %<td de %<tb de 20%<ty", hoje)); labelHora.setText(String.format("%tr", hoje)); timer1.start(); } private void timer1OnTime(java.awt.event.ActionEvent evt) { labelHora.setText(String.format("%tr", hoje)); }

Aqui nesse post tem o jeito certo de fazer isso com threads:
http://www.guj.com.br/posts/list/52964.java#279083

E nos dois depois dele tem outras 2 maneiras mais fáceis.

Olá Reginildo

Não sei como vc inplementou a Thread. Já quebrei a kbça com este tipo de problema e resolvi da seguinte forma.

Classe interna.
Lembrando que o JLabel jlbHora esta criado na classe principal.

private class Hora extends JFrame implements Runnable {

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private boolean starty = true;

		public Hora() {
		}

		public void run() {
                        Calendar myData = Calendar.getInstance();
                        Locale loc = new Locale("pt","BR");
                        DateFormat formData =DateFormat.getDateInstance(DateFormat.FULL, loc);
                        jlbData.setText(formData.format(myData.getTime()));
			while (starty) {
				try {
					Calendar myHora = Calendar.getInstance();
					SimpleDateFormat form = new SimpleDateFormat("hh:mm:ss");
					jlbHora.setText(form.format(myHora.getTime()));
					Thread.sleep(1000);
				} catch (Exception e) {
					e.printStackTrace();
					starty = false;
				}
			}
		}
	}
---------------------------------------------------------------------------------------------------------
Main da classe principal
public static void main(String[] args) {
		JControleView exe = new JControleView();
		exe.mostraTela();
		Hora hora = exe.new Hora();
		Thread principal = new Thread(hora);
		principal.start();
	}

Espero ter ajudado

Diego, clique em editar no seu post aí em cima e segue essas dicas:
http://www.guj.com.br/posts/list/50115.java

Sem a formatação do código, fica difícil entender o que você escreveu.

//Não sei como vc inplementou a Thread. Já quebrei a kbça com este tipo de problema e resolvi da seguinte forma.

//Classe interna.
//Lembrando que o JLabel jlbHora esta criado na classe principal.
private class Hora extends JFrame implements Runnable {

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private boolean starty = true;

		public Hora() {
		}

		public void run() {
                        Calendar myData = Calendar.getInstance();
                        Locale loc = new Locale("pt","BR");
                        DateFormat formData =DateFormat.getDateInstance(DateFormat.FULL, loc);
                        jlbData.setText(formData.format(myData.getTime()));
			while (starty) {
				try {
					Calendar myHora = Calendar.getInstance();
					SimpleDateFormat form = new SimpleDateFormat("hh:mm:ss");
					jlbHora.setText(form.format(myHora.getTime()));
					Thread.sleep(1000);
				} catch (Exception e) {
					e.printStackTrace();
					starty = false;
				}
			}
		}
	}
//---------------------------------------------------------------------------------------------------------
//Main da classe principal
public static void main(String[] args) {
		JControleView exe = new JControleView();
		exe.mostraTela();
		Hora hora = exe.new Hora();
		Thread principal = new Thread(hora);
		principal.start();
	}

Valeu pela dica

Opa ViniGodoy. Eu testei os códigos do post que você me enviou. Funcionou sim, porém em certas partes achei um pouco confuso para um objetivo aparentemente simples. Então tentei algo um pouquinho diferente aqui:

[code]public TelaPrincipal() {
initComponents();
labelData.setText(String.format("%ta, %<td de %<tb de 20%<ty", new Date()));
timer1.start();//quando inicio essa classe que extende JFrame também inicio o Timer.
}

private void timer1OnTime(java.awt.event.ActionEvent evt) {
/só formatei a hora e usei essa variável para chamar o método format/
DateFormat formatoHora = new SimpleDateFormat(“HH:mm:ss”);
labelHora.setText(formatoHora.format(new Date()));
}
[/code]
Consegui algo simples e acredito que está tudo certo, pois minha aplicação não deu nada de errado. Não sei se devo chamar o método sleep() para poupar o processador para outras coisas. Enfim é isso.
Ah, outra coisa.
Tentei fazer isso sem o uso de threads e resultou nesse código abaixo aí pra quem tiver interesse.

[code]import java.awt.BorderLayout;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class TesteThreads2 {
JLabel label;

public static void main(String[] args) {
	new TesteThreads2().run();
}

public void run() {

	JFrame frame = new JFrame("---- Hora Certa ----");
	label = new JLabel();

	frame.getContentPane().add(BorderLayout.CENTER, label);
	frame.setSize(260, 120);
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setVisible(true);

	while (true) {
		DateFormat formato = new SimpleDateFormat("HH:mm:ss");
		label.setText(formato.format(new Date()));			
	}
}

}
[/code][code]

[quote=Reginildo]Opa ViniGodoy. Eu testei os códigos do post que você me enviou. Funcionou sim, porém em certas partes achei um pouco confuso para um objetivo aparentemente simples. Então tentei algo um pouquinho diferente aqui:

[code]public TelaPrincipal() {
initComponents();
labelData.setText(String.format("%ta, %<td de %<tb de 20%<ty", new Date()));
timer1.start();//quando inicio essa classe que extende JFrame também inicio o Timer.
}

private void timer1OnTime(java.awt.event.ActionEvent evt) {
/só formatei a hora e usei essa variável para chamar o método format/
DateFormat formatoHora = new SimpleDateFormat(“HH:mm:ss”);
labelHora.setText(formatoHora.format(new Date()));
}
[/code]
Consegui algo simples e acredito que está tudo certo, pois minha aplicação não deu nada de errado. Não sei se devo chamar o método sleep() para poupar o processador para outras coisas. Enfim é isso.
Ah, outra coisa.
Tentei fazer isso sem o uso de threads e resultou nesse código abaixo aí pra quem tiver interesse.

[code]import java.awt.BorderLayout;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class TesteThreads2 {
JLabel label;

public static void main(String[] args) {
	new TesteThreads2().run();
}

public void run() {

	JFrame frame = new JFrame("---- Hora Certa ----");
	label = new JLabel();

	frame.getContentPane().add(BorderLayout.CENTER, label);
	frame.setSize(260, 120);
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setVisible(true);

	while (true) {
		DateFormat formato = new SimpleDateFormat("HH:mm:ss");
		label.setText(formato.format(new Date()));			
	}
}

}
[/code][code][/quote]

O problema dessa abordagem é que você está sobrecarregando o GC, dentro de um laço infinito você cria diversos objetos sem necessidade nenhuma. Mesmo eles sendo alocados no espaço de objetos jovens, ainda assim eles representam um custo considerável de memória e processamento. É uma solução? É. É mais simples? sim. É uma boa solução? NÃO.

Eu já suspeitava disso. Utilizarei outra abordagem. Valeu pelas explicações! =)

Outra coisa. Conforme expliquei no outro post, você não pode alterar componente do Swing usando outra thread. Por isso a necessidade do uso do EventQueue.invokeLater.

Essa é uma regra da API, e resultados inesperados podem acontecer caso você não siga. A abordagem mais simples de todas é a terceira, que usei no post, usando o timer do próprio Swing. Isso pq ele já dispara seus eventos na própria Thread do Swing e não na do timer.

Tome cuidado, abordagens “mais simples” nem sempre são corretas. Quando olhar código, procure entender o que ele faz e as explicações adicionais, principalmente no quesito threads, pois um erro pode ser extremamente complexo de reproduzir e debugar, e provavelmente só ocorrerá no seu cliente, que usa o sistema muito mais que você mesmo.

E sim, é bom chamar sleep, ou seu processador irá a 100% de CPU.