2012-12-07 31 views
3

我試過使用SwingWorker來更新進度欄。對我來說沒有新東西。我有點懶惰,所以我沒有重寫處理方法。這裏有一個簡化的例子:發佈/進程使SwingWorker變慢

protected Void doInBackground() throws Exception { 
    for (int i = 0; i < 10000; i++) { 
     progressBar.setValue(i+1);    
    } 
    return null; 
} 

在我的電腦上,大約需要6秒鐘將progess欄更新爲100%。今天是星期五,所以我想讓我們以不同的方式來做,就像經常描述的那樣。讓我們使用發佈和過程方法來更新進度條:

@Override 
protected Void doInBackground() throws Exception { 
    for (int i = 0; i < maximum; i++) {    
     publish(i+1); 
    } 
    return null; 
} 

@Override 
protected void process(List<Integer> chunks) {   
    progressBar.setValue(chunks.get(chunks.size()-1)); 
} 

但現在與發佈方式需要21(而不是6)秒,進度條更新到100%。

爲什麼?

這裏整個代號(車架有「開始」按鈕和進度條):

public class Gui extends JFrame { 

    public static void main(String[] args) { 
     new Gui(); 
    } 

    public Gui() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     final JProgressBar progressBar = new JProgressBar(); 
     progressBar.setStringPainted(true); 

     JButton btnStart = new JButton("Start"); 
     btnStart.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       new MySwingWorker(progressBar).execute(); 
      } 
     }); 

     getContentPane().setLayout(new BorderLayout(3, 3)); 
     getContentPane().add(btnStart, BorderLayout.CENTER); 
     getContentPane().add(progressBar, BorderLayout.SOUTH); 
     pack(); 
     setVisible(true); 
     setLocationRelativeTo(null); 
    } 

    private class MySwingWorker extends SwingWorker<Void, Integer> { 

     private final int MAXIMUM = 100000000; 
     private final JProgressBar progressBar; 

     public MySwingWorker(JProgressBar progressBar) { 
      this.progressBar = progressBar; 
      this.progressBar.setMaximum(MAXIMUM); 
      this.progressBar.setValue(0); 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      for (int i = 0; i < MAXIMUM; i++) { 
       //---------------------------------- 
       // TOGGLE BETWEEN THESE LINES: 
       //progressBar.setValue(i+1); 
       publish(i + 1); 
       //----------------------------------- 
      } 
      return null; 
     } 

     @Override 
     protected void process(List<Integer> chunks) { 
      progressBar.setValue(chunks.get(chunks.size() - 1)); 
     } 
    } 
} 

感謝建議...

+3

沒有仔細看 - 但你的第一個版本是_wrong_:你_must not_訪問Swing組件在doInBackground – kleopatra

+0

是的,我知道,但它幹活克沒有任何問題,它快70%! 6秒而不是21秒。所以問題在於我:真的會發生什麼? – a3po

+2

所有在美國東部時間的違規行爲可能發生的邪惡事情;-)很難發現,虛假(但肯定會拋出,當你最不希望它),不可預知的。所以根本不要(大多數生產代碼都應該有防範措施)。這裏的問題似乎是你無需充斥系統:在真實世界的情況下,你不會嘗試更新頻率高於屏幕分辨率的進度條,你會:-) – kleopatra

回答

1

你不應該張貼的每一個變化,但也許每10:

for (int i = 0; i < maximum; i++) { 
    doTheWork(); 
    if(i % 10 == 0) { 
     publish(i+1); 
    } 
} 
publish(maximum);