欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

NetBeans RCP: Loosely-coupled communication between modules

程序员文章站 2022-06-04 14:33:43
...

 

Register and Lookup Serivces (Globol Lookup)

 

1) In service module, create a service interface

 

public interface TaskIdGenerator {
    public String generateID();
}
 

In order to register a service, you only need to annotate a class with the @ServiceProvider annotation to fulfill the Java extension mechanism requirement, as this annotation causes the META-INF/services folder to be created at compile time, together with the required service provider registration.

 

@ServiceProvider(service = TaskIdGenerator.class)
public class TaskIdGeneratorImpl implements TaskIdGenerator {
   

2) Lookup the service from another module

 

The default Lookup finds the files created at compile time in the META-INF/services folder, evaluates them, and gives back instances of registered implementing classes.

 

TaskIdGenerator idGen = Lookup.getDefault().lookup(TaskIdGenerator.class);
this.id = idGen.generateID();
 

or get all registered implementations of the service:

 

Collection<? extends TaskIdGenerator> idGen =
Lookup.getDefault().lookupAll(TaskIdGenerator.class);

 

Exchange Data (Local Lookup)

 

To make loose coupling possible, an information provider is able to administer its own Lookup, providing it to anyone interested in its information. Into its Lookup, the provider can put objects that the consumer might find useful. The consumer only needs to find the Lookup and get the objects, based on their type.

 

The ability to administer and provide a Lookup is defined via the Lookup.Provider interface:

Lookup getLookup()

 

The TopComponent class already implements Lookup.Provider and provide a method for resetting the Lookup.

 

  • Usage 1:

 

Instead of implementing your own Lookup, you use the Lookup class, which creates a Lookup with one single object:

 

associateLookup(Lookups.singleton(taskEditorPanel1.task));

 

 

You can get the Task instance in another TopComponent subclass:

 

Task task = WindowManager.getDefault().
findTopComponent("TaskEditorTopComponent").
getLookup().lookup(Task.class);

 

  • Usage 2 (dynamic changes and notifications):

 

1) On data provider side:

 

InstanceContent class enables us to dynamically change the content of the Lookup.

 

InstanceContent content = new InstanceContent();
associateLookup(new AbstractLookup(content));

 

set the lookup data whenever you want to update it:

 

Mp3FileObject mp3 = ...;
content.set(Collections.singleton(mp3), null);

 

2) On data consumer side:

 

The NetBeans window system already provides an instance of the central proxy component, the class Global-ActionContextImpl. This class provides a proxy Lookup, which accesses the local Lookup of the
focused TopComponent. This Lookup can be obtained by calling the static utility method Utilities. actionsGlobalContext().

 

To get notification of changes in the Lookup, the LookupListener interface is implemented.

 

A Lookup.Result, which enables us to react to changes for a specific type (in our case Mp3FileObject), is used as a private member.

 

public class Mp3DetailsView extends TopComponent implements LookupListener {

private Lookup.Result<Mp3FileObject> result = null;

public void componentOpened() {
    result = Utilities.actionsGlobalContext().lookupResult(Mp3FileObject.class);
    result.addLookupListener(this);
    resultChanged(null);
}

public void resultChanged(LookupEvent event) {
    Collection<? extends Mp3FileObject> mp3s = result.allInstances();
    if(!mp3s.isEmpty()) {
        Mp3FileObject mp3 = mp3s.iterator().next();

 

 

Hidden Lookup API to Consumers (Global Services)

 

the services manage the implementation on their own and provide an additional
trivial implementation (as an inner class) in case there is no other implementation registered
in the system. This has the advantage that the user always gets a valid reference to a service and
never a null value.

 

The advantage of this pattern is that there is no need for users of the service to
know anything about the Lookup API.

 

public abstract class Mp3Player {
    public abstract void play(Mp3FileObject mp3);
    public abstract void stop();
    public static Mp3Player getDefault() {
        Mp3Player player = Lookup.getDefault().lookup(Mp3Player.class);
        if(player == null) {
            player = new DefaultMp3Player();
        }
        return(player);
    }

    private static class DefaultMp3Player extends Mp3Player {
        public void play(Mp3FileObject mp3) {
        }
        public void stop() {}
    }
}
 

References

 

相关标签: Netbeans Exchange