2016-08-05 39 views
1

我很抱歉添加到許多JProgressBar更新問題,但這真的讓我瘋了。JProgress酒吧不更新在SwingWorker

我有一個JProgressBar通過SwingWorker進行更新,但我仍然有完成後更新欄的典型問題。

下面是相關代碼:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.util.ArrayList; 
import java.util.Calendar; 
import java.util.List; 
import java.util.concurrent.ExecutionException; 
import javax.swing.*; 

public class SwingTest { 

    public static void main(String args[]) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       init(); 
      } 
     }); 
    } 

    public static void init() { 
     JFrame frame = new JFrame(); 
     JPanel panel = new JPanel(); 
     JProgressBar bar = new JProgressBar(); 

     JButton button = new JButton("Start"); 
     button.addActionListener(new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       bar.setMaximum(100); 
       bar.setValue(0); 

       SwingWorker worker = new SwingWorker<String, Void>() 
       { 
        @Override 
        public String doInBackground() 
        { 
         int val = 0; 
         // +1 to make inclusive 
         for (int i = 0; i < 100; i++) 
         { 
          try 
          { 
           Thread.sleep(50); 
          } catch (InterruptedException e) 
          { 
           e.printStackTrace(); 
          } 

          setProgress(++val); 
         } 

         return "Hello SwingWorker World"; 
        } 

        @Override 
        public void done() 
        { 
        } 
       }; 

       worker.addPropertyChangeListener(
         new PropertyChangeListener() 
         { 
          public void propertyChange(PropertyChangeEvent evt) 
          { 
           if ("progress".equals(evt.getPropertyName())) 
           { 
            bar.setValue((Integer)evt.getNewValue()); 
           } 
          } 
         } 
       ); 

       worker.execute(); 

       try 
       { 
        System.out.println("Return: " + worker.get().toString()); 
       } catch (InterruptedException e1) 
       { 
        e1.printStackTrace(); 
        System.out.println("Failed."); 
       } catch (ExecutionException e1) 
       { 
        e1.printStackTrace(); 
        System.out.println("Failed."); 
       } 
      } 
     }); 

     panel.add(button); 
     panel.add(bar); 

     frame.add(panel); 
     frame.pack(); 
     frame.setSize(200,90); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
} 

如果問題可能是由於另一部分如果需要的話我會編輯我的問題有更多的代碼。

在此先感謝。

編輯:剝離代碼到最小的產品。

+0

爲了儘快提供更好的幫助,請發佈[MCVE]或[簡短,獨立,正確的示例](http://www.sscce.org/)。 –

回答

0

您發佈的代碼中存在的問題是當您啓動SwingWorker時,您立即等待它運行。這將阻止事件線程,它可以防止顯示器被更新:

worker.execute(); // This starts the thread in the background 

try 
{ 
    // This immediately stops the event handler waiting for the worker to finish 
    System.out.println("Return: " + worker.get().toString()); 
} catch (InterruptedException e1) 
{ 
    e1.printStackTrace(); 
    System.out.println("Failed."); 
} catch (ExecutionException e1) 
{ 
    e1.printStackTrace(); 
    System.out.println("Failed."); 
} 

如果您註釋掉的try-catch塊的整體,它會運行並更新顯示。

如果您需要等待工作人員的結果,那麼您應該在另一個線程上等待結果,並允許UI線程繼續。

+0

太棒了!謝謝!所以,如果我在另一個線程上等待結果,我該如何去將它們返回到父函數?我想.wait()也會阻止美國東部時間。 –

+0

我很幸運地找到了解決方案。只需重構一些代碼。再次感謝! –

1

嗯,我不確切知道你的代碼在做什麼,但是我沒有看到你的代碼中有任何「延遲」的地方。

因此,循環會繼續執行,所有繪畫請求會合併到一個請求中,因此您只能看到最終值。

您可以通過在setProgress(...)方法之後簡單添加Thread.sleep()來驗證是否存在此問題。

如果是這種情況,問題是您爲什麼使用進度條,因爲代碼執行得太快了。

閱讀How to Use Progress Bars上的Swing教程部分,並從工作演示開始。然後,您可以修改工作代碼,以查看進行更改時發生的情況。

+0

我編輯我的代碼到更小的表示。完整的代碼可能需要幾分鐘到一個多小時才能執行,假設我理解你,我不認爲這是由於代碼執行速度太快。 –