netbeans.apache.org/src/content/wiki/DevFaqNodesCustomLookup.adoc (101 lines of code) (raw):

// // 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. // = I need to add-to/remove-from/customize the content of my Node/DataObject/TopComponent's Lookup. How do I do it? :jbake-type: wikidev :jbake-tags: wiki, devfaq, needsreview :jbake-status: published :keywords: Apache NetBeans wiki DevFaqNodesCustomLookup :description: Apache NetBeans wiki DevFaqNodesCustomLookup :toc: left :toc-title: :syntax: true :wikidevsection: _nodes_and_explorer :position: 15 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:https://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. ////