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 };}
}

有关使用IAdaptableIWorkbenchAdapterIAdaptableFactory更多信息,您可以看看如何使用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338726.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php第一课,[php第一课]php简介

学习php前提:应有html与css知识1、php简介[1]php是一种开源通用服务器端脚本语言。[2]php:hypertext preprocessor,译名为超文本预处理器[3]在服务器上执行[4]php文件:{1}php文件包含文本、html、js、php代码{2}服务器上运行&…

python省略_在python中如何连接用省略号(…)分隔的连续行

您只需:delim ...text This is single line.This is second long line... continue from previous line.This third single line.# here were building a list containing each line# well clean up the leading and trailing whitespace# by mapping Pythons str…

C语言边角料:结构体中指针类型的成员变量,它的类型重要吗?

一、前言昨天在编译代码的时候,之前一直OK的一个地方,却突然出现了好几个 Warning!本着强迫症要消灭一切警告的做法,最终定位到:是结构体内部, 指向结构体类型的指针成员变量导致的问题。这个问题,也许永远…

oracle 11g b表空间什么情况下自动增加,Oracle 11g表空间——创建和扩展(永久)表空间...

Oracle 11g表空间——创建和扩展(永久)表空间本文内容创建(永久)表空间查看表空间扩展表空间创建(永久)表空间Oracle 按照区和段空间进行管理表空间。区管理方式 - 针对区的分配方式的不同,有两种方式:字典管理方式(dictionary-managed tablespace&#…

python rsa 公钥解密_python利用rsa库做公钥解密的方法教程

前言对于RSA的解密,即密文的数字的 D 次方求mod N 即可,即密文和自己做 D 次乘法,再对结果除以 N 求余数即可得到明文。D 和 N 的组合就是私钥(private key)。算法的加密和解密还是很简单的,可是公钥和私钥的生成算法却不是随意的…

oracle 11g release2版本jdbc,Oracle发布JDeveloper11gRelease2更新版

Oracle在周二的时候发布了JDeveloper IDE升级版JDeveloper 11g Release 2,该版本支持JSF 2.0技术和模块化的服务端Web UI开发;另外该版本在启动时间上和运行性能上也有很大改善,因为整个IDE重新架构了,基于OSGi后端结构&#xff0…

C语言:--位域和内存对齐

位域位域是指信息在保存时,并不需要占用一个完整的字节,而只需要占几个或一个二进制位。为了节省空间,C语言提供了一种数据结构,叫“位域”或“位段”。“位域“是把一个字节中的二进位划分为几个不同的区域,并说明每个…

python页面驱动mxd_如何利用python 批量导出mxd至jpg

展开全部你好,arcpy.mapping提供了如下的函32313133353236313431303231363533e78988e69d8331333335313835数:arcpy.mapping 函数AddLayer(data_frame, add_layer, {add_position})AddLayerToGroup(data_frame, target_group_layer, add_layer, {add_posi…

junit rule_使用@Rule在JUnit中测试文件和目录

junit rule多亏了TemporaryFolder Rule在JUnit中使用文件和目录进行测试很容易。 在JUnit中,规则( Rule )可以用作夹具设置和清除方法( org.junit.Before , org.junit.After , org.junit.BeforeClass和org…

oracle 递归计算,SQL(Oracle)中的递归计算

好吧,我想我已经有了解决方案.这些数字与你的数字有点不同,但我相当确定我的正在做你想要的.我们可以在第1步和第1步中完成所有工作. 2使用单个查询(main_sql).必须使用递归语句(recur_sql)完成3和4.with main_sql as (select a.*,b.*,sum(a_amt) over (partition by b_id) as …

C语言实现数据字节序交换的四种方式

1关于数据字节序的说明1)关于字节序的说明字节序有两种大端和小端。大端:数据高位存放在低地址,地位放在高地址。如0x12345678在内存中存放为地址从左到右为低到高12345678。 小端:数据地位存放在低地址,高位存放在高地…

python 抓取微博评论破亿_一篇文章教会你使用Python定时抓取微博评论

【Part1——理论篇】试想一个问题,如果我们要抓取某个微博大V微博的评论数据,应该怎么实现呢?最简单的做法就是找到微博评论数据接口,然后通过改变参数来获取最新数据并保存。首先从微博api寻找 抓取评论的接口,如下图…

cassandra 入门_Apache Cassandra和Java入门(第一部分)

cassandra 入门在此页面上,您将学到足够的知识以开始使用NoSQL Apache Cassandra和Java,包括如何安装,尝试一些基本命令以及下一步要做什么。 要求 要遵循本教程,您应该已经有一个正在运行的Cassandra实例,并且已经在…

C语言如何实现动态数组?

提出问题请问在c语言里如何实现动态大小的数组啊,比如说int a[N];,这里N的值可以在程序中定,或者有什么方法可以实现类似的功能?总之只要在编译时不用制定数组大小就行。分析问题嵌入式系统的内存是宝贵的,内存是否高效…

Oracle为什么装在XP系统,重装xp系统后oracle恢复方法

重装系统后oracle如何恢复呢?下面就给大家介绍一下重装系统后oracle的恢复方法1、我们安装数据库软件只需安装同版本的数据库软件,不需要创建数据库。最好安装在和原来数据库同样的%ORACLE_HOME%下,省得还要修改参数文件路径等。(直接覆盖原来的oracle即…

vba 当前文件名_VBA代码解决方案第77讲内容:如何导出文件

大家好,我们今日继续讲解VBA代码解决方案的第77讲内容:如何导出文件,形成一个文本文件,如果需要将工作表中的数据保存为文本文件,可以创建一个文本文件用于保存数据。应用于FileSystemObject对象的CreateTextFile方法创…

jboss调jvm参数_在同一台机器上启动多个JBoss A-MQ JVM

jboss调jvm参数因此,我最近没有写过很多博客-只是很忙。 但是,我新年的决心是写一些博客,分享一些我经常遇到的事情,即使这些简单的事情可能会帮助一些人。 因此,对于本条目,我将展示一种在单个计算机上启…

startup oracle 01012,ORA-01012:not logged on的解决办法

conn / as sysdba 报错ORA-01012: not logged on发生缘故原由:关闭数据库是shutdown 后面没有接关闭参数中的任何一个。nomal --->所有毗邻都断开时才气关闭;transactional --->守候事务竣事后,自动断开毗邻;immediate ---&…

常见的C语言字符串操作

#字符串倒序输出实现逻辑,通过strlen获取字符串长度,然后通过 len/2 进行交叉赋值,这里需要注意,不需要考虑len是奇数还是偶数的问题。如果len是奇数,最后一个字符就不需要倒序,如果是偶数,最后…

mui 时间样式错乱_微信公众号素材样式中心在哪?公众号动态分割线怎么添加?...

相比于静态分割线,动态分割线更有特色,能给文章增加趣味性。今天壹姐就来给公众号运营的小伙伴们介绍,怎么添加动态的分割线样式到文章里吧~1怎么使用公众号样式中心公众号后台的编辑功能比较基础,想要使用好看的公众号素材&#…