我正在尝试在Java中使用类似于下面的进度条:
public class MyProgressSplashScreen extends JWindow
{
private final JProgressBar progressbar;
private final ExecutorService autoProgressExecutor = Executors.newFixedThreadPool(1);
public MyProgressSplashScreen(final int theMin, final int theMax)
{
super();
final JPanel contentPanel = new JPanel(new BorderLayout());
contentPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
if (theMin != -1 && theMax != -1)
{
progressbar = new JProgressBar(SwingConstants.HORIZONTAL, theMin, theMax);
}
else
{
progressbar = new JProgressBar(SwingConstants.HORIZONTAL);
progressbar.setIndeterminate(true);
}
progressbar.setStringPainted(true);
contentPanel.add(progressbar, BorderLayout.SOUTH);
add(contentPanel);
pack();
setAlwaysOnTop(true);
}
public void showProgress(final int theValueTo, final int theEstimatedTimeInSeconds)
{
showProgress(progressbar.getValue(), theValueTo, theEstimatedTimeInSeconds);
}
public void showProgress(final int theValueFrom, final int theValueTo,
final int theEstimatedTimeInSeconds)
{
setVisible(true);
autoProgressExecutor.execute(new Runnable()
{
@Override
public void run()
{
int numberOfSteps = theValueTo - theValueFrom;
long timeToWait = TimeUnit.SECONDS.toMillis(theEstimatedTimeInSeconds)
/ numberOfSteps;
for (int i = theValueFrom; i <= theValueTo; i++)
{
progressbar.setValue(i);
try
{
TimeUnit.MILLISECONDS.sleep(timeToWait);
}
catch (final InterruptedException e) { }
}
if (progressbar.getValue() == 100) { setVisible(false); }
}
});
}
}
但是我无法传递MyProgressSplashScreen的副本,以便让单独的线程更新进度。 例如,下面的程序从0到10开始计数,然后从0到30重新启动,而它不应该重置为零!
public class TestSplashScreen
{
private final MyProgressSplashScreen myProgressSplashScreen = new MyProgressSplashScreen(-1,-1);
public static void main(String args[])
{
TestSplashScreen testInvoke = new TestSplashScreen();
testInvoke.synchronize();
}
public void synchronize()
{
Runnable runnable = new Runnable()
{
@Override
public void run()
{
myProgressSplashScreen.showProgress(10, 2);
myProgressSplashScreen.toFront();
MyRunnable myRunnable = new MyRunnable();
myRunnable.setSyncProgressSplashScreen(myProgressSplashScreen);
Thread t1 = new Thread(myRunnable);
t1.start();
}
};
runnable.run();
}
}
class MyRunnable implements Runnable
{
MyProgressSplashScreen syncProgressSplashScreen;
public void setSyncProgressSplashScreen(MyProgressSplashScreen syncProgressSplashScreen)
{
this.syncProgressSplashScreen = syncProgressSplashScreen;
}
@Override
public void run()
{
syncProgressSplashScreen.showProgress(30, 3);
}
}
答案 0 :(得分:1)
问题是您拨打syncProgressSplashScreen.showProgress
2次。它第一次阻塞线程使其从0增加到10然后再次从0到30调用它。删除读取myProgressSplashScreen.showProgress(10, 2);
的行,它不会执行2次。另外我注意到你没有设置进度条的最大值,所以除非你打电话给myProgressSplashScreen.showProgress(100, 2)
,否则它不会达到100%。