2013-09-23 39 views
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); 
    } 
} 

回答

1

问题是你拨打syncProgressSplashScreen.showProgress 2次。它第一次阻塞线程,使它从0增加到10,然后再次调用它,从0到30.从删除线myProgressSplashScreen.showProgress(10, 2);,它不会做2次。此外,我注意到你不设置进度条的最大值,所以除非你打电话给myProgressSplashScreen.showProgress(100, 2)它不会去100%。

+0

我通过设计将它调用两次,如果您将两个调用showProgress放在方法synchronize()中的同一线程中,您会看到它正确地更新了进度。问题是,如果我从另一个线程复制MySplashScreen对象调用它,则不会。 – dendini

+0

@dendini为什么你会这么称呼它2次? –

相关问题