我在Eclipse新闻组中经常看到讨论视图之间通信的问题,他们经常要面对状态改变之后的同步问题(通常的做法是使用
ISelectionService),看来大家对OSGI EventAdmin服务不是很了解,这是一个采用发布订阅模式的事件系统,可以很轻松的应用到您的RCP程序中。
1、安装
首先将org.eclipse.osgi.services和
org.eclipse.equinox.event添加到工程的依赖项中。
2、发布事件
public class SenderView extends ViewPart {
public static final String ID = "viewcommunication.views.SenderView";
private Button b;
public void createPartControl(Composite 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) {
BundleContext ctx = FrameworkUtil.getBundle(SenderView.class).getBundleContext();
ServiceReference<EventAdmin> ref = ctx.getServiceReference(EventAdmin.class);
EventAdmin eventAdmin = ctx.getService(ref);
Map<String,Object> properties = new HashMap<String, Object>();
properties.put("DATA", new Date());
Event event = new Event("viewcommunication/syncEvent", properties);
eventAdmin.sendEvent(event);
event = new Event("viewcommunication/asyncEvent", properties);
eventAdmin.postEvent(event);
}
});
}
public void setFocus() {
b.setFocus();
}
}
3、订阅事件
1 public class ReceiverView extends ViewPart {
2 private TableViewer viewer;
3
4 @Override
5 public void createPartControl(final Composite parent) {
6 parent.setLayout(new FillLayout());
7 viewer = new TableViewer(parent);
8 viewer.getTable().setHeaderVisible(true);
9 viewer.getTable().setLinesVisible(true);
10 viewer.setLabelProvider(new ColumnLabelProvider() {
11 @Override
12 public String getText(Object element) {
13 return DateFormat.getDateTimeInstance().format(element);
14 }
15 });
16
17 BundleContext ctx = FrameworkUtil.getBundle(ReceiverView.class).getBundleContext();
18 EventHandler handler = new EventHandler() {
19 public void handleEvent(final Event event) {
20 if( parent.getDisplay().getThread() == Thread.currentThread() ) {
21 viewer.add(event.getProperty("DATA"));
22 } else {
23 parent.getDisplay().syncExec(new Runnable() {
24 public void run() {
25 viewer.add(event.getProperty("DATA"));
26 }
27 });
28 }
29 }
30 };
31
32 Dictionary<String,String> properties = new Hashtable<String, String>();
33 properties.put(EventConstants.EVENT_TOPIC, "viewcommunication/*");
34 ctx.registerService(EventHandler.class, handler, properties);
35 }
36
37 @Override
38 public void setFocus() {
39 viewer.getTable().setFocus();
40 }
41 }
42
不是很复杂,对吧,起码降低了耦合度。