Atualização de jProgressBar do SwingWorker
Eu uso para monitorar uma tarefa longa, atualizando uma ProgressBar. A tarefa de longa duração é, claro, executada em um encadeamento do Swingworker.
Eu costumava programar coisas assim:
public class MySwingWorkerClass extends SwingWorker<Void, Void> {
private JProgressBar progressBar;
public MySwingWorker(JProgressBar aProgressBar) {
this.progressBar = aProgressBar;
progressBar.setVisible(true);
progressBar.setStringPainted(true);
progressBar.setValue(0);
}
@Override
public Void doInBackground() {
//long running task
loop {
calculation();
progressBar.setValue(value);
}
return null;
}
@Override
public void done() {
progressBar.setValue(100);
progressBar.setStringPainted(false);
progressBar.setVisible(false);
}
}
mas recentemente eu descobri que eu poderia fazer isso usando o "setProgress" e definindo a mudança de propriedade e fazendo coisas assim
public class MySwingWorkerClass extends SwingWorker<Void, Void> {
private JProgressBar progressBar;
public MySwingWorker(JProgressBar aProgressBar) {
addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer) evt.getNewValue());
}
}
});
progressBar.setVisible(true);
progressBar.setStringPainted(true);
progressBar.setValue(0);
setProgress(0);
}
@Override
public Void doInBackground() {
//long running task
loop {
calculation();
setProgress(value);
}
return null;
}
@Override
public void done() {
setProgress(100);
progressBar.setValue(100);
progressBar.setStringPainted(false);
progressBar.setVisible(false);
}
}
Minha pergunta é: meu primeiro código é aceitável ou devo usar o setProgress para anyreason? Acho o segundo código mais complicado e no meu caso e não sei se há alguma vantagem ou razão para usar o segundo.
Qualquer conselho?
EDITAR Obrigado pela resposta. Como um resumo. A primeira solução está "errada" porque a atualização da barra de progresso é executada fora do EDT. A segunda solução é "correta" porque a atualização da barra de progresso é executada dentro do EDT
Agora, de acordo com a resposta "interessante" do @mKorbel no meu caso, o meu cálculo dá resultados em texto HTML que eu "insiro" (veresse link). Meu código atual é o seguinte.
Publico (string) e o meu código de processo parece
@Override
protected void process(List<String> strings) {
for (String s : strings) {
try {
htmlDoc.insertBeforeEnd(htmlDoc.getElement(htmlDoc.getDefaultRootElement(), StyleConstants.NameAttribute, HTML.Tag.TABLE), s);
} catch (BadLocationException ex) {
} catch (IOException ex) {
}
}
}
Como posso reutilizar @mKobel para fazer o mesmo no meu caso. Quero dizer, ele usa para anular a renderização de tabelas no meu caso, qual renderer devo sobrepor (jTextPane?) E como?