jface_使用JFace Viewer延迟获取模型元素
jface
Eclipse JFace Viewers顯示的模型元素有時需要花費大量時間來加載。 因此, 工作臺提供了IDeferredWorkbenchAdapter類型以在后臺獲取此類模型元素。 不幸的是,似乎僅通過DeferredTreeContentManager派生的AbstractTreeViewer支持此機制。
因此,我開發(fā)了自己的通用DeferredContentManager …它可以為允許添加和刪除模型元素的所有StructuredViewer類型進行后臺加載。 在這篇文章中,我解釋了它是如何工作的以及如何使用。
在需要(重新)使用TableViewer進行后臺獲取的情況下,我只發(fā)現(xiàn)了一個與此主題相關(guān)的舊的,尚未解決的平臺錯誤 。 但是我懷疑問題所提議的為表查看器實現(xiàn)額外內(nèi)容管理器的解決方案是否會非常明智。 因此,我決定嘗試一個基于可用的樹特定實現(xiàn)的概念的自制通用解決方案。
使用JFace Viewer延遲獲取內(nèi)容
在JFace Viewers中處理長加載模型元素的基本原理很簡單。 與其直接在IContentProvider#getElements(Object)獲取內(nèi)容, IContentProvider#getElements(Object)數(shù)據(jù)檢索委托給在后臺作業(yè)中執(zhí)行該操作的特定適配器。
此外,委托的getElements(Object)實現(xiàn)返回一個placeholder 。 只要發(fā)生數(shù)據(jù)加載,查看器就會顯示出來。 同時,收集的數(shù)據(jù)將轉(zhuǎn)發(fā)到更新作業(yè) 。 后者將元素附加到結(jié)構(gòu)化查看器。 由于僅允許通過UI線程執(zhí)行的代碼進行SWT小部件訪問,因此更新作業(yè)是UIJob 。
最后,在完成后臺獲取后,清理作業(yè)將刪除占位符。
不應(yīng)將延遲獲取內(nèi)容與使用SWT.VIRTUAL標志的元素的延遲加載相混淆。 盡管兩種方法之間存在相似之處,但虛擬表和樹通常可用于按需加載大型數(shù)據(jù)集。
延遲加載對于大小合理的數(shù)據(jù)集很有幫助,但是,數(shù)據(jù)集的檢索可能很耗時,因此會阻塞UI線程。 例如,考慮獲取遠程數(shù)據(jù)。 萬一您想知道,這兩種方法當然是互斥的 ……
IDeferredWorkbenchAdapter
從開發(fā)人員的角度來看, IDeferredWorkbenchAdapter是必經(jīng)之路。 它是IWorkbenchAdapter的擴展,通常負責(zé)“為工作臺元素提供視覺表示和層次結(jié)構(gòu),使它們可以在UI中顯示,而不必知道元素的具體類型”(如其javadoc所述) 。
該擴展聲明了其他方法來支持延遲獲取給定數(shù)據(jù)元素的子代,并且可以由適配器工廠進行注冊。 考慮一個簡單的pojo作為模型元素,例如:
public class ModelElement {[...] }為了從域類中抽象視覺呈現(xiàn)和后臺加載,請?zhí)峁┻m當?shù)倪m配器實現(xiàn)…
public class ModelElementAdapterimplements IDeferredWorkbenchAdapter {[...] }…并使用適配器工廠將這兩種類型映射在一起:
public class ModelElementAdapterFactoryimplements IAdapterFactory {@Overridepublic Object getAdapter( Object adaptableObject, Class adapterType ) {return new ModelElementAdapter();}@Overridepublic Class[] getAdapterList() {return new Class[] { ModelElement.class };} }有關(guān)使用IAdaptable , IWorkbenchAdapter和IAdaptableFactory更多信息,您可以看看如何使用IAdaptable和IAdapterFactory? 。 遺憾的是,默認工作臺內(nèi)容和標簽提供程序希望模型元素實現(xiàn)IAdaptable 。 但是,可以使用自定義提供程序來規(guī)避此問題。
以下測試草圖驗證了元素適應(yīng)是否按預(yù)期進行:
@Test public void testAdapterRegistration() {IAdapterManager manager = Platform.getAdapterManager();ModelElementAdapterFactory factory = new ModelElementAdapterFactory();manager.registerAdapters( factory, ModelElement.class );Object actual = manager.getAdapter( new ModelElement(), ModelElement.class );assertThat( actual ).isInstanceOf( ModelElementAdapter.class ); }現(xiàn)在該實現(xiàn)ModelElementAdapter的數(shù)據(jù)檢索功能了。 這是通過fetchDeferredChildren方法完成的:
@Override public void fetchDeferredChildren(Object parent, IElementCollector collector, IProgressMonitor monitor ) {collector.add( loadData( parent ), monitor ); }private Object[] loadData( Object parent ) {return [...] }費時的數(shù)據(jù)加載顯然由loadData()方法處理。 將數(shù)據(jù)元素添加到IElementCollector會觸發(fā)上述更新作業(yè)。 如您所見,可以通過幾個步驟來劃分數(shù)據(jù)獲取,并且可以通過給定的IProgressMonitor報告進度。
DeferredContentManager
最后要做的是將本文中描述的機制與用于描述模型元素的查看器實例連接起來。 為此, DeferredContentManager可以調(diào)整任意查看器并將元素檢索委托給相應(yīng)的IDeferredWorkbenchAdapter實現(xiàn)。
class ModelElementContentProviderimplements IStructuredContentProvider {DeferredContentManager manager;@Overridepublic void inputChanged(Viewer viewer, Object oldInput, Object newInput ){TableViewerAdapter adapter = new TableViewerAdapter( ( TableViewer )viewer );manager = new DeferredContentManager( adapter );}@Overridepublic Object[] getElements( Object inputElement ) {return manager.getChildren( inputElement );}[...] }自定義IStructuredContentProvider用于在其inputChanged方法中調(diào)整查看器。 getElements的實現(xiàn)將委托給內(nèi)容管理器,后者再使用DeferredContentManager#getChildren將元素加載委托給模型元素適配器。
進行提取時,將返回一個占位符元素,以在查看器中顯示“ Pending…”標簽。 這是左側(cè)標題圖像中所示的情況。 在右側(cè),檢索已完成,并且占位符已刪除。
StructuredViewerAdapter
查看示例,可以清楚地了解DeferredContentManager如何支持不同的查看器類型。 內(nèi)容管理器使用適當?shù)呐缮鶶tructuredViewerAdapter來修改查看器。 目前,只有用于抽象樹形和表形查看器的默認適配器可用。
但是,直接為其他結(jié)構(gòu)化查看器類型編寫適配器是很容易的。 以下代碼段顯示了例如ListViewer的實現(xiàn):
public class ListViewerAdapterextends StructuredViewerAdapter {public ListViewerAdapter( AbstractListViewer listViewer ) {super( listViewer );}@Overridepublic void remove( Object element ) {viewer.remove( element );}@Overridepublic void addElements( Object parent, Object[] children ) {viewer.add( children );} }在示例中,使用此選項并將表查看器替換為列表查看器將導(dǎo)致以下結(jié)果:
涼! 是不是
結(jié)論
這篇文章介紹了DeferredContentManager并展示了它如何啟用使用不同的JFace Viewer進行的模型元素的后臺加載。 并且,在上面引人注目的用法解釋之后,如果您可能想知道從哪里獲得它,那么您將在Xiliary P2存儲庫中找到它。 內(nèi)容管理器是com.codeaffine.eclipse.ui功能的一部分:
- http://fappel.github.io/xiliary
如果您想查看代碼或提出問題,也可以查看Xiliary GitHub項目:
- https://github.com/fappel/xiliary
翻譯自: https://www.javacodegeeks.com/2014/12/deferred-fetching-of-model-elements-with-jface-viewers.html
jface
總結(jié)
以上是生活随笔為你收集整理的jface_使用JFace Viewer延迟获取模型元素的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux被入侵如何溯源(linux被入
- 下一篇: junit rule_使用@Rule在J