如果您这样做的话,那只是鸡/蛋.您可以在EDT上构造所有Swing对象,然后通过指示EDT通过SwingUtilities.invokeLater(Runnable)执行它们来让SwingWorker(或任何其他线程)管理所有更新.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class RudeProgressBar extends JFrame {
private JButton button;
public RudeProgressBar() {
setTitle("Rude Progress Bar");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
button = new JButton("Do teh work");
add(button, BorderLayout.SOUTH);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JDialog dialog = new JDialog(RudeProgressBar.this, true);
dialog.setTitle("Doing teh work");
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
final JProgressBar progressBar = new JProgressBar(0, 100);
dialog.setLayout(new BorderLayout());
dialog.add(progressBar);
dialog.setSize(100, 100);
dialog.setLocationRelativeTo(RudeProgressBar.this);
MyTask task = new MyTask(dialog);
task.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});
task.execute();
}
});
setSize(200, 200);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new RudeProgressBar().setVisible(true);
}
});
}
private class MyTask extends SwingWorker {
private final JDialog dialog;
public MyTask(JDialog dialog) {
this.dialog = dialog;
}
@Override
protected Void doInBackground() throws Exception {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
dialog.setVisible(true);
}
});
int progress = 0;
for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
setProgress(progress += 20);
}
return null;
}
@Override
protected void done() {
dialog.setVisible(false);
dialog.dispose();
}
}
}
如果您担心在SwingWorker.done之后可能会执行invokeLater实现(在SwingWorker.doInBackground内部),则只需将代码完成放入另一个invokeLater中即可.通过这样做,您可以将Runnable实现排入队列,以便EDT以特定顺序执行它们.即使从EDT本身调用此方法,也会发生排队.
请注意,如果您查看SwingWorker的实现,将会看到它依赖javax.swing.Timer来执行done(),并且Timer本身调用invokeLater,因此再次在done内部调用它等同于什么也不做.但是,如果这样做,不会有任何问题.