使用JFace Viewer延迟获取模型元素
Eclipse JFace Viewers顯示的模型元素有時(shí)需要花費(fèi)大量時(shí)間來加載。 因此, 工作臺(tái)提供了IDeferredWorkbenchAdapter類型以在后臺(tái)獲取此類模型元素。 不幸的是,似乎僅通過DeferredTreeContentManager派生的AbstractTreeViewer支持此機(jī)制。
因此,我開發(fā)了自己的通用DeferredContentManager …它可以為允許添加和刪除模型元素的所有StructuredViewer類型進(jìn)行后臺(tái)加載。 在這篇文章中,我解釋了它是如何工作的以及如何使用。
在需要(重新)使用TableViewer進(jìn)行后臺(tái)獲取的情況下,我僅發(fā)現(xiàn)了一個(gè)與該主題有關(guān)的古老且尚未解決的平臺(tái)錯(cuò)誤 。 但是,我懷疑問題所提議的為表查看器實(shí)現(xiàn)額外內(nèi)容管理器的解決方案是否會(huì)非常明智。 因此,我決定嘗試一個(gè)基于可用樹特定實(shí)現(xiàn)的概念的自制通用解決方案。
使用JFace Viewer延遲獲取內(nèi)容
在JFace Viewers中處理長加載模型元素的基本原理很簡單。 與其直接在IContentProvider#getElements(Object)獲取內(nèi)容, IContentProvider#getElements(Object)數(shù)據(jù)檢索委托給在后臺(tái)作業(yè)中執(zhí)行該操作的特定適配器。
此外,委托的getElements(Object)實(shí)現(xiàn)返回一個(gè)placeholder 。 只要發(fā)生數(shù)據(jù)加載,查看器就會(huì)顯示出來。 同時(shí),收集的數(shù)據(jù)將轉(zhuǎn)發(fā)到更新作業(yè) 。 后者將元素附加到結(jié)構(gòu)化查看器。 由于僅允許從UI線程執(zhí)行的代碼進(jìn)行SWT小部件訪問,因此更新作業(yè)是UIJob 。
最后,在完成后臺(tái)獲取后,清理作業(yè)將刪除占位符。
不應(yīng)將延遲獲取內(nèi)容與使用SWT.VIRTUAL標(biāo)志的元素的延遲加載相混淆。 盡管兩種方法之間存在相似之處,但虛擬表和樹通常可用于按需加載大型數(shù)據(jù)集。
延遲加載對于大小合理的數(shù)據(jù)集很有幫助,但是,數(shù)據(jù)集的檢索可能很耗時(shí),因此會(huì)阻塞UI線程。 例如,考慮獲取遠(yuǎn)程數(shù)據(jù)。 萬一您想知道,這兩種方法當(dāng)然是互斥的 ……
IDeferredWorkbenchAdapter
從開發(fā)人員的角度來看, IDeferredWorkbenchAdapter是必經(jīng)之路。 它是IWorkbenchAdapter的擴(kuò)展,通常負(fù)責(zé)“為工作臺(tái)元素提供可視化表示和層次結(jié)構(gòu),使它們可以在UI中顯示而不必知道元素的具體類型”(如其javadoc所述) 。
該擴(kuò)展聲明了其他方法來支持對給定數(shù)據(jù)元素的子代進(jìn)行延遲獲取,并且可以由適配器工廠進(jìn)行注冊。 考慮一個(gè)簡單的pojo作為模型元素,例如:
public class ModelElement {[...] }為了從域類中抽象視覺呈現(xiàn)和后臺(tái)加載,請?zhí)峁┻m當(dāng)?shù)倪m配器實(shí)現(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? 。 遺憾的是,默認(rèn)工作臺(tái)內(nèi)容和標(biāo)簽提供程序希望模型元素實(shí)現(xiàn)IAdaptable 。 但是,可以使用自定義提供程序來規(guī)避此問題。
以下測試草圖驗(yàn)證了元素適應(yīng)是否按預(yù)期進(jìn)行:
@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)在是時(shí)候?qū)崿F(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 [...] }費(fèi)時(shí)的數(shù)據(jù)加載顯然由loadData()方法處理。 將數(shù)據(jù)元素添加到IElementCollector會(huì)觸發(fā)上述更新作業(yè)。 如您所見,可以通過幾個(gè)步驟來劃分?jǐn)?shù)據(jù)獲取,并且可以通過給定的IProgressMonitor報(bào)告進(jìn)度。
DeferredContentManager
最后要做的是將本文中描述的機(jī)制與用于描述模型元素的查看器實(shí)例連接起來。 為此, DeferredContentManager可以調(diào)整任意查看器并將元素檢索委托給相應(yīng)的IDeferredWorkbenchAdapter實(shí)現(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的實(shí)現(xiàn)將委托給內(nèi)容管理器,后者再使用DeferredContentManager#getChildren將元素加載委托給模型元素適配器。
在進(jìn)行提取時(shí),將返回一個(gè)占位符元素,以在查看器中顯示“ Pending…”標(biāo)簽。 這是左側(cè)標(biāo)題圖像中所示的情況。 在右側(cè),檢索已完成,并且占位符已刪除。
StructuredViewerAdapter
查看示例,可以清楚地了解DeferredContentManager如何支持不同的查看器類型。 內(nèi)容管理器使用適當(dāng)?shù)呐缮鶶tructuredViewerAdapter來修改查看器。 目前,只有用于抽象樹形和表形查看器的默認(rèn)適配器可用。
但是,直接為其他結(jié)構(gòu)化查看器類型編寫適配器是很容易的。 以下代碼段顯示了例如ListViewer的實(shí)現(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 );} }在示例中,使用此選項(xiàng)并將表查看器替換為列表查看器將導(dǎo)致以下結(jié)果:
涼! 是不是
結(jié)論
這篇文章介紹了DeferredContentManager并展示了它如何啟用使用不同的JFace Viewer進(jìn)行的模型元素的后臺(tái)加載。 并且,在上面引人注目的用法解釋之后,如果您可能想知道從哪里獲得它,那么您將在Xiliary P2存儲(chǔ)庫中找到一個(gè)。 內(nèi)容管理器是com.codeaffine.eclipse.ui功能的一部分:
- http://fappel.github.io/xiliary
如果您想看一下代碼或提出問題,也可以看一下Xiliary GitHub項(xiàng)目:
- https://github.com/fappel/xiliary
翻譯自: https://www.javacodegeeks.com/2014/12/deferred-fetching-of-model-elements-with-jface-viewers.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的使用JFace Viewer延迟获取模型元素的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux系统安装U盘(linux系统安
- 下一篇: (ddos 传统抵御方法)