Áno, SwingWorker je štandardným riešením vášho problému. Upozorňujem, že SwingWorkerov bolo v minulosti v obehu viacero. Pokiaľ môžete, použite javax.swing.SwingWorker<T, V> z JRE (since 1.6). Ten ponúka API aj pre progress výpočtu.
V Swingu je dôležité manipulovať s GUI výhradne vo vlákne, ktoré sa zvykne označovať ako "event dispatch thread". To sa týka aj vytvorenia a zobrazenia vášho JPanelu a JFramu/JDialogu. Na to je dobrá tá metóda invokeLater.
Tento kód by vám mohol pomôcť:
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import com.h311.swing.GridBagLayout;
public class Test {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final JTextField myResultField = new JTextField();
final JProgressBar myProgress = new JProgressBar();
myProgress.setStringPainted(true);
final JButton myStartButton = new JButton("Start");
myStartButton.setActionCommand("start");
final JButton myCancelButton = new JButton("Cancel");
myCancelButton.setActionCommand("cancel");
myCancelButton.setEnabled(false);
ActionListener actionListener = new ActionListener() {
private SwingWorker<Integer, Integer> worker;
@Override
public void actionPerformed(ActionEvent e) {
if (worker != null) {
worker.cancel(true);
}
if ("start".equals(e.getActionCommand())) {
worker = new SwingWorker<Integer, Integer>(){
@Override
protected Integer doInBackground() throws Exception {
/* 5 seconds */
int durationInMilliseconds = 1000 * 5;
long startTime = System.currentTimeMillis();
long deadLine = startTime + durationInMilliseconds;
int result = 0;
while (!isCancelled()) {
/* do something meaningful */
long now = System.currentTimeMillis();
if (now > deadLine) {
break;
}
long timeLeft = now - startTime;
publish(Integer.valueOf((int) ((timeLeft / (double)durationInMilliseconds) * 100)));
result++;
}
return result;
}
@Override
protected void process(List<Integer> chunks) {
if (!isCancelled() && chunks != null && chunks.size() > 1) {
/* consider only the last value */
int value = chunks.get(chunks.size() -1);
myProgress.setValue(value);
myProgress.setString(new StringBuilder(3 + 2).append(value).append(' ').append('%').toString());
}
}
@Override
protected void done() {
try {
Integer result = get();
myResultField.setText(String.valueOf(result));
} catch (CancellationException e) {
myProgress.setString("Cancelled");
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
finally {
myStartButton.setEnabled(true);
myCancelButton.setEnabled(false);
}
}
};
myStartButton.setEnabled(false);
myCancelButton.setEnabled(true);
myResultField.setText("");
worker.execute();
}
}
};
myStartButton.addActionListener(actionListener);
myCancelButton.addActionListener(actionListener);
JPanel myPanel = new JPanel(new GridBagLayout());
int row = 0;
GridBagConstraints startConstraints = new GridBagConstraints();
startConstraints.gridx = 0;
startConstraints.gridy = row;
myPanel.add(myStartButton, startConstraints);
GridBagConstraints cancelConstraints = new GridBagConstraints();
cancelConstraints.gridx = 1;
cancelConstraints.gridy = row;
myPanel.add(myCancelButton, cancelConstraints);
row++;
GridBagConstraints progressConstraints = new GridBagConstraints();
progressConstraints.gridx = 0;
progressConstraints.gridy = row;
progressConstraints.fill = GridBagConstraints.HORIZONTAL;
progressConstraints.gridwidth = 2;
myPanel.add(myProgress, progressConstraints);
row++;
GridBagConstraints resultLabelConstraints = new GridBagConstraints();
resultLabelConstraints.gridx = 0;
resultLabelConstraints.gridy = row;
myPanel.add(new JLabel("Iterations"), resultLabelConstraints);
GridBagConstraints resultConstraints = new GridBagConstraints();
resultConstraints.gridx = 1;
resultConstraints.gridy = row;
resultConstraints.fill = GridBagConstraints.HORIZONTAL;
myPanel.add(myResultField, resultConstraints);
JFrame myFrame = new JFrame();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setContentPane(myPanel);
myFrame.pack();
myFrame.setVisible(true);
}
});
}
}