1、使用Future表现一个费时的任务,可以极大地简化取消的实现。类似地,FutureTask中也有一个done钩子函数,可以方便任务完成后的通知,后台Callable完成后,会调用done,通过由done触发一个事件线程已经完成的任务。
2、构建BackgroundTask类,提供onCompletion钩子函数,同时还支持进度标识,compute方法调用setProgress来以数字形式指定进度,这会引起事件线程调用onProgress,更新用户接口,可视化显示进度。
3、代码:
abstract class BackgroundTask<V>implements Runnable,Future<V>{
private finalFutureTask<V> computation=newComputation();
private class Computation extendsFutureTask<V>{
public Computation(){
super(new Callable<V>)(){
public V call() throws Exception{
return BackgroundTask.this.compute();
}
});
}
protected final void done(){
GuiExecutor.instance().execute(newRunnable(){
public void run(){
Vvalue=null;
Throwable thrown=null;
booleancancelled=false;
try{
value=get();//得到计算完成的结果
}
catch(ExecutionException e){
thrown=e.getCause();
}
catch(CancellationException e){
cancelled=true;
}
catch(InterruptedExceptionconsumed){ }
finaly{
cnCompletion(value,thrown,cancelled);
}
};
});
}
}
protected void setProgress(final int current,final intmax){
GuiExecutor.instance().execute(new Runnable(){
public void run(){onProgress(current,max);}
});
}
//在后台线程中调用
protected abstract Vcompute() throws Exception;
//在事件线程中调用
protected voidonCompletion(V result,Throwable exeception,boolean cancelled){}
protected voidonProgress(int current,int max){}
}
startButton.addActionListener(new ActionListener(){
publicvoid actionPerformed(ActionEvent e){
class CancelListener implements ActionListener{
BackgroundTask<?>task;
public void actionPerformed(ActionEvent event){
if(task!=mull) task.cancel(true);
}
}
final CancelListener listener=newCancelListstener();
listener.task=newBackgroundTask<Void>(){
public void compute(){
while(moreWork()&&!isCancelled())
doSomeWork();
returnnull;
}
public void onCompletion(boolean cancelled,String s,Throwableexception){
cancelButton.removeActionListenr(listener);
label.setText("done");
}
};
cancelButton.addActionListener(listener);
backgroundExec.execute(listener.task);
}
});