我有一个操作监听器,它启动并运行线程A.当操作完成时,线程A停止,对话窗口关闭。
我创建了一个简单的进度条,它是UNKNOWN。主要是因为没有办法获得平均操作时间。时间基于各种因素。所以,我将TOTAL_TIME设置得相当高。
我想在Dialog关闭之前停止进度条线程。
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);
}
------------------------ EDIT ---------------- -
这就是我试图实施@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 Class的更改
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方法。 我还从启动Operation Listener的方法中删除了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对话框。我也收到以下错误
并且应用程序冻结。
答案 0 :(得分: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();
}
});
}
}
当操作正在进行时,行为将与您当前的版本相同。
但是当主进程完成时,它将通过发出条件信号通知将立即退出循环的进度条线程。