好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Eclipse 4

Eclipse 4

Eclipse 4简介

Eclipse SDK 4.x基于E4孵化器项目,是新一代构建基于Eclipse的工具和富客户端桌面应用的平台。它使得开发和组装基于Eclipse平台的应用和工具要更加容易。第一个版本(4.0)发布于2010年7月28日,4.1发布于2011年6月22日,2012年将发布Eclipse 4.2。Eclipse 3.8将和4.2同时发布,同时3.x也将停止更新。

Eclipse 4包含:

基于模型的用户界面和用于程序样式的基于CSS的声明机制。这使得设计和自定义应用程序界面变得更加容易,也给UI布局带来更大的灵活性,可以使UI看起来与IDE完全不同。 新的面向服务的编程模型,可以更容易地使用Eclipse平台提供的应用程序服务。 支持依赖注入。 提供了一个兼容层,已有的Eclipse 3.x程序也可以利用Eclipse 4应用程序平台的新功能。 架构概述

Eclipse 4应用程序平台与Eclipse 3.x应用程序平台非常类似。如全部JDT和PDE、大部分Platform都和Eclipse 3.x完全相同。E4AP与Eclipse 3.x平台的不同之处在于Workbench的实现(如 org.eclipse.ui.workbench.plugin ),以及这个新实现所依赖的技术。在发布之前,这些技术(模型化的UI、依赖注入、基于服务的编程模型、基于CSS的样式)称为“e4”,而现在,我们叫它Eclipse 4应用程序平台(E4AP)。在E4AP上端,4.0 Workbench提供了一个3.x Workbench APIs的实现,称为 兼容层 ,为已有的Eclipse 3.x应用提供向后兼容。

模型化UI

Eclipse 4应用程序的布局现在完全支持 模型 。它与Web页的DOM类似,描述用户界面的布局和结构,尽管还包含其他对用户不可见的元素(如命令和handler)。

模型化UI为自定义应用程序外观提供非常灵活的方式。应用程序的结构比3.x的透视图工厂和扩展更容易理解,因为每个元素的容器模型都设计得更好。

模型本身使用EMF创建和维护的,并使用EMF风格的模式来创建和添加元素。对模型的改变将立即反应在运行的应用程序中。

模型元素

Eclipse 4中的模型是一组接口,都以 M 作为前置,并公开了很多getter、setter方法。Eclipse 4的模型继承了上一代Eclipse应用程序平台的最佳实践。模型化的UI描述了窗体、透视图、stacks or tiles和part,也吸收了Eclipse 3.4中的命令/处理程序/绑定这个模型。

E4AP提供了 MApplicationElement 、 MUILable 等抽象元素,以及 MWindow 、 MPerspective 、 MPart 、 MMenu 等具体元素。详细内容可以参考 这里 。

CSS样式

E4AP的一个主要改进就是重新思考如何处理应用程序的主题和样式。它可以对控件、窗体、对话框应用样式。这一开始可能会感到很陌生。不过UI的层次结构与HTML类似。如SWT窗体或对话框包含一个根容器 Shell ,它又包含一些 Composite 和 Group 元素,每个元素又可以包含 CTabFolder 、 Text 、 Tree 和 Table 等。

CSS映射

使用CSS选择器可以通过 type#id.class 这样的方式来指定元素。从E4AP到SWT的映射如下:

type 对应Java组件类(如 Button 、 Composite 等)。 元素可以包含很多类。E4AP公开了模型化UI元素的接口类型(如 MPart 、 MTrimmedWindow )及其标签(通过类的特性(attribute))。类的特性也可以访问SWT组件的数据值。 id 对应模型化元素的elementId。

这里 有CSS属性与SWT控件方法的映射表。

应用样式

在CSS文件中,我们使用相关SWT控件的标示符,如下面的CSS文件:

  Label  {  
    font  :  Verdana  8px  ;  
    color  :   black  ;  }  Composite  Label  {  
    color  :   black  ;  }  Text  {  
    font  :  Verdana  8px  ;  }  Composite  Text  {  
    background  -  color  :   white  ;  
    color  :   black  ;  }  SashForm  {  
    background  -  color  :  #c1d5ef;  }  .  MTrimBar  {  
    background  -  color  :  #e3efff #c1d5ef;  
    color  :   white  ;  
    font  :  Verdana  8px  ;  }  Shell  {  
    background  -  color  :  #e3efff #c1d5ef 60  }  

要让你的程序使用CSS文件,可以有两种方式:

对产品指定 applicationCSS 文件。 使用主题管理器

如果程序样式固定,就使用第一种方式。打开RCP项目的 plugin.xml 文件,选择 extensioni 选项卡,向 org.eclipse.core.runtime.products 扩展点添加 applicationCSS 属性。该属性的值是指向CSS文件的URI,格式约定为 platform:/plugin/BundleSymbolicName/path/file 这种格式。例如:

  platform  :  /plugin/  com  .  example  .  e4  .  rcp  .  todo  /  css  /  default  .  css  

这样,我们的程序在一开始就将应用该样式。

第二种方法要更灵活一些。我们定义一个对于 org.eclipse.e4.ui.css.swt.theme 扩展点(定义ID和对CSS文件的指针)的扩展。然后为产品定义 cssTheme 属性。主题管理器允许我们在运行时选择样式,和注册新主题。

我们创建 org.eclipse.e4.ui.css.swt.theme 扩展点的两个扩展,如下图

创建一个 css/red.css 文件:

  CTabItem  ,  ToolBar  ,  Button  ,  CBanner  ,  CoolBar  {  
    font  -  size  :  9  ;  
    background  -  color  :   red  ;  }  

对项目添加 cssTemplate 参数:

创建下面这个handler将选择红色样式:

  import   javax  .  inject  .  Named  ;  import   org  .  eclipse  .  e4  .  core  .  di  .  annotations  .  Execute  ;  import   org  .  eclipse  .  e4  .  ui  .  css  .  swt  .  theme  .  IThemeEngine  ;  import   org  .  eclipse  .  e4  .  ui  .  workbench  .  IWorkbench  ;  public  class  ThemeSwitchHandler  {  @Execute  public  void   switchTheme  (  IThemeEngine   engine  )  {  
        engine  .  setTheme  (  "de.vogella.e4.todo.redtheme"  ,  true  );  }  }  

在应用程序中添加一个调用上面handler的菜单。运行程序,就可以通过菜单选择红色主题:

此外,我们还可以指定某个控件的标签,并在CSS文件中定义这些标签。我们可以用下面的代码来设置标签:

  Label   label   =  new  Label  (  parenet  ,   SWT  .  NONE  );  
label  .  setData  (  "org.eclipse.e4.ui.css.id"  ,  "MyCSSTagForLabel"  );  

CSS文件可以这样定义该标签的样式:

  #MyCSSTagForLabel{  
    color  :  #blue;  }  
依赖注入

Eclipse平台经过10年的发展,仍然存在以下问题:

代码需要频繁使用全局单例访问器(如 Platform 、 PlatformUI )或请求较深的依赖链(如获取 IStatusLineManager )。单例服务对RAP和Riena这种应用服务器来说,问题多多。 单例与提供程序的消费者紧密耦合,并且禁止重用。 不够动态。 ……

E4AP使用依赖注入来解决这些问题。客户端代码不需要知道如何访问服务,只需要描述所需的服务,而由平台负责配置适当的服务。它提供了与 JSR 330 兼容的 基于注解 的依赖注入框架,与Spring类似。注入器定义在多个插件中: org.eclipse.e4.core.di 、 org.eclipse.e4.core.di.extensions 、 org.eclipse.e4.ui.di 。

在Eclipse 3.x中,视图需要通过 PlatformUI 单例和part site的状态行管理器来访问Eclipse帮助系统:

  class  MyView  extends  ViewPart  {  public  void   createPartControl  (  Composite   parent  )  {  Button   button   =  ...;  PlatformUI  .  getWorkbench  ().  getHelpSystem  ().  setHelp  (  button  ,  "com.example.button.help.id"  );  

        getViewSite  ().  getActionBars  ().  getStatusLineManager  ().  setMessage  (  "Configuring system..."  );  }  }  

而在E4AP中,part是POJO,应用程序服务是直接注入进来的:

  class  MyView  {  @Inject  public  void   create  (  Composite   parent  ,  IWorkbenchHelpSystem   help  )  {  Button   button   =  ...;  
        help  .  setHelp  (  button  ,  "com.example.button.help.id"  );  

        slm  .  setMessage  (  "Configuring system..."  );  }  }  

DI的好处有:

客户端可以编写POJO和所需的服务列表。 更利于测试。

而DI也有一些缺点:

服务发现:无法使用代码自动完成功能来找到可用的服务。 调试加载失败的注入项时会很困难。

与依赖注入相关的注释,详见 这里 。

上下文

E4AP使用 上下文 ( IEclipseContext 接口)向应用程序提供公共服务。普通代码不需要使用或了解上下文。应该在Java类中使用 @Inject 注解来接收必要的服务,不应该直接使用 IEclipseContext 。

Eclipse 3.x存在以下问题,可以由 IEclipseContext 和依赖注入来解决:

频繁使用全局单例访问器(如 Platform 、 PlatformUI 等等) 生产者与消费者之间的耦合过于紧密,同时很难重用 对上下文变化的动态响应不是增量的 IEvaluationContext 包含全局状态(可根据上下文的改变而变化) 当前解决方案不是多线程的(计算发生在UI线程) 尺寸变化 当前解决方案不会因为服务的生命周期短而减小尺寸 当前解决方案会因为服务多而增大尺寸 包含太多相似的并行树(控件树、服务位置树等) 不跟踪服务的消费者 客户端代码需要了解Eclipse代码库的内部 不支持由运行时的其他服务组成的服务查找

E4AP的上下文存储了可用的服务,并提供了OSGi服务查找。由于不太可能向Eclipse上下文请求可用的服务,并且不建议直接调用上下文中的方法,所以了解能够注入哪些内容是十分重要的。

以 模型 为例,它们都是 MContext 的实例,包含在自身的上下文中。例如, MWindow 和 MPart 都是 MContext ,所以可以这样查询模型对象的上下文:

  // window == mwindow  MWindow   window   =  (  MWindow  )   mwindow  .  getContext  ().  get  (  MWindow  .  class  .  getName  ());  // part == mpart  MWindow   part   =  (  MPart  )   mpart  .  getContext  ().  get  (  MPart  .  class  .  getName  ());  

这些模型对象都存在于上下文中,所以可以直接将它们注入到客户端代码中:

  public  class  AccountsPart  {  @Inject  private  MPart   part  ;  @Inject  private  MWindow   window  ;  void   setDirty  (  boolean   dirty  )  {  
        part  .  setDirty  (  dirty  );  }  }  

为了鼓励重用,你应该注入所需的最小公分母。例如,如果只关注让part变dirty,只需要:

  public  class  AccountsPart  {  @Inject  private  MDirtyable   dirtyable  ;  void   setDirty  (  boolean   dirty  )  {  
        dirtyable  .  setDirty  (  dirty  );  }  }  

这样其他非 MPart 的 MDirtyable 实现也可以复用你的代码。这导致了一个非常有趣的现象,即一个模型接口的上层接口也会添加到上下文中。例如:

  public  class  AccountsPart  {  @Inject  private  MDirtyable   dirtyable  ;  @Inject  private  MUILabel   label  ;  @Inject  private  MContext   context  ;  @Inject  private  MPart   part  ;  }  

所有的字段都是相同的 MPart 实例。

关于上下文的详细内容,请参考 这里 。

事件模型

Eclipse 4使用了一个发布/订阅事件模型的 全局事件总线 (global event bus)。《 E4中的事件处理 》描述了其原理。全局事件总线实现在OSGi事件引起之上,可使用 org.eclipse.e4.core.services.events.IEventBroker 访问。

IEventBroker 提供了一些方法,可以订阅、取消订阅总线上的事件,以及向总线发布事件。

获取IEventBroker

可以通过 EclipseContext 来获取 IEventBroker 的一个实例:

  …  private  IEclipseContext   eclipseContext  ;  …  IEventBroker   eventBroker   =   eclipseContext  .  get  (  IEventBroker  .  class  );  

或通过依赖注入:

  @Inject  IEventBroker   eventBroker  ;  

发布事件

向全局事件总线发布事件十分简单,只需调用一下两个方法之一:

  IEvent  Broker  .  post  (  String   topic  ,  Object   data  )  // synchronous delivery  IEventBroker  .  send  (  String   topic  ,  Object   data  )  // asynchronous delivery  

例如:

  ...  
foo  .  Bar   payload   =   getPayload  ();  boolean   wasDispatchedSuccessfully   =   eventBroker  .  send  (  TOPIC_STRING  ,   payload  );  

如果 send 或 post 命令的 payload 是普通Java对象,将把它作为包含 IEventBroker.DATA 键的属性附加到OSGi事件上。如果 payload 是 Dictionary 或 Map ,所有的值都将作为包含相应键的属性进行添加。

响应事件

声明和相应事件包含两种方法:依赖注入和通过 IEventBroker 订阅。

Eclipse推荐在任何时候都使用依赖注入来注册和相应事件。它的代码更少,更容易阅读和维护,包含较少的匿名内部类。(但实际上E4代码库并没有使用这种方法来订阅事件。)

  @Inject  @Optional  void   closeHandler  (  @UIEventTopic  (  ''  TOPIC_STRING  ''  )   foo  .  Bar   payload  )  {  // Useful work that has access to payload.  The instance of foo.Bar that the event poster placed on the global event bus with the topic ''TOPIC_STRING''  }  

应该将事件处理方法定义为私有的,这样可以更清晰,也能避免直接调用。依赖注入机制可以注入私有字段和方法。(目前定义成私有方法会有bug,可以定义为包级私有。)

如果你的类没有使用依赖注入,则只能用 IEventBroker 来订阅:

  IEventBroker   eventBroker  ;  …  void   addSubscribers  ()  {  

    eventBroker  .  subscribe  (  TOPIC_STRING  ,   closeHandler  );  …  }  void   removeSubscribers  ()  {  
    eventBroker  .  unsubscribe  (  closeHandler  );  …  }  …  private   org  .  osgi  .  service  .  event  .  EventHandler   closeHandler   =  new  EventHandler  ()  {  public  void   handleEvent  (  Event  event  )  {  // Useful work that has access  
    foo  .  Bar   payload   =  (  foo  .  Bar  )  event  .  getProperty  (  IEventBroker  .  DATA  );  }  
参考资料 Eclipse 4 RCP Eclipse 4 Tutorials Eclipse 4 FAQ

 

分类:  [05] 桌面应用

标签:  Eclipse

当前标签: Eclipse

 

Eclipse 4综述

 

Eclipse Tips(3):Template

 

Eclipse Tips(2):代码颜色设置

 

Eclipse Tips(1):增强智能感知

 

Eclipse & Visual Studio Tips(不断更新)

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于Eclipse 4的详细内容...

  阅读:63次