0

我正在尝试在 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);
    }
}
4

1 回答 1

1

问题是你打了syncProgressSplashScreen.showProgress2次电话。第一次阻塞线程导致它从 0 增加到 10 然后你再次调用它从 0 到 30。删除读取的行,myProgressSplashScreen.showProgress(10, 2);它不会执行 2 次。另外我注意到您没有为进度条设置最大值,因此除非您调用它,否则myProgressSplashScreen.showProgress(100, 2)它不会达到 100%。

于 2013-09-23T14:14:18.280 回答