使用JFace Viewer延迟获取模型元素
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 Viewer延迟获取模型元素相关推荐
- jface_使用JFace Viewer延迟获取模型元素
jface Eclipse JFace Viewers显示的模型元素有时需要花费大量时间来加载. 因此, 工作台提供了IDeferredWorkbenchAdapter类型以在后台获取此类模型元素. ...
- 深入css布局 (1) — 盒模型 元素分类
深入css布局(1)-- 盒模型 & 元素分类 " 在css知识体系中,除了css选择器,样式属性等基础知识外,css布局相关的知识才是css比较核心和重要的点.今天我们来深 ...
- 额外参数_Pytorch获取模型参数情况的方法
分享人工智能技术干货,专注深度学习与计算机视觉领域! 相较于Tensorflow,Pytorch一开始就是以动态图构建神经网络图的,其获取模型参数的方法也比较容易,既可以根据其内建接口自己写代码获取模 ...
- web api、获取DOM元素的方式、事件理解、click事件在移动端300ms延时、事件对象、事件委托、常见事件类型
web api: API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力 ...
- Knockout获取数组元素索引的2种方法,在MVC中实现
在遍历数组.集合的时候,通常要获取元素的索引,本篇体验使用Knockout获取索引的2种方法. 假设有这样的一个模型: namespace UseIndex.Models {public class ...
- pytorch中获取模型参数
原文链接:pytorch中获取模型参数:state_dict和parameters两个方法的差异比较_造未来-CSDN博客 一.本文的模型案例 代码如下: import torch import to ...
- vue 获取id元素_.vue组件中获取DOM元素问题
一.问题引入 原项目把一块内容直接写在了模块中(浏览器显示的一整个页面),现在想把它提成一个单独组件,而且把其中使用document.getElementById('id')改为ref获取元素的形式. ...
- [转载] js 下获取子元素的方法 -- 李富生
地址:https://www.cnblogs.com/web-fusheng/p/6816440.html firstElementChild只会获取元素节点对象,从名称就可以看出来,firstChi ...
- C#开发BIMFACE系列19 服务端API之获取模型数据4:获取多个构件的共同属性
系列目录 [已更新最新开发文章,点击查看详细] 在前几篇博客中介绍了一个三维文件/模型包含多个构建,每个构建又是由多种材质组成,每个构建都有很多属性.不同的构建也有可能包含相同的属性. 上图中 ...
最新文章
- 很多程序员编程时都戴耳机?他们在听什么
- oracle重新启动步骤
- 数据恢复knowledge
- 今年2月的微盟“删库”主角被判 6 年有期徒刑
- 说一说ffmpeg到处都在使用的ff_thread_once函数
- redis key设计技巧
- cad lisp 二次抛物线_学习CAD的五个段位,你是青铜还是王者?
- Linux虚拟内存管理 | 虚拟地址与物理地址映射、段错误SIGSEGV
- 挂载本地目录到Virtualbox并解决[mounting failed with the error: Protocol error]错误
- vCenter上解决”此主机当前没有管理网络冗余“的警告
- PPT封面怎样设计才更赏心悦目
- 专访哈佛公共卫生学院院长胡里奥·弗兰克
- 一键获取graphpad同款主题
- 中国与印度软件工程师的比较
- <img>标签上title属性与alt属性的区别
- 自动调制分类发展历程
- solidworks螺纹线画法
- nginx error_log 日志配置
- BUUCTF·[网鼎杯 2020 青龙组]boom·WP
- Learning by Fixing: Solving Math Word Problems with Weak Supervision论文阅读