JLabel - Contador

13 respostas
MaTToS

Olá pessoal,

Estou aprendendo Java a pouco tempo, estou com uma dificuldade para implementar uma contador em um aplicativo.
Gostaria que o JLabel fosse acrescentando de um a um o numero de meu contador, estou colocando o metodo settext() mas o JLabel só acrescenta o ultimo numero de meu contador, gostaria que fosse setando de um a um.

segue um exemplo de como estou fazendo o código:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { for(int i=0;i<1000;i++){ String cont = String.valueOf(i); jLabel1.setText(cont); } }

Obrigado galera!

13 Respostas

MaTToS

pesquisei e descobri que em outras liguagens exemplo C# existe o metodo refresh(), mas em Java não encontrei nada parecido, sei que tem que usar threads mas como sou iniciante ainda não consegui resolver meu problema!

valeu galera!

fabiofalci

Olha esse exemplinho usando Timer

public class TimerTest3 extends JPanel {
	JLabel label;
	Timer timer;
	int current = 0;

	public TimerTest3() {
		this.add(this.getLabel());
		this.go();
	}

	public JLabel getLabel() {
		if (this.label == null) {
			this.label = new JLabel(this.current + "");
			this.label.setPreferredSize(new Dimension(100, 22));
		}
		return this.label;
	}

	public void go() {
		ActionListener action = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				label.setText(++current + "");
			}
		};
		this.timer = new Timer(1000, action);
		this.timer.start();
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setContentPane(new TimerTest3());
		frame.setSize(200, 75);
		frame.setVisible(true);
	}
}
MaTToS

Esse exemplo eu até ja usei pra tentar entender, mas como sou iniciante estou ainda com dificuldade, gostaria de saber um codigo mais simples estilo o exemplo que passei para que possa entender os simples e depois os mais complexos.

Valeu Fabio agradeço pela ajuda!

Abrass!!!

T

MaTToS:
pesquisei e descobri que em outras liguagens exemplo C# existe o metodo refresh(), mas em Java não encontrei nada parecido, sei que tem que usar threads mas como sou iniciante ainda não consegui resolver meu problema!
valeu galera!

O Java funciona assim e acabou; não há uma “maneira mais simples” para fazer isso que você precisa. Isso foi feito dessa maneira por motivos de desempenho. (A rigor, há gente que usa o método “updateUI”, mas ele é muito exagerado e repinta coisas demais, deixando seu programa super-lento e porco; já vi muito código porco e sujo que usa direto “updateUI”, porque a pessoa estava acostumada a usar DoEvents do VB 3.0 para poder atualizar a tela.)

fabiofalci

editado: falei besteira… é isso, o thingol falou tudo.

MaTToS

Desculpa Fabio realmente faltou o sleep ali no código, o que eu tenho aqui implementado esta com o sleep de 1 segundo também, mas mesmo assim ainda ele só seta o ultimo valor do contador no JLabel.

valeu cara!

Abrass!

ViniGodoy

O problema é o seguinte.

O Swing tem uma fila de eventos. Nessa fila ele faz o seguinte:

a) Desenha a tela (processando eventos de repaint);

b) Processa os eventos de clique do mouse, teclado e outros inputs;

c) Dispara os eventos de componente

d) Volta para a).

Seu evento te botão está no caso c). Você faz todas as atualizações, mantendo o passo c bloqueado. Essas atualizações são feitas nas propriedades locais do componente, ou seja, na memória. Ainda não houve reflexo na parte visual. Ao final, quando seu último label foi setado, o swing prossegue, só indo pintar a tela novamente no passo a). Note que não adianta colocar sleeps no seu for, pois isso só deixará a aplicação com a aparência de “congelada”.

Como solucionar esse problema? O passo C deve disparar outra thread, que alterá a label, sem bloquear a execução do swing. É o que a solução do colega faz, usando para isso a thread criada pela classe timer.

Nesse post, e nos dois depois dessa, tem 3 forma de se fazer isso (com threads, java.util.Timer e javax.swing.Timer):
http://www.guj.com.br/posts/list/52964.java#279083

O exemplo funciona, você pode copiar e colar no seu Eclipse ou Netbeans. O código está muito comentado.

É por isso que, quando você está trabalhando com Swing, deve disparar eventos longos em outra thread. Caso contrário seu programa parecerá congelado. Como a aplicação ficaria parada no passo c) sem outra thread, o swing não a repintaria até que o processamento termine.

MaTToS

Muito obrigado ViniGodoy, agradeço pela explicação, me ajudou muito a entender o processo como um todo. Irei verificar os topicos e tentar implementar em meu código, se der certo posto novamente aqui.

Obrigado!

Abrass!

fabiofalci

Aqui tem material de apoio para entender essa parte do swing
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html

MaTToS

Obrigado Fabio pela ajuda!

MaTToS

Boa tarde pessoal,

Agradeço a ajuda de todos, consegui compreender o sistema de THREADS e implementei em meu código.

Segue o código:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { Thread tThread = new Thread(new Runnable() { public void run() { try { for(int i=0;i<=100;i++){ jLabel1.setText(i+""); Thread.sleep(100); } } catch (InterruptedException ex) {} } }); tThread.start(); }

ViniGodoy

Se não vai usar tThread depois, pode ainda fazer:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { new Thread(new Runnable() { public void run() { try { for(int i=0;i&lt;=100;i++){ jLabel1.setText(i+&quot;&quot;); Thread.sleep(100); } } catch (InterruptedException ex) {} } }).start(); }

MaTToS

Valeu pela dica!!

Criado 14 de julho de 2009
Ultima resposta 15 de jul. de 2009
Respostas 13
Participantes 4