0

スレッドAを開始して実行する操作リスナーがあります。操作が完了すると、スレッドAが停止し、ダイアログウィンドウが閉じます。

UNKNOWNというシンプルなプログレスバーを作成しました。主に、平均稼働時間を取得する方法がないためです。時間はさまざまな要因に基づいています。そのため、TOTAL_TIMEをかなり高く設定しました。

ダイアログが閉じる直前に、どういうわけかプログレスバースレッドを停止したいと思います。

ProgressBarThread

 class ProgressBarThread implements IRunnableWithProgress {
  private static final int TOTAL_TIME = 5000;
  private static final int INCREMENT = 1000;

  public ProgressBarThread() {

  }

  public void run(IProgressMonitor monitor) throws InvocationTargetException,InterruptedException {
     monitor.beginTask("Sending Plot", IProgressMonitor.UNKNOWN);
     for (int total = 0; total < TOTAL_TIME ; total += INCREMENT) {
        Thread.sleep(INCREMENT);
        monitor.worked(INCREMENT);
        if (total == TOTAL_TIME / 2) monitor.subTask("Please be patient... Operation should finish soon.");
    }
    monitor.done();

  }

OperationListener-操作が戻ったときにウィンドウを閉じます

 public abstract class MyOperationListener implements InterfaceAIFOperationListener {

  AplotPlotterDialog w = null;

  public MyOperationListener(AplotPlotterDialog 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();

}

ProgressBarを開始するメソッド

  public void startProgressBar() {
  try {
     new ProgressMonitorDialog(getShell()).run(true, false,
        new ProgressBarThread());
  } 
  catch (InvocationTargetException e) {
     MessageDialog.openError(getShell(), "Error", e.getMessage());
  }  
  catch (InterruptedException e) {
     MessageDialog.openInformation(getShell(), "Cancelled", e.getMessage());
  }

}

操作方法とProgressBarの開始場所

 public void startPrintOperation() {
  Display.getDefault().asyncExec(new Runnable() {
     public void run() {
        startProgressBar();
     }
  });
  final ArrayList<PlotData> datasetData =  AplotPlotDataModel.getInstance().getPlotDataArray();
  plotOp = new AplotPlotOperation(appReg.getString("aplot.message.PLOTTING"),datasetData, getPlottersData(), getSpinnerValue(), session);
  plotOp.addOperationListener(new MyOperationListener(this) {
     public void endOperationImpl() {
        try {
           plotResults = (ArrayList) plotOp.getPlotResults();
           for (int i = 0; i < plotResults.size(); ++i) {
                            AplotResultsDataModel.getInstance().addEntry((AplotPlotResultsParser.DatasetPlotResult) plotResults.get(i));
           } // end for
        }
        catch (Exception e) {
           e.printStackTrace();
        }
        finally {
           plotOp.removeOperationListener(this);
           plotOp = null;
           Display.getDefault().asyncExec(new Runnable() {
              public void run() {
                 baseDialog.removeAllTableRows();
                 AplotPlotDataModel.getInstance().clearPlotDataArray();
              }
           });
        }
     }
  });
  session.queueOperation(plotOp);
} 

- - - - - - - - - - - - 編集 - - - - - - - - -

これは私が@Seriousであるという提案を実装しようとする方法です。

ProgressBarクラスに加えられた変更

class ProgressBarThread implements IRunnableWithProgress  {
  private static final int TOTAL_TIME = 10000;
  private static final int INCREMENT = 1000;
  private Condition done = null;

  public ProgressBarThread(Condition done) {
     this.done = done;
  }

  public void run(IProgressMonitor monitor) throws InvocationTargetException,InterruptedException {
     monitor.beginTask("Creating PDF File(s)", IProgressMonitor.UNKNOWN);
     for (int total = 0; total < TOTAL_TIME ; total += INCREMENT) {
        if (done.await(INCREMENT, TimeUnit.MILLISECONDS))
        {
           break;
        }
        monitor.worked(INCREMENT);
        if (total == TOTAL_TIME / 2) monitor.subTask("Please be patient... Operation should finish soon.");
     }
    monitor.done();
  }
}

これはMyOperationLisnterクラスへの変更です

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

  public MyOperationListener(AplotCreatePDFDialog win) {
     w = win;
     Lock lock = new ReentrantLock();
     done = lock.newCondition();
  } 

  public void startOperation(String startMessage) {
     Display.getDefault().asyncExec(new Runnable() {
        public void run() {
     startProgressBar();
        }
     });
  }

  public void startProgressBar() {
     try {
        new ProgressMonitorDialog(getShell()).run(true, false,
        new ProgressBarThread(done));
     } 
     catch (InvocationTargetException e) {
        MessageDialog.openError(getShell(), "Error", e.getMessage());
     }  
     catch (InterruptedException e) {
        MessageDialog.openInformation(getShell(), "Cancelled", e.getMessage());
     }
  }

  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());
              done.signal();
              w.close();
           }
        });
     }
  } 
  abstract protected void endOperationImpl();
} 

DialiogクラスからstartProgressBarメソッドを削除します。また、操作リスナーを開始するメソッドからstartProgressBarを削除しました

 private void startSavePdfOperation() {
  //Display.getDefault().asyncExec(new Runnable() {
  //   public void run() {
  //      startProgressBar();
   //  }
  //});
  saveOp = new AplotSaveOperation(appReg.getString("aplot.message.SAVETOPDF"), "PDF", session);
  saveOp.addOperationListener(new MyOperationListener(this) {<-- this is the start operation listener call.

結果:ProgressBarダイアログの代わりにエラーダイアログが表示されます。次のエラーも発生します

ここに画像の説明を入力してください

アプリケーションがフリーズします。

4

1 に答える 1

0

あなたは条件を待つことができます:

class ProgressBarThread implements IRunnableWithProgress
{
    private static final int TOTAL_TIME = 5000;
    private static final int INCREMENT = 1000;

    private Condition done = null;

    public ProgressBarThread(Condition done)
    {
        this.done = done;
    }

    public void run(IProgressMonitor monitor) throws InvocationTargetException,InterruptedException
    {
        monitor.beginTask("Sending Plot", IProgressMonitor.UNKNOWN);
        for (int total = 0; total < TOTAL_TIME ; total += INCREMENT)
        {
            if (done.await(INCREMENT, TimeUnit.MILLISECONDS))
            {
                break;
            }
            monitor.worked(INCREMENT);
            if (total == TOTAL_TIME / 2) monitor.subTask("Please be patient... Operation should finish soon.");
        }
        monitor.done();
    }
}

条件はメインプロセスによって作成されます:

AplotPlotterDialog w = null;

Condition done = null;

public MyOperationListener(AplotPlotterDialog win)
{
    w = win;
    Lock lock = new ReentrantLock();
    done = lock.newCondition();
} 

public void startProgressBar()
{
    try
    {
        new ProgressMonitorDialog(getShell()).run(true, false,
        new ProgressBarThread(done));
    } 
    catch (InvocationTargetException e)
    {
        MessageDialog.openError(getShell(), "Error", e.getMessage());
    }  
    catch (InterruptedException e)
    {
        MessageDialog.openInformation(getShell(), "Cancelled", e.getMessage());
    }
}

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());
        done.signal();
        w.close();
    }
    });
    }
}

操作の進行中の動作は、現在のバージョンと同じになります。

しかし、メインプロセスが完了すると、状態を通知することにより、ループをすぐに終了するプログレスバースレッドに通知します。

于 2013-01-11T23:00:06.057 に答える