blob: 20644a2c34772a98df59e9637d3e008f7742bac2 [file] [log] [blame]
//
// 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.