O JProgressBar nao esta atualizando

8 respostas
G

ola a todos…

fiz um JProgressBar e um laco pra fazer ate q chegue no valor maximo, e incremententei a cada passagem no laco, mas esta atualizando.

Uma coisa interessante: de colocar o JOptionPane.showMessageDialog(null,nProgress), dai ele atualiza certo !

while (nProgress < 100)
{
    nProgress = nProgress + 1;
    oProgress.setValue(nProgress);
    //JOptionPane.showMessageDialog(null,nProgress);
}

O q pode ser ?

desde ja agradeco: obrigado !

gilba

8 Respostas

T

Procure sobre “thread de GUI do Swing”.
Basicamente o problema é o seguinte: o Swing, para evitar problemas, usa apenas uma thread para desenhar TODOS os elementos da tela.
Isso não é só uma característica do Swing, mas de todos os toolkits (incluindo o .NET) que devem desenhar telas e evitar problemas de portabilidade e drivers de vídeo.
Se você tentar usar a thread de GUI do Swing para fazer contas (como é o seu caso), então ela tem de esperar a conta acabar até que possa efetivamente desenhar alguma coisa.
Você tem de fazer essas coisas em uma thread separada.

G

oloko, meu !!! rsss

fala em portugues pra mim entender (nao viu q soh postei umas 20 mesanges = iniciante) ?

tem como explicar melhor num demo, por favor ?

muitissimo obrigado !

Giba.

T

Aqui no GUJ há vários exemplos de JProgressbar que funcionam. Dê uma procuradinha, por favor.

G

nao sei se nao estou fazendo certo (mas acho q sim) q escreve algo pra pesquisar, e buscar topicos q nao tem nada a ver com a pesquisa…

alguem poderia me ajudar, por favor ?

obrigado !!!

fabiofalci

Dá uma lida aqui pra entender
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/interim.html

G

ola…

primeiramente, obrigado por responder…

segundo, dei uma olhadinha, mas, infelizmente, por estar iniciando no java, nao entendi nada…sorry !

mas se alguem mais poder tentar ajudar, eu fico muito agradecido: MUITO OBRIGADO !!!

fabiofalci

Ok, achei um exemplo aqui usando SwingWorker.publish.
Se vc é iniciante, pode achar meio complicado.

Em todo o caso é esse

public class PublishSwingWorker extends JPanel {

	JLabel resultLabel;
	JProgressBar progressBar;

	public PublishSwingWorker() {
		progressBar = new JProgressBar();
		progressBar.setPreferredSize(new Dimension(150, 25));
		progressBar.setStringPainted(true);
		add(progressBar);

		resultLabel = new JLabel("Result: None");
		resultLabel.setPreferredSize(new Dimension(250, 25));
		add(resultLabel);

		JButton button = new JButton("Start Process");
		button.setPreferredSize(new Dimension(75, 25));
		add(button);
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				startProcess();
			}
		});
	}

	private void startProcess() {
		resultLabel.setText("Result: None");
		progressBar.setString("0%");
		new SwingWorker<String, Integer>() {
			@Override
			protected String doInBackground() throws Exception {
				for (int i = 0; i < 100; i++) {
					if (i % 2 == 0) {
						// vou atualizar de 2 em 2
						publish(i);
					}
					// faz alguma coisa
					Thread.sleep(100);
				}

				publish(100);
				return "Success";
			}

			@Override
			protected void process(List<Integer> chunks) {
				int value = chunks.get(0);
				progressBar.setValue(value);
				progressBar.setString(value + "%");
			}

			@Override
			protected void done() {
				try {
					endProcess(get());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}.execute();
	}

	private void endProcess(String result) {
		resultLabel.setText("Result: " + result);
	}

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

Olá Giba.

Primeiramente, se você quer trabalhar com JProgressBar, te aconselho a estudar sobre Thread, pois é imprescindível.

Mas vamos tentar entender o que está acontecendo:

Quando você executa dois programas no Windows, são abertos dois processos, um para cada programa. Com o Java acontece algo parecido. Para você executar o loop e atualizar o JProgressBar ao mesmo tempo, você deve colocar cada tarefa em um processo, pois senão será priorizada a execução do loop, em detrimento à atualização do JProgressarBar. Para fazer isso, utiliza-se Thread. Nessa situação teríamos duas Threads sendo executadas em paralelo. O loop será executado na Thread principal, que é o próprio processo do teu programa. A atualização do JProgressBar será executada no outro processo, ou Thread, como é chamado em Java.
Então funcionaria da seguinte forma: a cada vez que passa pelo loop, é necessário informar o JProgressBar para que atualize o seu valor atual. Para que o JProgressBar atualize o seu valor, é necessário iniciar uma nova Thread, no intuito de realizar a atualização. Então, toda vez que o programa passa pelo loop, uma Thread é iniciada para que atualize o valor do JProgressBar. A Thread que foi iniciada deve ser encerrada logo que realiza a atualização.

Espero que possa ter entendido pelo menos o que está acontecendo com o teu programa, e como pode ser resolvido. O algoritmo que escrevi não é a única solução para o problema, e também não é a mais eficiente, mas possui a ideia central para a solução.

Se está iniciando em Java, não se preocupe se não entender, pois esse é um caso que exige o domínio de vários conhecimentos para que se possa chegar a uma solução satisfatória.

Boa sorte

Criado 6 de julho de 2009
Ultima resposta 7 de jul. de 2009
Respostas 8
Participantes 4