2013-09-23 66 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次? –

相關問題