大夢想家

          5年開發工程師,2年實施經理,X年售前顧問,......
          數據加載中……
          JFace進度條使用經驗一則

              我討論的進度條主要是JFace的進度條,RCP已經提供了完善的Job組件,為什么還要用JFace的進度條呢?原因是我要在登陸界面上做進度處理,也就是使用Eclipse3.3提供的AbstractSplashHandler特性,可以將原有的啟動畫面替換成為一個登陸界面,啟動這個登陸界面時,Eclipse的Platform此時還沒有啟動,所以不能使用RCP本身的Job組件了。

              由于是一個檢測服務器是否聯通的測試,所以并不知道測試的真實時間,所以就是要使用“傻瓜進度條”了,也就是反復走的進度條陳剛的代碼如下:

          button.addSelectionListener(new SelectionAdapter() {
                      private boolean stopFlag;// 停止標志

                      private void go() {
                          for (int i = 0; i < 10; i++) {// 循環10次,每次間隔一秒
                              System.out.println("第" + (i + 1) + "個任務執行完畢");
                              if (stopFlag) {// 監控是否要讓停止后臺任務
                                  System.out.println("被中斷了");
                                  return;
                              }
                              try {
                                  Thread.sleep(1000);
                              } catch (Throwable t) {}
                          }
                          stopFlag = true;// 執行完畢后把標志位設為停止,好通知給進度框
                          System.out.println("全部任務執行完畢");
                      }

                      public void widgetSelected(SelectionEvent e) {
                          stopFlag = false;// 每次都設初值為false
                          new Thread() {// 把后臺任務放到一個新開線程里執行
                              public void run() {
                                  go();
                              }
                          }.start();
                          showProgressDialog();// 打開一個進度框
                      }

                      private void showProgressDialog() {
                          IRunnableWithProgress runnable = new IRunnableWithProgress() {
                              public void run(IProgressMonitor monitor) {
                                  monitor.beginTask("正在執行中......", 30);
                                  int i = 0;
                                  while (true) {
                                      // 監聽是否單擊了進度框的“取消”按鈕,stopFlag則是監聽后臺任務是否停止
                                      if (monitor.isCanceled() || stopFlag) {
                                          stopFlag = true; // 單擊了“取消”按鈕要設標志位為停止,好通知后臺任務中斷執行
                                          break;// 中斷處理
                                      }
                                      // i到30后清零。并將進度條重新來過
                                      if ((++i) == 30) {
                                          i = 0;
                                          monitor.beginTask("正在執行中......", 30);
                                      }
                                      // 進度條每前進一步體息一會,不用太長或太短,時間可任意設。
                                      try {
                                          Thread.sleep(99);
                                      } catch (Throwable t) {}
                                      monitor.worked(1);// 進度條前進一步
                                  }
                                  monitor.done();// 進度條前進到完成
                              }
                          };
                          try {
                              new ProgressMonitorDialog(s).run(true, true, runnable);
                          } catch (Exception e) {
                              e.printStackTrace();
                          }
                      }
                  });

           

              主要是使用兩個線程交替使用,第一個線程處理業務,第二個線程監控第一個線程查看它是否結束,如果結束或者被點擊cancele則停止進度條的進程,如果一直沒有關閉的指令,則反復開始---累加---結束---開始---累加---結束。

              我們幾乎是把陳剛的代碼原原本本的抄襲了一下,僅僅是替換了go()中的內容,但是發現一個問題

          new ProgressMonitorDialog(s).run(true, true, runnable);
          使用此句的話,JFace的線程永遠不會啟動;

          替換為

          new ProgressMonitorDialog(s).run(false, true, runnable);
          使用此句的話,JFace的線程可以啟動,運行正常,但是cancele不能響應,UI界面完全卡死!

              第一個參數的名字fork~乍看去,什么意思都沒有,但是看看API才發現內藏很大的玄機,如果為true則此線程為一個非UI線程,大家知道非UI線程是不會阻塞UI的;如果為false則此線程為一個UI線程,大家也知道UI線程如果使用不當很容易阻塞UI的。

              關鍵的問題是我們和陳剛的代碼幾乎一摸一樣他的進度條就啟動,我的進度條就不啟動!為什么?(這點至今不明白!)

              詳查API發現如果fork為false的時候還是另有洞天的:

          This implementation of IRunnableContext#run(boolean, boolean, IRunnableWithProgress) runs the given IRunnableWithProgress using the progress monitor for this progress dialog and blocks until the runnable has been run, regardless of the value of fork. The dialog is opened before the runnable is run, and closed after it completes. It is recommended that fork is set to true in most cases. If fork is set to false, the runnable will run in the UI thread and it is the runnable's responsibility to call Display.readAndDispatch() to ensure UI responsiveness.

          API中說的很明白,如果fork為false時需要在線程中調用Display.readAndDispatch()方法,以避免UI被阻塞!

          大家如果在JFace的開發中如果使用了進度條,發現UI被阻塞的話,就想想我哦!!!呵呵只用在進程中調用一下Display.readAndDispatch()就解決了!



          客戶虐我千百遍,我待客戶如初戀!

          posted on 2008-02-29 08:47 阿南 閱讀(3825) 評論(6)  編輯  收藏 所屬分類: Eclipse-SWT個人原創

          評論

          # re: JFace進度條使用經驗一則 2008-02-29 10:12 香草的天空

          這一點和win32api很像
            回復  更多評論    

          # re: JFace進度條使用經驗一則 2008-02-29 13:43 Matthew Chen

          我把你的代碼拷過來,用new ProgressMonitorDialog(s).run(true, true, runnable); 好像可以用啊,進度條走了幾次就停下來,cancel也可以,沒出什么問題啊,我用swt3.3
            回復  更多評論    

          # re: JFace進度條使用經驗一則 2008-02-29 17:26 阿南

          首先我上面貼的代碼是沒有問題的!
          其次多看幾遍
          “我討論的進度條主要是JFace的進度條,RCP已經提供了完善的Job組件,為什么還要用JFace的進度條呢?原因是我要在登陸界面上做進度處理,也就是使用Eclipse3.3提供的AbstractSplashHandler特性,可以將原有的啟動畫面替換成為一個登陸界面,啟動這個登陸界面時,Eclipse的Platform此時還沒有啟動,所以不能使用RCP本身的Job組件了。”
            回復  更多評論    

          # re: JFace進度條使用經驗一則 2008-03-01 10:01 pice

          在go()方法中你用一個for循環來假設正在執行的業務調用,如果go方法中就一個方法調用,但是這個方法執行時間比較長。private void go() {
          dbSelectList();//查詢數據庫,查詢時間大約10秒
          stopFlag = true;// 執行完畢后把標志位設為停止,好通知給進度框
          System.out.println("全部任務執行完畢");
          }
          這時進度條的cancel按鈕就不起作用了,不管是否點擊cancel按鈕dbSelectList()方法都將執行完畢后進度條才注銷。就算是重寫進度條的cancelPressed()方法關閉UI線程使得進度條界面“消失”,但是dbSelectList()方法還是會繼續執行完。
          進度條能應對這樣的情況嗎?
            回復  更多評論    

          # re: JFace進度條使用經驗一則 2008-03-02 14:46 xifu

          比javascript簡約啊
            回復  更多評論    

          # re: JFace進度條使用經驗一則 2010-05-09 10:38 靈均

          做個手機收發短信軟件
            回復  更多評論    
          主站蜘蛛池模板: 南京市| 海宁市| 石城县| 昌都县| 明溪县| 伊川县| 延川县| 浪卡子县| 武胜县| 尼木县| 云安县| 汝阳县| 平谷区| 万山特区| 云霄县| 麻阳| 郧西县| 铜山县| 横山县| 商水县| 焉耆| 郸城县| 广宗县| 泗水县| 滦平县| 新乡县| 高州市| 富川| 东丽区| 泗水县| 马鞍山市| 泸水县| 山丹县| 高雄县| 黄骅市| 五常市| 积石山| 朔州市| 仁怀市| 京山县| 汤阴县|