ProgressMonitorDialog - 监视活动线程以更新监视器

时间:2012-12-11 21:09:11

标签: java multithreading swt progress-bar

在我的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必须有某种测量才能正确显示指标。

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

1 个答案:

答案 0 :(得分:2)

为什么不使用ProgressMonitorDialog

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

这就是它的样子:

enter image description here


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

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

它会在跑步时显示空闲栏。