Rediscovering the NetBeans Lookup Library (II)

In my previous blog entry about the NetBeans Lookup Library we learned how to look-up stuff inside what we called "travel bags".

In this entry we'll take a quick look at how to create our own travel bags.

The global travel bag

The NetBeans Lookup Library has a special travel bag known as the "Global Lookup".

You can get a reference to this huge travel bag as follows:

    Lookup globalBag = Lookup.getDefault();

This global bag contains lots of things, and its contents may vary depending on the application you're running.

In a standalone application, the "Global Lookup" contains a list of all services registered in your application using the jar file service provider interface.

Say your application has at least tree jar files, named A.jar, B.jar and C.jar (and our well known org-openide-util.jar as well, of course).

Say that each one of those jar files contains a plain text file named "META-INF/services/my.package.MyInterface" and that the content of that file is as follows:

  • The content of A.jar/META-INF/services/my.package.MyInterface is "my.package.MyAImpl"
  • The content of B.jar/META-INF/services/my.package.MyInterface is "my.package.MyBImpl"
  • The content of C.jar/META-INF/services/my.package.MyInterface is "my.package.MyCImpl"

By using the NetBeans Lookup Library you can find all the implementations of the my.package.MyInterface interface bundled in your application:

    Lookup global = Lookup.getDefault();
    Collection impls =
      global.lookup( my.package.MyInterface.class );

So the collection "impls" above will contain instances of "my.package.MyAImpl", "my.package.MyBImpl" and "my.package.MyCImpl".

What I mean is that the global lookup can be used to find implementations of interfaces registered using the "META-INF/services" directory.

And, more importantly, that it doesn't matter how many jar files you add, but the Global Lookup will always find those implementations for you.

If you run your application inside the NetBeans Rich Client Platform you can use the global lookup to find some more interesting stuff, such as the contents of the "layer.xml" files of your modules, for instance.

So, to summarize: the Global Lookup contains information about your application, including all services registered using the jar-file service provider mechanism.

Creating your own travel bags

That's cool and easy but, how do we create our own travel bags? How do we place stuff inside them? Let's review the different ways to create travel bags.

Travel bags with a single object

To create a Lookup object with a single object you may use the Lookups class (an utility class used to create travel bags).

    Lookup myBag = Lookups.singleton( "Hello, world");

The resulting travel bag will contain a single object (a String in this case) and the results of this Lookup will be fixed and not allowed to change.

Travel bags with many objects

The Lookups utility class contains methods to create travel bags with a variable number of objects:

    Lookup myBag = Lookups.fixed( "Hello", "World" );

The resulting bag will contain two objects (strings in this class) and you won't be able to modify its contents.

Travel bags of travel bags

You can also combine the contents of different bags inside a bigger one using a ProxyLookup like this:

    Lookup helloBag = Lookups.singleton("Hello");
    Lookup worldBag = Lookups.singleton("World");
    Lookup helloWorldBag =
      new ProxyLookup( helloBag, worldBag );

So "helloWorldBag" will contain the contents of "helloBag" and of "worldBag".

The interesting feature of this "combined" lookup object is that if the contents of any of the original bags change, then the result of the "combined" lookup will also change!!

Your own custom travel bags

But how can we create our own travel bags, you ask? Well, the very first thing you need is an InstanceContent object to hold the stuff in your bag. And then you create an AbstractLookup (which is, peculiarly, not abstract) with it. Like this:

    InstanceContent contents = new InstanceContent();
    Lookup myTravelBag = new AbstractLookup( contents );
    contents.add("Hello");
    contents.add( new Integer(5) );
    contents.add("Goodbye");

That's easy, isn't it?

Summary and... what next?

So in the previous entry we've seen how to look up stuff in travel bags, and in this entry we've seen how to create travel bags.

We're almost all set. What next, you ask? Well, in the next entry we'll see what the NetBeans Lookup Library has to do with... rabbits!!

Until next time, Antonio

  • Comment #1, by Emmbec

    Hi, I am having trouble understanding the lookups. I have an API Object that just stores some String, then on a TopComponent I create a new instance of that API Object.

    So if I click for example in an action button that creates each time a new instance of my APIObject I will end up with many windows that will contain my API object (In which I can of course edit the String that the API Object has).

    How can I store ALL of the API Objects that are opened in a Lookup?

    How can I retrieve ALL the opened API Objects in an array or something like that?

    Thanks!

  • Comment #2, by Antonio

    Hi Emmbec,

    Please send me an email with a concrete example of your problem.

    Cheers,
    Antonio

  • Comment #3, by j

    # InstanceContent contents = new InstanceContent();
    # Lookup myTravelBag = new AbstractLookup( contents );
    # contents.add(

  • Comment #4, by Emmanuel

    How to you put objects into the Global Bag?

  • Comment #5, by HMMM

    Hi Antonio

    Thanks for the good introduction to Lookup, but im still a little confused. I want to monitor changes in a data structure of connected objects. Should this structure define its own lookup and attach it like datastructureA.getLookup() where all objects in the data structure would be registrered/added? And how should you access this lookup from other independent modules, e.g. for creating different views/editors? The idea is using a listener on a lookup to update the different views... This idea seems to smell eventhough its MVC like - is there a better way?

    Cheers,
    HMMM

  • Comment #6, by sanu

    Hi Antonio,

    Nice simple explanation. We know that the listener is notified when contents of a lookup changes.

    Does change of content here only mean adding / removing an object from the lookup, or, making changes to fields within one of the objects too.

Add a comment




No HTML allowed.