Enhanced RCP: How views can communicate – The e4 way | Tomsondev Blog
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的更多相关文章
- django复习笔记3:urls/views/templates三板斧
0.先看看文件结构 mysite/ mysite/ ├── __pycache__ │ └── manage.cpython-.pyc ├── blog │ ├── __init__.py │ ...
- Materialized Views 物化视图 -基础篇
Materialized Views 物化视图 -基础篇 http://blog.csdn.net/elimago/article/details/5404019
- Django+Tastypie作后端,Backbone作前端的TodoMVC
TodoMVC是各种js框架入门的比较经典的例子,详细可查看github地址https://github.com/tastejs/todomvc 接着上篇文章, 1,先在github上把backbon ...
- Tastypie 学习笔记
Tastypie是什么? 运行于Python环境中的 Django web服务器下的 Restful 风格API接口 (python 类库) 1.安装下面环境或者依赖包到python库(安装过程类似 ...
- django 富文本展示 以及 post提交出错
1.富文本转义 使用 {{ content.record.content | safe }} 2.post提交报错 页面表单内追加 <form id="f"action=&q ...
- python Django教程 之模板渲染、循环、条件判断、常用的标签、过滤器
python3.5 manage.py runserver python Django教程 之模板渲染.循环.条件判断.常用的标签.过滤器 一.Django模板渲染模板 1. 创建一个 zqxt_tm ...
- 巧用freemarker
使用Freemarker宏进行可扩展式模块化编程 该文是转载而来,并非我本人所写,但是觉得真心不错,所以收藏一下 一.前言 今天的文章聊一下freemarker的一些特性:宏,我们将使用它写出一些模块 ...
- curl operate elasticsearch
export elasticsearchwebaddress=localhost:9200# 1. Add documentcurl -X PUT "$elasticsearchwebadd ...
- 使用Freemarker宏进行可扩展式模块化编程
作者:Chu Lung 原文链接:http://blog.chulung.com/article/13 本文由MetaCLBlog于2016-07-08 14:42:10自动同步至cnblogs 一. ...
随机推荐
- c#winform将全局异常抛出,不用大量写try()catch()
一.在program.cs处完善成如下,但是这样后只能抛出主线程(UI)的错误,所以请看第二步 /// 应用程序的主入口点. /// </summary> [STAThread] stat ...
- 【JEMTER】后置处理器JSON Path Extractor获取server端返回的json中某项值
需求1:点击所有报表模板时,server端返回所有报表模板的ID(templateId),测试时需要下载某个模板生成的报表 需求2:点击单个报表模板时,server端返回这个报表模板下的所有报表ID( ...
- 重构22-Break Method(重构方法)
这个重构是一种元重构(meta-refactoring),它只是不停地使用提取方法重构,直到将一个大的方法分解成若干个小的方法.下面的例子有点做作,AcceptPayment方法没有丰富的功能.因此为 ...
- 重构4-Push Down Method(方法下移)
我们介绍了将方法迁移到基类以供多个子类使用的上移方法重构,今天我们来看看相反的操作.重构前的代码如下: public abstract class Animal { public void Bark( ...
- 用Chrome浏览器模拟手机,android,iphone,ipad访问网站
很多网站都通过User-Agent来判断浏览器类型,如果是3G手机,显示手机页面内容,如果是普通浏览器,显示普通网页内容.谷歌Chrome浏览 器,可以很方便地用来当3G手机模拟器.在Windows的 ...
- page80-栈用例-算术表达式求值
表达式由括号, 运算符和操作数(数字)组成.我们根据以下4中情况从左到右逐个将这些实体送入栈处理. (1)将操作数压入操作数栈: (2)将运算符压入运算符栈: (3)忽略左括号: (4)在遇到右括号时 ...
- 数理方程:Fourier级数
更新:25 MAR 2016 对于周期函数(周期为\(2\pi\))或定义在\([-\pi,\pi]\)上的函数\(f(x)\),可以展开为* \(\large f(x)=\dfrac{a_0}{2} ...
- Python15-day1课后作业
功能:编写一个用户登录接口 要求:1)根据提示输入用户名.密码信息 2)输入的用户.密码正确则显示欢迎信息 3)连续三次输入错误则锁定账号 #coding=utf-8import sys,os,get ...
- 兼容性调试-- 在谷歌浏览器中,td 设置colspan的失效的问题
通过设置table width="100%"table-layout="fixed" 解决
- CS加密算法
概述: 加密数据可以使用对称加密或非对称加密算法,使用对称加密比非对称密钥快得多,但对称密钥需要解决安全交换密钥的问题.在 .NET Framework中,可以使用System.Security.Cr ...