NetBeans Lookups 解析

NetBeans Lookups 解析

(作者:Toni Epple 译:李佳明)

 

   

Lookup是Netbeans平台中最重要的部份,无论何时何地需要向已投递的列表中申请信息时都需要使用Lookup。很多时候,当把Lookup作为一个非常特殊的上下文工具——例如选择管理器或ServiceLoader解释时,会将Lookup复杂化而难于理解,但实际上它非常简单并且特别有用。

这就是为什么我认为是时候写一篇文章来解释Lookup的本质以及如何使用它的原因。下面我将解释如何使用它来解决一些常规问题。

Lookup作为数据结构的情况

 首先来看看将Lookup作为数据结构的情况。Lookup是一种Map,它将类对象作为“键”,以键相关的一组类对象作为值。与Map不同,Lookup还有一个额外的功能用于监听其内部的变化,但它和Map一样简单。如果你想向Lookup请求获得它的内容,你可以像这样使用它:

    Lookup  lookup = //get a lookup somewhere...
    Collection <String>strings =lookup.lookupAll(String.class);

如果想监听它的变化,可以向Lookup.Result(表示查询结果的内部类)添加一个监听器,这样的监听器会监听特定类对象的增加或删除。

    Lookup.Result <String>strings = lookup.lookupResult(String.class);
    strings.allItems();
    strings.addLookupListener(new LookupListener(){  
       @override
       public void resultChanged(LookupEvente){
           // do something
       }}
    );

这就是通常使用一个已有Lookup的方法。但如果想创建一个Lookup,也有很多实现方法,其中最简单的就是Lookup.Singleton,它只包含一个对象。

    Lookup simple = Lookups.singleton("HelloWorld!");

还有一个实现用以创建保存多个固定实体的Lookup:

    Lookups moreElements = Lookups.fixed( "Hello", "World", new Integer(5));

如果想要使作一个Lookup来动态地向里面放东西,则需要选择支持此功能的另一种实现方法,其中最灵活的一种是使用一个InstanceContent对象来增加或删除所保存的内容。

    InstanceContent content = new InstanceContent();
    Lookup dynamicLookup = new AbstractLookup(content);
    content.add("Hello");
    content.add(5);

     注册于相应类的监听器在内容改变时会得到通知。如果想在同一时刻查询多个Lookup,可以使用ProxyLookup。下面就是一个例子,它将上面创建的两个Lookup组合在一起。

    ProxyLookup proxy = new ProxyLookup(dynamicLookup,moreElements);
Lookup.Provider

    如果你的对象有一个Lookup来存储一连串的东西,你可以通过实现Lookup.Provider接口来让该Lookup具备可访问性,该接口只有一个方法:

    public Lookup getLookup();

    同样特别的简单。所有对该对象中的Lookup的内容感兴趣的人均可请求到该Lookup并向它注册监听器以侦听它的改变。在Netbeans中,TopComponent实现了此接口,因此可以取得任何TopComponent中的Lookup,取得绝大多数TopComponent的最简单的方法是通过它的ID:

    TopComponent tc = WindowManager.getDefault().findTopComponent("AnInterestingTopComponent");
    Lookup tcLookup = tc.getlookup();

    由于大多数的TopComponent在其中的任何东西被选中时会将它们放入Lookup——例如选中列表中的项,因此你可以添加一个监听器来跟踪在TopComponent中的选择。例如,如果对被选的结点感兴趣,可以这样做:

    Lookup.result <Node> noderesult =tcLookup.lookupResult(Node.class);
    result.allInstances();
    noderesult.addLookuplistener(myLookupListener);

    在提供“主—从”视图的情况下这特别有用。如果你想在自己的TopComponent中提供自己的Lookup,可以这样做:

    associateLookup(mylookup);

全局选取

    有时你可能不仅对特定TopComponent中的选取内容感兴趣,还对此刻拥有焦点的TopComponent中的选取内容感兴趣。这同样很容易,因为Netbeans提供了一个代理当前聚焦的TopComponent中的Lookup的Lookup。要使用它,仅需像这样:

    Lookup global = Utilities.actionsGlobalContext();

    你可以像使用其他任何Lookup一样使用它,没有任何特别之处。

结点

    结点(Node)也实现了Lookup.Provider接口,因此也同样可以请求获得它们的Lookup。存储于Node的Lookup中有用的东西是代表某种数据的DataObject。如果使用结点,你可能会将DataObject存储于Node中,并结合用以显示该结点的Explorer API一起使用,如果这样,你可以会通过ExplorerManager的帮助为你的TopComponent创建一个Lookup。

    associateLookup(ExplorerUtils.createLookup(explorermanager, this.getActionMap()));

    返回的Lookup同样代理了被选结点的Lookup的内容。这样,任何人感兴趣的东西都可通过你的TopComponent的Lookup展现出来。

服务调用和其他用法

    正如上面所述,Lookup其实是一种非常简单但极为有用的概念,Netbeans Zone中的有些文章还介绍了使用Lookup在Netbeans RCP应用程序中调用服务的方法,这也是重要的应用。要完成服务调用,Netbeans提供了一个默认Lookup,它一般用于在特定位置用以注册服务,例如在一个模型的jar文件的META-INF/services目录或模型的layer.xml文件中。如果你对获取一个服务实现的实例感兴趣,可以这样做:

    Collection <ServiceInterface> services= Lookup.getDefault().lookupAll(ServiceInterface.class);

    如果你在layer.xml中注册你的服务,你可以获得一个特定目录的Lookup,如下所示:

    Lookup lkp = Lookups.forPath("ServiceProviders");
    我想这就是你开始使用Lookup时所要了解的全部内容,那么祝你用愉快,它确实很简单。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值