JLabel - Contador

13 respostas
M

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

M

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!

F

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);
	}
}
M

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.)

F

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

M

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!

V

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.

M

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!

F

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

M

Obrigado Fabio pela ajuda!

M

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(); }

V

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(); }

M

Valeu pela dica!!

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