如何使用 Swing Timer 来延迟进度条的加载
Posted
技术标签:
【中文标题】如何使用 Swing Timer 来延迟进度条的加载【英文标题】:How to use the Swing Timer to delay the loading of a progress bar 【发布时间】:2013-03-18 02:47:34 【问题描述】:我需要找到一种方法来使用带有进度条的摇摆计时器。我尝试使用 Thread.sleep(),但是当我使用它时它使应用程序崩溃。有什么方法可以使用 Swing Timer 而不是 Sleep()?
public void piiEros(int dist)
Pii pii = new Pii();
pii.setVisible(true);
for(int pc = 0;100 > pc; pc++)
try
Thread.sleep(dist/100);
catch (InterruptedException ex)
Logger.getLogger(Trav.class.getName()).log(Level.SEVERE, null, ex);
pii.pg.setValue(pc);
pii.dispose();
o.Eros();
注意:Pii 是一个带有进度条的类。 Dist 是它加载的速度。 Trav 是方法所在的类。Pc 代表 %,完成了多少会显示在条上。 o.Eros 打开另一个 GUI。
【问题讨论】:
对不起代码,空格只是删除自己。编辑:Eng Fouad 修复了缩进,谢谢! 这是一个更易读的代码:dropbox.com/s/402vcqi3ah4kcbn/ST%20PG.JPG 不要在美国东部时间睡觉!顺便说一句,说到进度条,请使用 SwingWorker。 使用 SwingWorker 可能更好 另见Getting my jProgressBar to run on a timer 【参考方案1】:您可以通过这种方式更改您的piiEros
方法:
public void piiEros(int dist)
final Pii pii = new Pii();
pii.setVisible(true);
javax.swing.Timer timer = new javax.swing.Timer(dist/100, new ActionListener()
public void actionPerformed(ActionEvent evt)
pii.pg.setValue(pg.getValue()++);
if ( pii.pg.getValue() > 100 )
timer.stop();
pii.dispose();
o.Eros();
);
timer.setInitialDelay(0);
timer.setRepeats(true);
timer.start();
【讨论】:
(无需调用setDelay
,你已经在构造函数中建立了;))
是的,我想确保 ;)
IDE 不喜欢在方法中调用 javax.swing.Timer 并且我之前总是添加要创建的对象的名称,所以现在看起来像这样:Timer timer = new Timer(dist/100, new ActionListener()
Could'nt get your point..你的意思是你的 IDE 在看到 javax.swing.Timer
时在抱怨吗?【参考方案2】:
使用SwingWorker
可能更容易(从长远来看)。它提供了许多有用的方法来更新 UI(从事件调度线程的上下文中),同时允许在后台继续执行......
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestSwingWorker02
public static void main(String[] args)
new TestSwingWorker02();
public TestSwingWorker02()
EventQueue.invokeLater(new Runnable()
@Override
public void run()
try
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
catch (ClassNotFoundException ex)
catch (InstantiationException ex)
catch (IllegalAccessException ex)
catch (UnsupportedLookAndFeelException ex)
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
);
public class TestPane extends JPanel
public TestPane()
setLayout(new GridBagLayout());
JProgressBar pb = new JProgressBar();
add(pb);
new ProgressWorker(pb, 40).execute();
@Override
public Dimension getPreferredSize()
return new Dimension(200, 200);
public class ProgressWorker extends SwingWorker<Void, Integer>
private int delay;
private JProgressBar pb;
public ProgressWorker(JProgressBar progressBar, int delay)
this.pb = progressBar;
this.delay = delay;
@Override
protected void process(List<Integer> chunks)
// Back in the EDT...
pb.setValue(chunks.get(chunks.size() - 1)); // only care about the last one...
@Override
protected Void doInBackground() throws Exception
for (int index = 0; index < 100; index++)
publish(index);
Thread.sleep(delay);
return null;
@Override
protected void done()
// Back in the EDT...
//pii.dispose();
//o.Eros();
SwingWorker
允许您分离逻辑。在doInBackground
方法中你可以专注于需要在EDT之外运行的那部分代码,你可以将publish
分别更新回EDT和process
它们。当全部为done
时,您可以根据需要进行清理。
SwingWorker
还提供进度监控功能,因此,在您的情况下,如果您不想这样做,您就不必使用 API 的 publish
/process
部分。这将允许您将PropertyChangeListener
附加到工作人员,而无需向其公开进度条。 (但我为示例做了)
public class ProgressWorker extends SwingWorker<Void, Integer>
private int delay;
private JProgressBar pb;
public ProgressWorker(JProgressBar progressBar, int delay)
this.pb = progressBar;
this.delay = delay;
// You can use a property change listener to monitor progress updates...
addPropertyChangeListener(new PropertyChangeListener()
@Override
public void propertyChange(PropertyChangeEvent evt)
if ("progress".equalsIgnoreCase(evt.getPropertyName()))
pb.setValue((Integer)evt.getNewValue());
);
@Override
protected Void doInBackground() throws Exception
for (int index = 0; index < 100; index++)
setProgress(index);
Thread.sleep(delay);
return null;
@Override
protected void done()
// Back in the EDT...
//pii.dispose();
//o.Eros();
【讨论】:
+1 现代和干净的答案..;) 。但是你不觉得SwingWorker
对于这么小的任务来说是一个很大的任务。
就我个人而言,我觉得它更干净,更容易理解(但我就是这么简单)
我明白了..程序员自己的品味..;)以上是关于如何使用 Swing Timer 来延迟进度条的加载的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 swift 显示带有进度条的 AVAudioPlayer?