如果您这样做的话,那只是鸡/蛋。您可以在EDT上构造所有Swing对象,然后
SwingWorker通过指示EDT通过执行它们来让您(或任何其他线程)管理所有更新
SwingUtilities.invokeLater(Runnable)。
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<Void, Void> { 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(); } }}
如果您担心
invokeLater实现(内部
SwingWorker.doInBackground)在执行之后会被执行
SwingWorker.done,只需将代码
done放入另一个
invokeLater。通过这样做,您可以将
Runnable实现排入队列以让EDT以特定顺序执行它们。即使从EDT本身调用此方法,也会发生排队。
请注意,如果您看一下
SwingWorker实现,您会看到它依赖于
javax.swing.Timer执行
done()和
Timer本身调用
invokeLater,因此
done再次在内部调用它无济于事。但是,如果这样做,不会有任何问题。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)