Fabrizio Giudici is a Senior Java Architect with a long Java experience in the industrial field. He runs Tidalwave, his own consultancy company, and has contributed to Java success stories in a number of fields, including Formula One. Fabrizio often appears as a speaker at international Java conferences such as JavaOne and Devoxx and is member of JUG Milano and the NetBeans Dream Team. Fabrizio is a DZone MVB and is not an employee of DZone and has posted 67 posts at DZone. You can read more from them at their website. View Full User Profile

EventBus: How to Publish & Subscribe on the NetBeans Platform

10.17.2008
| 22282 views |
  • submit to reddit
So you are using the NetBeans Platform and you know that it allows you to create a really modular design, in which components can be plugged in and out at your wish. But now, which pattern can you use to reduce the coupling between components that must talk together? Consider for instance the problem I face with blueMarine: some components ('explorers') allow you to query the internal database of pictures with different criteria (e.g. browsing the filesystem, by metadata, by tag...), while other components ('views') show the result in different ways (e.g. thumbnails, or property panels, or full rendering). Which is the better approach: to have explorers depending on viewers, so they can directly call a method on them? Or the opposite?

The best solution is to have neither of the two depending on each other. You can achieve that with my favorite decoupling pattern, "publish and subscribe": define a set of messages ("topics"), define portions of code that register interest in those topics and receive an asynchronous notification ("subscribers") , and define portions of code that publish and unpublish those topics ("publishers"). Then you're done. All the components can now communicate without knowing about each other, while only depending on the messaging infrastructure and on the topics.

Indeed, this is one of the first parts that I developed in blueMarine when I ported it to the NetBeans Platform more than two years ago, and it was a pretty good improvement from the previous design. The implementation was focused on the NetBeans Platform's Lookup class, one of the most powerful in the NetBeans Platform. While it is mostly used for looking up services registered in the application, it is also used by the NetBeans Platform runtime to store relevant objects (such as selected items in a list) and to notify listeners (such context sensitive actions). So I basically used a global Lookup provided by the NetBeans Platform, "Utilities.actionsGlobalContext()", to listen for selections that were made in TopComponents. It seemed a pretty logical way to work, since TopComponents usually contain an ExplorerManager that automatically receives notification of selected Nodes in trees or lists that are placed inside the TopComponent. So, the flow of events is:

select a node in a tree -> notification published to ExplorerManager -> notification published to the actionsGlobalContext() -> notification received by my listener.

With this approach, you can use the class information as the 'topic': when you select a Node, everything that is inside its private Lookup (for instance, the DataObject) gets published. DataObject is obviously one of the most used topics by blueMarine (representing photos) and delivers information about selecting a single object: to notify that a set of DataObjects has been prepared, I defined a specific class named DataObjectSelection; to notify that there is a selection task running in the background, another specific object (DataObjectSelectionInProgress) is used, so viewers can display a "Please wait" message.

Published at DZone with permission of Fabrizio Giudici, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Aljoscha Rittner replied on Fri, 2008/10/17 - 8:22am

Excelent, I like the clean implementation. IMHO many RCP projects need this feature.

best regards, josh.

Pavan Kumar Sri... replied on Fri, 2008/10/17 - 12:45pm

 

We can also use the EventBus API from https://eventbus.dev.java.net/ , which could easily  be used  in existing swing apps which don't use the  netbeans platform  .

vincent cobra replied on Fri, 2008/10/17 - 6:21pm

Last time I tried to use EventBus from java.net, few months ago, it was buggy, so I had to roll my own implementation(not open source).

   It would be more interesting and probably more useful to contribute to the existing EventBus project instead of writing such a library in my opinion. EventBus probably does a whole lot more already.

Jean-Francois P... replied on Fri, 2008/10/17 - 7:52pm

Why reinvent the wheel?

I have done that myself a couple of years ago (I think a few month before the "EventBus" project on java.net) and made it OSS (if you are interested, you can take a look here http://hivetranse.sourceforge.net/ but i's covered with dust now;-))

Java.net EventBus already does all that (and has been existing for several years now).

If EventBus has bugs, then anyone can report these and even contribute (it is OSS after all).

Pavan Kumar Sri... replied on Sat, 2008/10/18 - 3:13am in response to: Jean-Francois Poilpret

 

Yeah...very true....that should be our approach instead of re-inventing the wheel... 

Fabrizio Giudici replied on Sat, 2008/10/18 - 3:29am

I think that Java.Net's EventBus is a good solution for people working with plain Swing applications; the code provided by Wade and me it's a very thin syntaptic sugar wrapper around the Lookup API, which plays a central role in the NetBeans Platform. With very few changes, one could wrap an EventBus around one of the many Lookup instances that exist in the Platform, enabling locally scoped EventBuses, for instance one per TopComponent or even one for DataObject, etc...

Tim Boudreau replied on Wed, 2008/10/22 - 8:45am

Slight preference for

public void onEvent (T object);

to notify() as the method name.  Generally on* makes a more readable pattern for listener-like things (and avoids confusion with Object.notify() and friends.

 

-Tim

Michael Bushe replied on Thu, 2008/11/06 - 7:52pm in response to: vincent cobra

I own the EventBus project.  This is the first time I ever heard someone call the EventBus "buggy."  I take bug reports very seriously.  There are no open bugs in the project and there have only been 7 bug reports in its history, most minor and in beta versions.  If you identify a bug, please add an issue to the java.net project, or if you don't won't to be bothered, send an email.   If it's a real bug, I will likely fix it within 24 hours.

You probably ran into an issue with using WeakReferences by default.  If you call subscribe (and don't call subscribeStrongly) and nothing else holds a reference to that object but the EventBus, then the object will be garbage collected.  This is a feature, not a bug.  A warning to new users appears on the website, the examples and the javadoc, it's probably mentioned about 20 times in total.

Michael Bushe replied on Thu, 2008/11/06 - 8:13pm in response to: Fabrizio Giudici

Fabrizio,

The EventBus' has some pretty cool options for locally-scoped convesations.  One is the ContainerEventServiceRegsitrar and ContainerEventServiceFinder.

If a component needs to subscribe to an event in it's container, create a ContainerEventServiceRegsitrar on its construction:
<code>
public MyFormCombo extends JComboBox implements EventSubscriber {
     public MyFormCombo() {
        new ContainerEventServiceRegsitrar(this, this, MyEvent.class);
    }
}
</code>
This is kind of magical in the sense that registrar will wait until the component is added to a container.  When it is, then it searches up the containment hierarchy to find a locally scopped SwingEventService.  If a parent implements ContainerEventServiceSupplier (perhaps implemented by MyFormPanel), then it uses it.  Otherwise, it dynamically creates one on the JRootPane (so it covers dialogs, frames, internal frames, docing components, etc.) and subscribes the component to MyEvent.class.  If the component is moved, it readjusts the subscription to the new container.

To publish to the container, use the ContainerEventServiceFinder:
<code>
ContainerEventServiceFinder.getEventService(someComponentInTheLocalScope).publish(new MyEvent("Hello!"));
</code>

I'm hoping I find the time to figure out the best ways to integrate this into Netbeans RCP, I like your suggestion, Fabrizio.

Michael

Michael Bushe replied on Thu, 2008/11/06 - 8:17pm in response to: Michael Bushe

Strange, I posted an earlier version of my comment, must be the IE8 beta.

The other option is the EventServiceLocator for publishing on private "channels" (or busses):
EventServiceLocator.getEventService("MyPrivateChannel").publish("Foo", new Bar());//topic example

Ashley Ford replied on Tue, 2011/01/11 - 1:24pm

I wish I had known about publish and subscribe sooner! I followed your suggestion to set parameters for search and I am really happy with the results.

 Everyone is buzzing about 'local search'. I run my own business ("Family Leisure") and I want to try and reach out to customers using more than just Google and Facebook. Is there a platform I can utilize to make this easier?  Thanks! 

 Tina Figgler, Family Leisure

Ashley Ford replied on Tue, 2011/01/11 - 1:22pm in response to: Michael Bushe

This is what I was looking for I think, thanks!

Carla Brian replied on Mon, 2012/04/16 - 6:50pm

This is really helpful. It is a broad Java framework on which you can base large desktop applications. I can't wait using this platform. I need to study the mechanics first. - Incredible Discoveries

Martin Sooner replied on Sun, 2012/04/22 - 6:42am

What other platforms that compatible with the netbeans because I’m also thinking about porting it with my website as well tech comm

Gilber Mantis replied on Fri, 2012/04/27 - 3:48am in response to: Pavan Kumar Srinivasan

One of the reason I like using Ruby is that I can integrate my custom made Flash program to enhance the look of my website asphaltene

Mateo Gomez replied on Mon, 2012/05/21 - 3:42am in response to: Aljoscha Rittner

very clean implementation indeed

mexican dip recipes
 

Matt Coleman replied on Thu, 2013/03/14 - 12:53am in response to: Aljoscha Rittner

very clean indeed...i agree on all points

buffalo search engine optimization 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.