`
Dollyn
  • 浏览: 165276 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

关于Eclipse中的选择服务(SelectionService)V1.0

阅读更多

翻译自下面文章。还没有完成翻译,因为最近没有精力做这个事情,又看到很多朋友遇到这方面的问题,先发上来。

http://www.eclipse.org/articles/Article-WorkbenchSelections/article.html

By Marc R. Hoffmann, Mountainminds GmbH & Co. KG, hoffmann@mountainminds.com

April 14, 2006

 

图片挂掉了,尽快修复。

 

摘要:

工作台提供的选择服务( Selection Service )允许工作台窗口中的不同部件( parts )之间进行有效的沟通。了解和使用现存的选择机制可以让你的插件有清楚的设计,有机地使他们和工作台结合,并向将来可能的扩展开放。

简介

Eclipse 工作台对于 IDE 和其他应用程序都是一个强大的 UI 框架。它为一个高度完整和可扩展的用户界面提供了很多服务。一个典型的综合应用就是那些在工作台窗口中,显示特定对象的额外信息,并且当选择的对象发生变化的时候自动更新相关信息的视图。例如,属性视图这样工作:无论在工作台窗口的哪个部件,一个元素被选中的时候,属性视图会自动显示这个元素的属性。

 

 

其他应用,比如全局操作的“ enable ”状态的转换也依赖于当前的选择。

插件可以使用所说的“选择服务”而不必实现一个紧耦合的通信机制。它可以减少有可以选中的条目的部件和其他对选择变化起作用的部件之间的耦合。

本文概述了选择服务的机制和用法。

蓝图

每个工作台窗口有它自己的选择服务的实例。这个服务追踪当前活动部件,并且向所有的注册的监听者传播选择改变事件。这种事件在当前布局中的选择改变或者当另外一个部件被激活的时候发生。这两种情况都可以由用户界面或者程序来触发。

 

元素或者文本被选中的视图不需要知道谁在关心这个选择。于是我们可以创建一个依赖于已经存在的视图中的选择的新视图而不必更改原视图中的任何一行代码。

下一节我们将介绍 (who) (whom) 提供什么样 (what) 的选择。

什么可以被选择?

从用户视图角度来讲,一个选择是指在表或者树控件中,高亮的实体的一个集合。一个选择还可以指在文本编辑器中的一段文本。在表象的背后,每个可视元素在工作台中都由一个 Java 对象描述。 JFace MVC 实现映射了领域模型和直观表示。

在内部,一个选择是一个保留了对应于工作台中选择的图形化的元素的模型对象的数据结构。前面已经指出,共有两种基本的选择类型:

一个对象列表

一段文本

每个选择都允许为空,比如一个空列表或者长度为 0 的字符串。在 Eclispe 体系中,这些数据结构由下列接口定义:

 

IStructuredSelection 代表了一个对象集合; ITextSelection IMarkSelection 描述了一段被选中的文本。

为方便使用,这些接口都有着默认的实现:

org.eclipse.jface.viewers.StructuredSelection

org.eclipse.jface.text.TextSelection

org.eclipse.jface.text.MarkSelection

这些实现被用在查看器( viewer )内部实现来吧底层的 SWT 事件转换为 ISelection 对象。这些实现在当元素需要以程序的方式被选中的使用也非常有用:

    ISelection sel = new StructuredSelection(presetElement);

    treeviewer.setSelection(sel);

将选择告知工作台窗口

所有的 JFace 查看器都是所谓的 选择提供者。选择提供者实现 ISelectionProvider 接口:

不同的 JFace 查看器使用和传播不同类型的选择:

Viewer                          Selection Type

ComboViewer                   IStructuredSelection

ListViewer                       IStructuredSelection

TreeViewer                      IStructuredSelection  

+- CheckboxTreeViewer         IStructuredSelection

ableViewer                     IStructuredSelection  

+- CheckboxTableViewer        IStructuredSelection

extViewer                      ITextSelection , IMarkSelection

 +- SourceViewer             ITextSelection , IMarkSelection     

 +- ProjectionViewer          ITextSelection , IMarkSelection

自定义的查看器也可以作为选择提供者并且实现 ISelectionProvider 接口。

任何一个包含了查看器的工作台部件都应该把这个查看器注册为各自的 view site 的选择提供者:

getSite().setSelectionProvider(tableviewer);

即使你暂时没有需要马上传播你的选择,但这让你的插件向你或者其他人的插件实现开放。如果你的视图定义了一个依赖于当前选择的操作,那么这些操作的动态改变 enable 状态也需要你设置一个选择提供者。

追踪当前的选择

工作台窗口典型地是由很多部件组成的,每个部件至少有一个查看器(这点 ms 不太对)。工作台保持追踪工作台窗口中当前选中的部件以及部件中的选择。这样,插件实现就可以访问这些信息或者注册选择变化的通知。

每个工作台窗口都有一个 ISelectionService 的实现,用来追踪当前的选择。一个视图部件可以通过他的 site 来获取这个对象的引用:

getSite().getWorkbenchWindow().getSelectionService()

选择服务知道当前活动部件或者指定 ID 的部件的当前选择:

    ISelection getSelection()

    ISelection getSelection(String partId)

典型的情况是视图作用于工作台窗口中的选择变化。这种情况下,最好注册一个 ISelectionListener 以在窗口的选择变化的时候获得通知:

    void addSelectionListener(ISelectionListener listener)

    void removeSelectionListener(ISelectionListener listener)

通过这种途径注册的监听者会在当前活动的部件的选择发生变化或者不同的部件被激活的时候获得通知。如果程序只对某个特定的部件的选择(并且不依赖于其真实的活动状态)感兴趣,那么可以只向特定 id 的部件注册监听者:

    void addSelectionListener(String partId, ISelectionListener listener)

    void removeSelectionListener(String partId, ISelectionListener listener)

即使当前没有给定 id 的部件,这种方式依然有效。一旦这个 id 的部件被创建,它的初始选择就会被传播给注册了的监听者。如果监听者实现了 INullSelectionListener 接口的话,监听者会在被监听的部件 dispose 的时候收到一个 null 选择。

实现一个选择监听者(监听器)

ISelectionListener 是一个只有一个方法的简单接口。一个典型的实现是向这样的:

    private ISelectionListener mylistener = new ISelectionListener() {

        public void selectionChanged(IWorkbenchPart sourcepart, ISelection selection) {

        if (sourcepart != MyView.this &&

              selection instanceof IStructuredSelection) {

                    doSomething(((IStructuredSelection) selection).toList());

            }

        }

    };
 

根据你的需求,你的监听器实现也许需要处理上面代码片段中的几个问题:

1. 如果我们还需要提供选择服务,那么我们应该把我们自己的选择事件排除在外,不加处理。这避免了当用户在我们的部件中选择了元素的时候的不可预料的结果。

2. 检查我们是否可以处理这种选择

3. 取得选择内容并且进行处理

注意:不要弄混 ISelectionListener 接口和 JFace 查看器用来通知选择更改的 ISelectionChangedListener

移除监听器

当你不能再处理事件的时候(例如当你的视图被关闭),不要忘记删除你的选择监听器。 dispose() 方法是一个删除监听器的好地方:

    public void dispose() {

        ISelectionService s = getSite().getWorkbenchWindow().getSelectionService();

     s.removeSelectionListener(mylistener);

        super.dispose();

    }

其他选择相关的问题

到现在为止,我们关注了选择服务的核心机制,覆盖了大多数用例。但在实际的实现当中,还有其他更多的问题会出现。

后选择

当浏览视图的时候,选择会频繁变化——尤其当使用键盘来滚动一个很长的列表或者使用鼠标拖动选择一段文本的时候。这会导致很多不必要的被注册为监听器的视图的更新,也可能导致你的程序响应很慢。

所谓的后选择事件会在一个较短短的延时以后再被发出。在这段延时时间内发生的选择会被忽略;仅仅最终的那个选择会被传播。 ISelectionService 有另外的方法来向延时选择事件注册监听器:

    void addPostSelectionListener(ISelectionListener listener)

    void removePostSelectionListener(ISelectionListener listener)

    void addPostSelectionListener(String partId, ISelectionListener listener)

    void removePostSelectionListener(String partId, ISelectionListener listener)

为避免性能问题,查看器一般应该用这种方式注册监听器。

选择提供者负责发送延时选择事件,它必须实现 IPostSelectionProvider 这个接口来支持延时选择事件,所有的 JFace 查看器都支持延时的选择事件。

INullSelectionListener

ISelectionListener 中定义的 selectionChanged() 这个回调方法可以像源部件( originating part )传入一个参数一样得到新的选择项:

    public void selectionChanged(IWorkbenchPart part, ISelection selection);

接口 INullSelectionListener 扩展了 ISelectionListener ,但是没有声明另外的方法。这是一个纯粹的标记接口,仅仅是为了标识那些即使是在选择为 ISelection 参数为 null 的情况下也想被通知的 selectionChanged() 方法的实现者。这个在当你想知道因为当前没有人提供一个选择项所以没有当前选择项的情况下非常有用。在下面情况下你会进入到这里面:

当前活动部件没有设置选择提供者。

我们为指定部件注册了监听器,但这个部件没有提供选择提供者。

工作台窗口没有活动部件,所有的部件都关闭了。

我们为指定部件注册了监听器,但这个部件被关闭了。

哪个选择服务:页面或者窗口

如果你仔细研究工作台 API 你会发现有两个选择服务: IWorkbenchPage 是一个 ISelectionService 。另外, IWorkbenchWindow 也有一个方法 getSelectionService() 。所以举例来说,有两种方法可以在一个部件中注册一个监听器:

    getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(l);

或者

    getSite().getPage().addSelectionListener(l);

实际上这两种方式是完全等价的,以为在 Eclipse2.0 以后,一个工作台窗口限制只有一个工作台页面。但是不要再添加和删除监听器的时候混合使用它们(例如用第一种方法添加,而用第二种方法删除),因为在内部他们是两个不同的实现。

一个部件中的多个选择提供者

要明白,工作台部件的 site 只接受一个选择提供者,而且必须只能在 createPartControl() 方法中调用:

        
getSite().setSelectionProvider(provider);

工作台不支持在工作台部件的运行过程中替换选择提供者。如果一个部件包含了多个提供选择项的查看器,例如“ Java Hierarchy ”这个视图,必须提供一个中间的 ISelectionProvider 的实现来允许动态地在部件中委派给当前活动的查看器。作为一个开始,你可以查看本文提供的 SelectionProviderIntermediate.java 这个文件。

如何处理被选中的对象

本文主张选择服务要负责帮助减少视图之间选择引起的不必要的相应。但是处理一个选择项的视图还必须为提供任何有用的功能而处理选择的对象。

分享到:
评论

相关推荐

    第五次作业函数第一题代码

    第五次作业函数第一题--

    基于深度学习的作物病害诊断内含数据集和运行环境说明.zip

    本项目旨在利用深度学习方法实现作物病害的自动诊断。作物病害是农业生产中的重要问题,及时诊断和处理对于减少产量损失至关重要。 我们采用深度学习算法,通过分析作物的图像,实现对病害的自动识别和分类。项目使用的数据集包括公开的作物病害图像数据集,如ISIC等,并进行了预处理,包括图像增强、分割和特征提取等。 在运行环境方面,我们使用Python编程语言,基于TensorFlow、PyTorch等深度学习框架进行开发。为了提高计算效率,我们还使用了GPU加速计算。此外,我们还采用了Docker容器技术,确保实验结果的可重复性。 项目完成后,将实现对作物病害的快速、准确诊断,为农业生产提供有力支持,有助于减少产量损失。同时,项目成果也可应用于其他图像识别和分类任务。

    机械设计CD驱动印刷设备step非常好的设计图纸100%好用.zip

    机械设计CD驱动印刷设备step非常好的设计图纸100%好用.zip

    tensorflow-2.7.2-cp37-cp37m-manylinux2010-x86-64.whl

    python烟花代码

    python烟花代码示例

    附件中是一个简单的烟花效果的代码示例: 在Python中,可以使用多种方式来模拟烟花效果,其中一种常用的方法是使用turtle模块,它提供了一个画布和一个小海龟,可以用来绘制各种图形。 这段代码首先导入了turtle模块和random模块,然后在屏幕上绘制了10次烟花爆炸的效果。每次爆炸都是由5个小圆组成,颜色随机选择,圆的大小也是随机的。 请注意,这段代码需要在支持turtle模块的Python环境中运行,并且需要有图形界面的支持。如果你在没有图形界面的环境中(比如某些服务器或者命令行界面),这段代码可能无法正常运行。

    商业化产品经理,到底如何实现产品商业化?.docx

    商业化产品经理,到底如何实现产品商业化?.docx

    Panduit 工业以太网部件内部销售指南

    Panduit 工业以太网部件内部销售指南

    Java版三维装箱代码示例

    在Java中,实现一个三维装箱(也称为三维背包问题)的算法通常涉及到组合优化和动态规划。这个问题是一个典型的优化问题,其中目标是在三个维度的限制下最大化价值的总和。下面是一个简单的Java代码示例,它使用动态规划来解决三维装箱问题。 请注意,这个代码只是一个简单的示例,它假设所有物品的第三个维度的大小都是1,并且没有给出如何回溯选择物品的完整逻辑。在实际应用中,三维装箱问题可能更加复杂,需要考虑所有三个维度的限制,并且可能需要更复杂的算法来解决。 此外,这个问题的解决方案可能需要根据具体问题的要求进行调整,例如物品是否可以分割、是否允许超过一个的物品等。如果你有特定的问题描述或者需要进一步的帮助,请提供更多的细节。

    常用品牌EPLAN部件库

    常用品牌EPLAN部件库

    单片机开发的教程.doc

    单片机开发的教程可以分为以下几个步骤: 1. 了解单片机基础知识:在学习单片机开发之前,需要了解单片机的相关知识,包括单片机的基本结构、指令系统、编程语言等。 2. 选择开发板:选择一款适合自己学习开发板的型号和厂商,通常需要关注开发板的性价比、开发环境是否友好等因素。 3. 学习开发环境:根据所选的开发板,学习相关的开发环境和使用方法,例如Keil、IAR等集成开发环境。 4. 掌握编程语言:单片机常用的编程语言包括C语言和汇编语言,根据实际情况选择其中一种进行学习。 5. 基础操作:熟悉单片机的引脚定义和IO口配置,了解单片机的启动代码,可以通过修改启动代码进行基本功能调试。 6. 综合实践:根据具体项目需求,进行单片机开发的综合实践。在实践中需要掌握如何编写程序、如何进行硬件调试、如何使用相关工具软件等技能。 下面是一个单片机开发的简单教程介绍: 首先,确定所使用的单片机型号和开发板类型。在这个阶段,需要查阅相关资料,了解开发板的规格书、芯片规格等基本资料。 其次,安装并配置开发环境。根据所选的开发板,安装相应的集成开发环境(IDE),并配置好开发环境。 接着,学习并掌

    Q1.ipynb

    Q1.ipynb

    (自适应手机端)IT网络建站公司pbootcms模板 互联网营销企业网站源码下载.zip

    (自适应手机端)IT网络建站公司pbootcms模板 互联网营销企业网站源码下载.zip

    Bematech 激光扫描器用户手册

    Bematech 激光扫描器用户手册

    激励视频接入文档.pdf

    激励视频接入文档.pdf

    java jdk1.8 202版本下载window linux打包

    java jdk1.8 202版本下载window linux打包

    Lite Beam M5快速指南 Lite Beam M5天线设置指南

    Lite Beam M5快速指南

    互联网金融导论.docx

    互联网金融导论.docx

    字节跳动青训营-抖音项目

    字节跳动青训营——抖音项目

    node-v12.22.10-linux-s390x.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v12.12.0-linux-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

Global site tag (gtag.js) - Google Analytics