jface_使用JFace Viewer延迟获取模型元素
jface
Eclipse JFace Viewers顯示的模型元素有時需要花費大量時間來加載。 因此, 工作臺提供了IDeferredWorkbenchAdapter類型以在后臺獲取此類模型元素。 不幸的是,似乎僅通過DeferredTreeContentManager派生的AbstractTreeViewer支持此機制。
因此,我開發了自己的通用DeferredContentManager …它可以為允許添加和刪除模型元素的所有StructuredViewer類型進行后臺加載。 在這篇文章中,我解釋了它是如何工作的以及如何使用。
在需要(重新)使用TableViewer進行后臺獲取的情況下,我只發現了一個與此主題相關的舊的,尚未解決的平臺錯誤 。 但是我懷疑問題所提議的為表查看器實現額外內容管理器的解決方案是否會非常明智。 因此,我決定嘗試一個基于可用的樹特定實現的概念的自制通用解決方案。
使用JFace Viewer延遲獲取內容
在JFace Viewers中處理長加載模型元素的基本原理很簡單。 與其直接在IContentProvider#getElements(Object)獲取內容, IContentProvider#getElements(Object)數據檢索委托給在后臺作業中執行該操作的特定適配器。
此外,委托的getElements(Object)實現返回一個placeholder 。 只要發生數據加載,查看器就會顯示出來。 同時,收集的數據將轉發到更新作業 。 后者將元素附加到結構化查看器。 由于僅允許通過UI線程執行的代碼進行SWT小部件訪問,因此更新作業是UIJob 。
最后,在完成后臺獲取后,清理作業將刪除占位符。
不應將延遲獲取內容與使用SWT.VIRTUAL標志的元素的延遲加載相混淆。 盡管兩種方法之間存在相似之處,但虛擬表和樹通常可用于按需加載大型數據集。
延遲加載對于大小合理的數據集很有幫助,但是,數據集的檢索可能很耗時,因此會阻塞UI線程。 例如,考慮獲取遠程數據。 萬一您想知道,這兩種方法當然是互斥的 ……
IDeferredWorkbenchAdapter
從開發人員的角度來看, IDeferredWorkbenchAdapter是必經之路。 它是IWorkbenchAdapter的擴展,通常負責“為工作臺元素提供視覺表示和層次結構,使它們可以在UI中顯示,而不必知道元素的具體類型”(如其javadoc所述) 。
該擴展聲明了其他方法來支持延遲獲取給定數據元素的子代,并且可以由適配器工廠進行注冊。 考慮一個簡單的pojo作為模型元素,例如:
public class ModelElement {[...] }為了從域類中抽象視覺呈現和后臺加載,請提供適當的適配器實現…
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 };} }有關使用IAdaptable , IWorkbenchAdapter和IAdaptableFactory更多信息,您可以看看如何使用IAdaptable和IAdapterFactory? 。 遺憾的是,默認工作臺內容和標簽提供程序希望模型元素實現IAdaptable 。 但是,可以使用自定義提供程序來規避此問題。
以下測試草圖驗證了元素適應是否按預期進行:
@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 ); }現在該實現ModelElementAdapter的數據檢索功能了。 這是通過fetchDeferredChildren方法完成的:
@Override public void fetchDeferredChildren(Object parent, IElementCollector collector, IProgressMonitor monitor ) {collector.add( loadData( parent ), monitor ); }private Object[] loadData( Object parent ) {return [...] }費時的數據加載顯然由loadData()方法處理。 將數據元素添加到IElementCollector會觸發上述更新作業。 如您所見,可以通過幾個步驟來劃分數據獲取,并且可以通過給定的IProgressMonitor報告進度。
DeferredContentManager
最后要做的是將本文中描述的機制與用于描述模型元素的查看器實例連接起來。 為此, DeferredContentManager可以調整任意查看器并將元素檢索委托給相應的IDeferredWorkbenchAdapter實現。
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方法中調整查看器。 getElements的實現將委托給內容管理器,后者再使用DeferredContentManager#getChildren將元素加載委托給模型元素適配器。
進行提取時,將返回一個占位符元素,以在查看器中顯示“ Pending…”標簽。 這是左側標題圖像中所示的情況。 在右側,檢索已完成,并且占位符已刪除。
StructuredViewerAdapter
查看示例,可以清楚地了解DeferredContentManager如何支持不同的查看器類型。 內容管理器使用適當的派生StructuredViewerAdapter來修改查看器。 目前,只有用于抽象樹形和表形查看器的默認適配器可用。
但是,直接為其他結構化查看器類型編寫適配器是很容易的。 以下代碼段顯示了例如ListViewer的實現:
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 );} }在示例中,使用此選項并將表查看器替換為列表查看器將導致以下結果:
涼! 是不是
結論
這篇文章介紹了DeferredContentManager并展示了它如何啟用使用不同的JFace Viewer進行的模型元素的后臺加載。 并且,在上面引人注目的用法解釋之后,如果您可能想知道從哪里獲得它,那么您將在Xiliary P2存儲庫中找到它。 內容管理器是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
總結
以上是生活随笔為你收集整理的jface_使用JFace Viewer延迟获取模型元素的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux被入侵如何溯源(linux被入
- 下一篇: junit rule_使用@Rule在J