2015-05-18 42 views
0

我正在編寫一個java swt應用程序來處理服務器日誌文件並使用一些分析生成Excel表格,我沒有這樣做的問題。從線程更新進度條時,SWT窗口變得無響應

當我嘗試更新進度欄時出現問題。

以下是代碼的基本流程。用戶使用directoryDialog選擇日誌文件並按下開始按鈕。點擊按鈕時,執行以下代碼。

startButton.addMouseListener(new MouseAdapter() { 
     public void mouseUp(MouseEvent e) { 
      pm.setUserData(ud,progressBar); 
      progressBar.getDisplay().asyncExec(new Runnable() { 
         @Override 
         public void run() { 
          pm.startProcessing(); 
         } 
        }); 
} 

在文件的實際處理髮生的類中,有簡單的while循環,直到它到達文件的末尾。從文件讀取每行後,我調用更新進度欄的方法。

while ((logEntry = br.readLine()) != null) { 
       readSize += logEntry.length() + 1; 
       //some long processing logic 
       progressBar.setSelection(getProgress()); 
} 

getProgress()是計算該文件的百分讀

(read/total)*100 

上述程序正在工作的簡單方法。我收到了預期的結果。進度條更新,但gui變得無法響應。我無法移動窗戶。我無法點擊關閉按鈕。

我嘗試使用擺動工人和display.asyncExec()

+0

日誌文件的範圍從幾MB上綠帶。因此,如果UI變得無響應,用戶可能會認爲應用程序凍結並終止它 – kamesh

+0

我認爲讀取/處理日誌文件是在不同於運行GUI的主線程的線程中完成的? – Stugal

+0

似乎[that](http://stackoverflow.com/a/16714819/2894369)可以幫助你。您也可以嘗試使用['Executors'](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html)執行任務,使用'asyncExec()'更新UI。 – alex2410

回答

2

的SWT文件明確指出,ProgressBar.setSelection() 將拋出一個異常(ERROR_THREAD_INVALID_ACCESS)時,不從UI線程調用。這意味着你要麼在你的代碼的某處吞下異常,要麼在UI線程中運行上面的代碼。

有一個snippet which shows how to update a ProgressBar from a thread

display.asyncExec(new Runnable() { 
        @Override 
        public void run() { 
         if (bar.isDisposed()) 
          return; 
         bar.setSelection(getProgress); 
        } 
       }); 
+0

對不起,我粘貼錯誤的代碼片段。請在原文中找到更新的代碼。我只使用display.asyncExec – kamesh

+0

正如我所說:您正在運行'pm.startProcessing();'在UI線程內部。不要這樣做。之前的代碼看起來好多了;你只需要用我的答案中的代碼替換'progressBar.setSelection(getProgress());'。注意:Swing工人不能在SWT中工作:-) –

+0

感謝Aaron ......它的工作原理...... :)我一直在努力從一週 – kamesh