2

在我的 GUI 中,我有一个 PDF 文件创建操作。该操作最多可能需要 10-15 秒才能完成。当我开始操作时,我给它附加了一个监听器。侦听器更改光标并禁用 GUI,直到操作完成。
我还想添加一个进度条,这样用户就会知道它什么时候完成。

创建了一个方法 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();

上面的代码创建了 ProgressBar。问题是操作将在进度条指示器接近结束之前结束。

问题:这是因为在方法中我正在创建一个新线程,而指标是根据新线程而不是操作线程更新的吗?

问题:是否可以创建一个新线程来监视 GUI 线程并相应地更新进度条?

阅读建议将 ProgressMonitorDialog 与 IRunnableWithProgress 一起使用的文章。

使用 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...

 }

似乎它在线程和更新方面会遇到与上面的代码相同的问题。

问题:所以现在我在想我可以将 ProgressBar 添加或更新到我现有的 Listener

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

感谢您对此提供的任何帮助。

编辑

Baz,您在下面的回答正是问题所要求的,所以感谢您的回答。

但是我开始认为我想做的事情是不可能的。当我的操作开始时,我希望进度条指示器开始,当我的操作结束时,我希望指示器在最后并且监视器会关闭。

我认为可能有一种方法可以使用我的侦听器来添加进度条。类似于以下内容。

 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

但我开始看到 ProgressBar 必须进行某种测量才能正确显示指标。

如果指示器只是来回走动并且显示器会在操作结束时关闭,我会很高兴。

4

1 回答 1

2

为什么不使用ProgressMonitorDialog

是我的一个相关答案,展示了一个简单的例子。

这是它的样子:

在此处输入图像描述


如果您不确定工作负载,请使用以下代码:

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

它会在运行时显示空闲栏。

于 2012-12-11T21:23:52.793 回答