Visual – JProgressBar, Thread.Sleep, SwingWorker, doInBackground, PropertyChangeListener – Java

Publicado: 9 de abril de 2014 em Java

Uma barra de progresso é um componente de uma interface gráfica de usuário usado para visualizar a progressão de uma operação de computador estendida, como um download, transferência de arquivos, ou de instalação. Às vezes, o gráfico é acompanhada por uma representação textual do progresso em um formato por cento.

JProgressBar

Um componente que exibe visualmente o progresso de alguma tarefa. À medida que a tarefa avança para a sua conclusão, a barra de progresso exibe porcentagem da tarefa de conclusão. Esse percentual é normalmente representado visualmente por um retângulo que começa vazio e gradualmente se torna cheio mostrando como a tarefa progride. Além disso, a barra de progresso pode exibir uma representação textual desse percentual.

Thread.sleep

Faz com que o segmento atual suspenda a execução por um período determinado.

SwingWorker

O SwingWorker em si é uma classe abstrata; você deve definir uma subclasse, a fim de criar um objeto SwingWorker; classes internas anônimas são muitas vezes útil para a criação de objetos.

doInBackground

O método doInBackground () é chamado nesta para executar uma tarefa simultânea as demais tarefas, e é como todas as atividades de fundo devem acontecer. Para notificar a mudança de alguma propriedade use PropertyChangeListeners. Por padrão, existem duas propriedades ligadas disponíveis: state e progress.

PropertyChangeListeners

Um evento PropertyChangeé disparado quando um objeto altera uma propriedade ligada a ele.

Processando Menssagens

Imagine uma barra de progresso que por padrão atinge um valor de 0 à 100, a principio podemos incrementar este valor no evento do clique do botão, porem a GUI sozinha não conseguirá atualizar os frames do andamento do status da barra progresso porque esta ocupada processando o contador do incremento, deste modo podemos ver o progresso vazio(0%) quando iniciar e cheio(100%) quando o contador chegar ao final, entretanto não poderemos ver o andamento desta porcentagem.  Para que possamos ver o andamento precisamos trabalhar os processos simultaneamente, em algumas linguagens de programação como o Delphi por exemplo temos o comando Application.ProcessMessages que executa este trabalho para nós. O Java possui uma classe abstrata chamada SwingWorker e podemos usa-la para executar um trabalho equivalente ao comando do Delphi para processar mensagens.

jprogressbar

JProgressBar – SwingWorker

Exemplo:

Neste exemplo usamos um contador e um temporizador para simular uma tarefa e usamos a classe abstrata SwingWorker para processar o andamento da tarefa.

Java

import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

public class BarraProgresso implements ActionListener, PropertyChangeListener
{

	// Declara componentes
	JLabel rotulo;
	JProgressBar progresso;
	JButton botao;

	public Container criaPainel()
	{
		// Cria painel
		JPanel painel = new JPanel();

		// Cria layout
		painel.setLayout(new BoxLayout(painel,BoxLayout.PAGE_AXIS));
		painel.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));

		// Cria componentes
		rotulo = new JLabel("Barra de progresso");
		progresso = new JProgressBar(0,100);
		botao = new JButton("Ok");

		// Alinha componentes
		rotulo.setAlignmentX(Component.CENTER_ALIGNMENT);
		progresso.setAlignmentX(Component.CENTER_ALIGNMENT);
		botao.setAlignmentX(Component.CENTER_ALIGNMENT);

		// Adiciona propriedade a barra de progresso
		progresso.setStringPainted(true);

		// Cria evento do botão
		botao.addActionListener(this);

		// Adiciona componentes ao painel
		painel.add(rotulo);
		painel.add(Box.createVerticalStrut(10));
		painel.add(progresso);
		painel.add(Box.createVerticalStrut(10));
		painel.add(botao);

		return painel;
	}

	// Cria classe SwingWorker para a propriedade progress
	class ProcessaMenssagem extends SwingWorker<Void, Void>
	{

		@Override
		public Void doInBackground() throws Exception {

			// Progresso inical
			setProgress(0);

			// cria contador
			for (int andamento = 0; andamento <= 100; andamento++)
			{
				// Cria um efeito de espera
				try
				{
					Thread.sleep(500);
				}
			    catch (InterruptedException e)
				{
					e.printStackTrace();
				}

				// Atualiza o contador
				setProgress(Math.min(andamento, 100));
			}

			return null;
		}

	}

	// Evento do botão
	public void actionPerformed(ActionEvent arg0)
	{

		if (arg0.getSource() == botao)
		{
			// Cria objeto de progresso
			ProcessaMenssagem processa = new ProcessaMenssagem();
			processa.addPropertyChangeListener(this);
			processa.execute();
		}

	}

	// Atualiza a propriedade do objeto
	public void propertyChange(PropertyChangeEvent evt) {

		if ("progress" == evt.getPropertyName())
		{
			int andamento = (Integer) evt.getNewValue();
			progresso.setValue(andamento);
		}
	}

	// Cria GUI
	public static void criaGUI()
	{
		// Cria formulario principal
		JFrame formulario = new JFrame("DA - Progress Bar");
		formulario.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// Cria instancia da classe
		BarraProgresso barra = new BarraProgresso();

		// Adiciona painel principal
		formulario.setContentPane(barra.criaPainel());

		formulario.setSize(300,150);

		formulario.setVisible(true);
	}

	public static void main(String[] args) {

		// Thread do swing
		javax.swing.SwingUtilities.invokeLater(new Runnable() {

			public void run() {
				criaGUI();
			}
		});

	}

}
Anúncios
comentários
  1. Oi estou fazendo um programa usando o Netbeans para fazer as janelas e estou tendo dificuldade de usar o ProgressBar. Tentei adaptar o seu codigo mas tive problemas. Dentro do ActionPerformed(que coloquei no evento chamado pelo botão) dá erro.
    Ele aponta para a linha do this e: “incompatible types: jMain cannot be converted PropertyChangeListener”. jMain é a janela principal. Veja:

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    // TODO add your handling code here:
    jButton1.setEnabled(false);
    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    //Instances of javax.swing.SwingWorker are not reusuable, so
    //we create new instances as needed.
    task = new Task();
    task.addPropertyChangeListener(this);
    task.execute();
    }
    Vc pode me ajudar ?
    Att. Clemente

    • Olá Clemente,

      Programar com JProgressBar no NetBeans é diferente porque ele não implementa o PropertyChangeListener na classe principal e não consegue converter a sua classe (this) que estende o JFrame para PropertyChangeListener que está declarado somente no escopo do evento.

      jProgressBar1.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
      public void propertyChange(java.beans.PropertyChangeEvent evt) {
      jProgressBar1PropertyChange(evt);
      }

      Mas é só você criar uma Thread para o progresso, este vídeo mostra como utilizar o JProgressBar no NetBeans: https://www.youtube.com/watch?v=xPDV4hwhQW4

      Espero ter ajudado.
      Abraços.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

w

Conectando a %s