延时执行Job避免无用的Job运行
我们经常需要根据选中的对象刷新我们部分的界面元素如果我们连续很快的改变选择而每次刷新界面涉及到的区域比较大时界面会出现闪烁从用户的角度来说我们很快的改变选择希望看到的只是最后选中的结果中间的界面刷新都是不必要的
在Jface中StructuredViewer提供了addPostSelectionChangedListener方法如果我们使用这个方法监听selectionChanged事件当用户一直按着方向键改变选中时我们只会收到一个selectionChanged事件这样我们可以避免过度的刷新界面
实际上Jface中就是通过延时执行Job来实现这一功能的我们也可以自己实现类似功能
private final static Object UPDATE_UI_JOBFAMILY = new Object();
tableviewer addSelectionChangedListener (new ISelectionChangedListener (){
public void selectionChanged(SelectionChangedEvent event){
JobgetJobManager()cancel(UPDATE_UI_JOBFAMILY);
new UIJob(更新界面) {
protected IStatus runInUIThread (IProgressMonitor monitor) {
//更新界面
return StatusOK_STATUS;
}
public boolean belongsTo(Object family){
return family== UPDATE_UI_JOBFAMILY;
}
}schedule();
}
});
首先我们需要将界面更新的代码放到一个UIJob中同时我们将Job延时毫秒执行(我们可以根据需要改变延时的时间)如果下一个selectionChanged事件很快到来我们的调用JobgetJobManager()cancel(UPDATE_UI_JOBFAMILY)将以前未运行的Job取消这样只有最后一个Job会真正运行
在UI线程中等待非UI线程的结束 有时我们在UI线程中需要等待一个非UI线程执行完我们才能继续执行例如我们在UI线程中要显示某些数据但是这些数据又需要从数据库或者远程网络获取于是我们会启动一个非UI的线程去获取数据而我们的UI线程必须要等待这个非UI线程执行完成我们才能继续执行当然一种简单的实现方法是使用join我们可以在UI线程中调用非UI线程的join方法这样我们就可以等待它执行完了我们再继续但是这会有一个问题当我们的UI线程等待时意味着我们的程序不会再响应界面操作也不会刷新这样用户会觉得我们的程序象死了一样没有反应这时我们可以使用ModalContext类你可以将你要执行的获取数据的任务用ModalContext的run方法来运行(如下)ModalContext会将你的任务放到一个独立的非UI线程中执行并且等待它执行完再继续执行与join方法不同的是ModalContext在等待时不会停止UI事件的处理这样我们的程序就不会没有响应了
try {
ModalContextrun(new IRunnableWithProgress(){
public void run(IProgressMonitor monitor)
throws InvocationTargetException InterruptedException {
/*需要在非UI线程中执行的代码*/
ModalContextcheckCanceled(monitor);
}
} true new NullProgressMonitor() DisplaygetCurrent());
} catch (InvocationTargetException e) {
} catch (InterruptedException e) {
}
[] [] [] [] [] []