延時執行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) {
}
[] [] [] [] [] []
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27700.html