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. iOS H5容器的一些探究(二):iOS 下的黑魔法 NSURLProtocol

    来源:景铭巴巴 链接:http://www.jianshu.com/p/03ddcfe5ebd7 iOS H5 容器的一些探究(一):UIWebView 和 WKWebView 的比较和选择 一.前言 ...

  2. LOG4NET开源日志dll引用流程,在net3.5中已经实践ok

    一,在app.config中配置 <?xml version="1.0"?><configuration> <configSections> & ...

  3. Flex学习总结

    Flex SDK Flex框架类库.Flex编译环境.调式器.MXML.ActionScript编程语言以及其它工具组成,Flash Builder是其开发环境,   Flash Player的工作模 ...

  4. iOS中的网络请求 和 网络监测

    1.网络监测 //根据主机名判断网络是否连接 Reachability *reach = [Reachability reachabilityWithHostName:@"www.baidu ...

  5. Oracle 11g XE 试用记录

    安装之前先删除系统环境变量中的oracle_home等配置(如果存在的话): 如果安装后出现Web管理界面不能访问或者数据库不能连接的情况,卸载再多安装几次可能就正常了.状态不正常时,可以使用 C:\ ...

  6. [书目20131223]Android、iPhone、Windows Phone手机网页及网站设计:最佳实践与设计精粹 - 张亚飞

    目录 第I篇 手机版专用网站设计和开发入门篇 第1章 准备创作环境和测试环境 3 1.1 使用Mobile Safari测试网页 4 1.1.1 iOS Simulator安装 5 1.1.2 使用M ...

  7. 获取https证书

    获取证书 个人如果想购买SSL证书,相对来说还是比较简单的.对于小型网站,可以考虑通过StartSSL获取免费证书.另外还可以通过LetsEncrypt项目使用一个简单的命令行界面为服务获取免费证书. ...

  8. self.view添加UIView时添加动画

    CATransition *animation = [CATransition animation]; animation.delegate = self; animation.duration = ...

  9. 熔断器设计模式<转>

    熔断器设计模式 如果大家有印象的话,尤其是夏天,如果家里用电负载过大,比如开了很多家用电器,就会”自动跳闸”,此时电路就会断开.在以前更古老的一种方式是”保险丝”,当负载过大,或者电路发生故障或异常时 ...

  10. Struts2_概述