| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| |
| = DevFaqNodesCustomLookup |
| :jbake-type: wiki |
| :jbake-tags: wiki, devfaq, needsreview |
| :jbake-status: published |
| :keywords: Apache NetBeans wiki DevFaqNodesCustomLookup |
| :description: Apache NetBeans wiki DevFaqNodesCustomLookup |
| :toc: left |
| :toc-title: |
| :syntax: true |
| |
| === I need to add-to/remove-from/customize the content of my Node/DataObject/TopComponent's Lookup. How do I do it? |
| |
| If it's just adding something, use |
| |
| [source,java] |
| ---- |
| |
| return new ProxyLookup( |
| new Lookup[] { |
| super.getLookup(), |
| Lookups.fixed( |
| something, somethingElse) |
| }); |
| |
| ---- |
| |
| If there's only one object, substitute `Lookups.singleton ( someObject )`. |
| |
| If you need to change the content of the lookup on the fly, it's a little more complicated, but not too much. Use the above |
| ProxyLookup technique if there's a Lookup returned by the superclass and you still want to use its content. |
| What you'll use to change content on the fly is the combination of `AbstractLookup` (which, as fate would |
| have it, is not actually abstract), and `InstanceContent`, which is a grab bag of stuff you can add to and |
| remove from. |
| |
| The result will look something like this: |
| |
| [source,java] |
| ---- |
| |
| class MyNode extends AbstractNode { |
| private final InstanceContent lookupContents; |
| public MyNode() { |
| this(new InstanceContent()); |
| } |
| private MyNode(InstanceContent ic) { |
| super(Children.LEAF, new AbstractLookup(ic)); |
| this.lookupContents = ic; |
| } |
| } |
| |
| ---- |
| |
| When you need to change the contents of your lookup, you can call `InstanceContent.add()` or and `InstanceContent.remove()`, e.g.: |
| |
| [source,java] |
| ---- |
| |
| lookupContents.add(someObject); |
| lookupContents.remove(someObject); |
| |
| ---- |
| |
| Your lookup will be updated to include all items in the InstanceContent. |
| |
| ==== Custom Lookup Contents with DataObjects |
| |
| DataObjects have a Lookup, but also use an older variant on the Lookup pattern, called a `link:http://bits.netbeans.org/dev/javadoc/org-openide-nodes/org/openide/nodes/CookieSet.html[CookieSet]`. Since this is a somewhat bewildering term, and `CookieSet` will eventually be deprecated, you may want to avoid using it. A `CookieSet` ordinarily provides the `Lookup` for a DataObject; and certain APIs such as `DataEditorSupport` require it. |
| |
| However, it is possible to work with the more modern idioms of Lookup as described above, with a few caveats. Such a DataObject typically looks like: |
| |
| [source,java] |
| ---- |
| |
| public class FooDataObject extends MultiDataObject { |
| private final Lookup lookup; |
| private final InstanceContent lookupContents = new InstanceContent(); |
| public FooDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { |
| super(pf, loader); |
| lookup = new ProxyLookup(getCookieSet().getLookup(), new AbstractLookup(lookupContents)); |
| lookupContents.add (...whatever...); |
| } |
| |
| @Override |
| public Lookup getLookup() { |
| return lookup; |
| } |
| |
| @Override |
| protected Node createNodeDelegate() { |
| return new DataNode (this, Children.LEAF, getLookup()); |
| } |
| //... |
| |
| ---- |
| |
| You can then add and remove objects from your `InstanceContent` and the `DataObject` will behave as expected. |
| |
| *Caveat 1: You really must override `createNodeDelegate()`* or otherwise (in your `DataNode` subclass) pass your `DataObject`'s `Lookup` to your `DataNode`'s constructor. Otherwise its lookup will be `getCookieSet().getLookup()` and nothing added to your `InstanceContent` will appear in the `Lookup` of your `Node`. So, _if you use AbstractLookup in a DataObject, make sure its Node is really using your DataObject's Lookup_. |
| |
| *Caveat 2: A DataObject should always appear in its own Lookup* — If you are _really sure_ that nothing is going to use your `DataObject`'s `CookieSet` at all, you can omit merging `getCookieSet().getLookup()` into the `ProxyLookup` in the constructor. However, many things will not work correctly if _the DataObject itself_ cannot be found in its own `Lookup`. If you are going to do that, replace `getCookieSet().getLookup()` with `Lookups.singleton(this)` to ensure it is present and cannot be removed or replaced. |
| |
| === Apache Migration Information |
| |
| The content in this page was kindly donated by Oracle Corp. to the |
| Apache Software Foundation. |
| |
| This page was exported from link:http://wiki.netbeans.org/DevFaqNodesCustomLookup[http://wiki.netbeans.org/DevFaqNodesCustomLookup] , |
| that was last modified by NetBeans user Jtulach |
| on 2010-07-24T19:02:08Z. |
| |
| |
| *NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed. |