2012-12-11 70 views
2

在我的GUI中,我有一個PDF文件創建操作。該操作可能需要10-15秒才能完成。當我開始操作時,我附加了一個監聽器。監聽器更改光標並禁用GUI,直到操作完成。
我也想添加一個進度條,這樣用戶就會知道它什麼時候會完成。ProgressMonitorDialog - 觀看活動線程以更新顯示器

創建一個方法startProgressBar()並從操作方法的開始調用它。
見下圖:

private void startSavePdfOperation() { 
     startProgressBar(); 
     saveOp = new AplotSaveOperation(appReg.getString("aplot.message.SAVETOPDF"), "PDF", session); 
     saveOp.addOperationListener(new MyOperationListener(this) { 

startProgressBar方法 - 見下:

public void startProgressBar() { 
    Shell shell = new Shell(getShell()); 
    shell.setSize(260, 120); 
    final ProgressBar bar = new ProgressBar(shell, SWT.SMOOTH); 
    bar.setBounds (20, 20, 200, 20); 
    shell.open(); 
    final int maximum = bar.getMaximum(); 
    new Thread(new Runnable() { 
    public void run() { 
     for (final int[] i = new int[1]; i[0] <= maximum; i[0]++) { 
     try {Thread.sleep (100);} catch (Throwable th) {} 
      if (Display.getDefault().isDisposed()) return; 
      Display.getDefault().asyncExec(new Runnable() { 
       public void run() { 
       if (bar.isDisposed()) return; 
       bar.setSelection(i[0]); 
       } 
      }); 
     } 
    } 
    }).start(); 

上面的代碼創建的進度。問題在於,進度條指標即將結束之前,操作就會結束。

問題:這是因爲在創建新線程的方法中,指標是根據新線程而不是操作線程更新的?

問題:是否可以創建一個觀察GUI線程並相應更新進度條的新線程?

閱讀一篇文章,建議在IRunnableWithProgress中使用ProgressMonitorDialog。

使用ProgressMonitorDialog 方法startProgressBar - 見下:

public void startProgressBar() { 
    ProgressMonitorDialog dialog = new ProgressMonitorDialog(getShell());  
    try { 
    dialog.run(true, true, new IRunnableWithProgress(){ 
      public void run(IProgressMonitor monitor) { 
       monitor.beginTask("Some nice progress message here ...", 100); 
       ** getThread(); ** 
       monitor.done(); 
      } 
     }); 
    } 
    catch (InvocationTargetException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 
    catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    } 
} 

public void getThread() { 
    new Thread etc.. etc... 

} 

它似乎將與線程和更新就像上面的代碼相同的問題。

問:所以,現在我想我可以再補充或更新進度,以我現有的監聽

OperationListener碼 - 見下:

public abstract class MyOperationListener implements InterfaceAIFOperationListener { 
    AplotCreatePDFDialog w = null; 

    public MyOperationListener(AplotCreatePDFDialog win) { 
    w = win; 
    } 
    public void startOperation(String startMessage) { 
    Display.getDefault().asyncExec(new Runnable() { 
     public void run() { 
      w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_WAIT)); 
      w.recursiveSetEnabled(getShell(), getShell().getEnabled()); 
      w.getShell().setEnabled(!getShell().getEnabled()); 
     } 
    }); 
    } 

    public void endOperation() { 
    try { 
     endOperationImpl(); 
    } 
    finally { 
     Display.getDefault().asyncExec(new Runnable() { 
      public void run() { 
       w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_ARROW)); 
       w.recursiveSetEnabled(getShell(), true); 
       w.getShell().setEnabled(!getShell().getEnabled()); 
       w.close(); 
      } 
     }); 
    } 
    } 
    abstract protected void endOperationImpl(); 
} // end class MyOperationListener 

感謝您的幫助,您可以給我有了這個。

編輯

巴茲,下面你的答案是什麼問題問,所以謝謝你的回答。

但是我開始認爲我想要做的事是不可能的。 當我的手術開始時,我希望進度條指示器開始,當手術結束時,我希望指示器在最後,顯示器將關閉。

我想可能有一種方法來使用我的偵聽器添加進度條。像下面這樣。

public void startOperation(String startMessage) { 
    Display.getDefault().asyncExec(new Runnable() { 
     public void run() { 
      ->monitor.beginTask("Creating PDF File(s)", IProgressMonitor.UNKNOWN);<- 
      w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_WAIT)); 
      w.recursiveSetEnabled(getShell(), getShell().getEnabled()); 
      w.getShell().setEnabled(!getShell().getEnabled()); 

     } 
    }); 
    } 
    public void endOperation() { 
    try { 
     ->monitor.worked(1);<- 
     endOperationImpl(); 
    } 
    finally { 
     Display.getDefault().asyncExec(new Runnable() { 
      public void run() { 
       w.getShell().setCursor(new Cursor(Display.getCurrent(), SWT.CURSOR_ARROW)); 
       w.recursiveSetEnabled(getShell(), true); 
       w.getShell().setEnabled(!getShell().getEnabled()); 
       ->monitor.done();<- 
       w.close(); 
      } 
     }); 
    } 
    } 
    abstract protected void endOperationImpl(); 

} //結束類MyOperationListener

但我開始看到進度條必須具有某種測量的正確顯示的指標。

如果指標剛好來回顯示,操作結束時顯示器會關閉,我會很高興。

回答

2

爲什麼不使用ProgressMonitorDialog

Here與我相關的答案是一個簡單的例子。

這是什麼樣子:

enter image description here


如果你不能確定工作量,使用此代碼:

monitor.beginTask("Copying files", IProgressMonitor.UNKNOWN); 

它會顯示閒置條而運行。

+0

我已經添加了ProgressMonitordialog的代碼。我創建了一個處理try和創建Dialog的方法。我添加了YourThread類。我應該在偵聽器的startOperation方法中調用progressbar方法嗎?我也明白工作量是衡量進度的方式。但我沒有平均的時間來完成操作。它可能需要5秒到20秒。所以我不確定如何處理工作量 - 但我更喜歡這個對話,並感謝您的幫助。 – jkteater

+0

@jkteater我用一些示例代碼編輯了我的答案,以處理未知的工作負載。至於代碼的位置。在聽衆中這樣做應該沒問題。 – Baz

+0

請參閱上面的編輯 – jkteater