Some weeks ago I published how views can communicate using the EventAdmin-Service. To get things working in an 3.x application one has to write some glue code but more importantly one has to know about all those nifty things about event publishing, getting access to OSGi-Services, … .

One of the main topics of the Eclipse 4 Application Platform was to make easy things easy by removing the need to know about all the concepts by hiding them using DI. The service responsible to deliver events in application built on top the Eclipse 4 Application Platform is the EventBroker-Service:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package org.eclipse.e4.core.services.events;
 
public interface IEventBroker {
    public String DATA = "org.eclipse.e4.data"; //$NON-NLS-1$
 
    public boolean send(String topic, Object data);
    public boolean post(String topic, Object data);
 
    public boolean subscribe(String topic, EventHandler eventHandler);
 
    public boolean subscribe(String topic, String filter, EventHandler eventHandler,
            boolean headless);
 
    public boolean unsubscribe(EventHandler eventHandler);
}

This is all we need to know (assuming we have already understood how DI-works) to implement our sender and receiver views:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class SenderView {
  @Inject
  private IEventBroker eventBroker;
  private Button b;
 
  @PostConstruct
  void init(Composte parent) {
    parent.setLayout(new GridLayout());
    b = new Button(parent, SWT.PUSH);
    b.setText("Send Event");
    b.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        Date d = new Date();
        eventBroker.send("viewcommunication/syncEvent",d);
        eventBroker.post("viewcommunication/asyncEvent", d);
      }
    });
  }
 
  @Focus
  void focus() {
    b.setFocus();
  }
}

These are some fewer lines of code which is good but IMHO the more important fact is that you are independent from OSGi running now so the code you have there is much easier testable by simply mocking IEventBroker!

Let’s look now at the receiver side of the story. If you take a look at the IEventBroker you see the subscribe methods which allows us to subscribe to various topics so we could as a first step implement it like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class ReceiverView {
  @Inject
  private IEventBroker eventBroker;
  private TableViewer viewer;
 
  @PostConstruct
  public void init(final Composite parent) {
    parent.setLayout(new FillLayout());
    viewer = new TableViewer(parent);
    viewer.getTable().setHeaderVisible(true);
    viewer.getTable().setLinesVisible(true);
    viewer.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(Object element) {
        return DateFormat.getDateTimeInstance().format(element);
      }
    });
 
    EventHandler handler = new EventHandler() {
      public void handleEvent(final Event event) {
        if( parent.getDisplay().getThread() == Thread.currentThread() ) {
          viewer.add(event.getProperty(IEventBroker.DATA));
        } else {
          parent.getDisplay().syncExec(new Runnable() {
            public void run() {
              viewer.add(event.getProperty(IEventBroker.DATA));
            }
          });
        }
      }
    };
    eventBroker.subscribe("viewcommunication/*",handler);
  }
 
  @Focus
  void focus() {
    viewer.getTable().setFocus();
  }
}

This is once more making your code looser coupled because you are independent from OSGi running but we can do even better by fully leveraging the Eclipse DI-Framework. By default Eclipse DI injects data it has stored in its IEclipseContext (you can think of the IEclipseContext as a Map where the value is thing that gets injected into you “POJO”).

The important thing for us is that one can extend Eclipse DI to consult other resources like e.g. Preferences (@Preference) and e.g. Event-Data (@EventTopic) – a blog post explaining how this works will follow hopefully soon.

So we can rewrite our receiver code like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class ReceiverView {
  private TableViewer viewer;
 
  @PostConstruct
  public void init(final Composite parent) {
    parent.setLayout(new FillLayout());
    viewer = new TableViewer(parent);
    viewer.getTable().setHeaderVisible(true);
    viewer.getTable().setLinesVisible(true);
    viewer.setLabelProvider(new ColumnLabelProvider() {
      @Override
      public String getText(Object element) {
        return DateFormat.getDateTimeInstance().format(element);
      }
    });
  }
 
  @Inject
  void eventReceived(@EventTopic("viewcommunication/*") Date date) {
    Display d = viewer.getControl().getDisplay();
    if( d.getThread() == Thread.currentThread() ) {
      viewer.add(date);
    } else {
      parent.getDisplay().syncExec(new Runnable() {
        public void run() {
          viewer.add(date);
        }
      });
    }
  }
 
  @Focus
  void focus() {
    viewer.getTable().setFocus();
  }
}

[Update 2011-02-07] – Start
But we can do even better so that we don’t need to take of the UI-Thread syncing all we need to do is use another annotation:

1
2
3
4
@Inject
  void eventReceived(@UIEventTopic("viewcommunication/*") Date date) {
    viewer.add(date);
  }

Now the DI-Framework takes care of the Event loop syncing. Thanks to Brian de Alwis for pointing this out.
[Update 2011-02-07] – End

If you are interested in how you can use things like this in your Eclipse 3.x applications and you are going to be at EclipseCon you should come to my talk about “Singlesourcing for Eclipse 4.x and Eclipse 3.x

 
 

Enhanced RCP: How views can communicate – The e4 way | Tomsondev Blog的更多相关文章

  1. django复习笔记3:urls/views/templates三板斧

    0.先看看文件结构 mysite/ mysite/ ├── __pycache__ │   └── manage.cpython-.pyc ├── blog │   ├── __init__.py │ ...

  2. Materialized Views 物化视图 -基础篇

    Materialized Views 物化视图 -基础篇 http://blog.csdn.net/elimago/article/details/5404019

  3. Django+Tastypie作后端,Backbone作前端的TodoMVC

    TodoMVC是各种js框架入门的比较经典的例子,详细可查看github地址https://github.com/tastejs/todomvc 接着上篇文章, 1,先在github上把backbon ...

  4. Tastypie 学习笔记

    Tastypie是什么? 运行于Python环境中的 Django web服务器下的 Restful 风格API接口  (python 类库) 1.安装下面环境或者依赖包到python库(安装过程类似 ...

  5. django 富文本展示 以及 post提交出错

    1.富文本转义 使用 {{ content.record.content | safe }} 2.post提交报错 页面表单内追加 <form id="f"action=&q ...

  6. python Django教程 之模板渲染、循环、条件判断、常用的标签、过滤器

    python3.5 manage.py runserver python Django教程 之模板渲染.循环.条件判断.常用的标签.过滤器 一.Django模板渲染模板 1. 创建一个 zqxt_tm ...

  7. 巧用freemarker

    使用Freemarker宏进行可扩展式模块化编程 该文是转载而来,并非我本人所写,但是觉得真心不错,所以收藏一下 一.前言 今天的文章聊一下freemarker的一些特性:宏,我们将使用它写出一些模块 ...

  8. curl operate elasticsearch

    export elasticsearchwebaddress=localhost:9200# 1. Add documentcurl -X PUT "$elasticsearchwebadd ...

  9. 使用Freemarker宏进行可扩展式模块化编程

    作者:Chu Lung 原文链接:http://blog.chulung.com/article/13 本文由MetaCLBlog于2016-07-08 14:42:10自动同步至cnblogs 一. ...

随机推荐

  1. 1.4.2 solr字段类型--(1.4.2.1)字段类型定义和字段类型属性

    1.4.2 solr字段类型 (1.4.2.1) 字段类型定义和字段类型属性. (1.4.2.2) solr附带的字段类型 (1.4.2.3) 使用货币和汇率 (1.4.2.4) 使用Dates(日期 ...

  2. spring mvc 接收页面表单List

    很少写博客,如果写的不好请多多包涵! 最近在用Spring mvc时遇到一个问题,在网上搜了很多资料.几乎没看到解决办法! 例如:当我们在做批量添加或者更新时,在Controller层接收表单数据的问 ...

  3. oc中的block使用心得

    typedef void (^ simpleBlock) (void); typedef double (^multiplyTwoValues)(double, double); typedef vo ...

  4. How to installation V145 Renault CAN Clip diagnostic software

    Eobd2.fr has launched the new 2015 V145 Renault CAN Clip diagnostic tool (SP19-A and SP19-B). Here i ...

  5. (四)u-boot2013.01.01 for TQ210:《mkconfig分析》

    config.mk主要功能是配置单板信息和编译环境,将会被u-boot的makefile所调用,本文仍然侧重于句法分析. ####################################### ...

  6. 剑指Offer47 不用加减乘除做加法

    /************************************************************************* > File Name: 47_AddTwo ...

  7. Backbone.js学习之Router

    官方文档的解释: Web applications often provide linkable, bookmarkable, shareable URLs for important locatio ...

  8. Android 联系人字母排序(仿微信)

    现在很多APP只要涉及到联系人的界面,几乎都会采取字母排序以及导航的方式.作为程序猿,这种已经普及的需求还是需要学习的,于是小生开始了在网上默默的学习之路,网上学习的资料质量参差不齐,不过也有很不错的 ...

  9. Activity生命周期-Android

    Activity常见的三种生命周期: 1.完整生命周期 oncreate-->onstart-->onresume-->onpause-->onstop-->ondest ...

  10. Android 动画学习笔记

    Android动画的两种:Frame帧动画.Tween动画(位移动画)[实现:存放目录res/anim] Tween动画:(位移.缩放.旋转):通过对场景里的对象不断做图像变换. 四种效果Alpha. ...