org.openide.nodes.ChildFactory
除非您特别需要使用其中一种Children
API ,否则建议使用它来创建子节点。但是对于常见的情况,ChildFactory
就足够了。
使用 Nodes API 时要记住的一件事是,它只是一个包装模型的表示层,并与 Explorer API 结合使用,使其可用于 NetBeans 平台中的各种视图组件,例如org.openide.explorer.view.BeanTreeView
.
使用一个名为的模型MyModel
,它可能看起来像:
public class MyModel {
private String title;
private List<MyChild> children;
public MyModel(List<MyChild> children) {
this.children = children;
}
public String getTitle() {
return title;
}
public List<MyChild> getChildren() {
return Collections.unmodifiableList(children);
}
}
您可以创建一个ChildFactory<MyModel>
负责创建节点的:
public class MyChildFactory extends ChildFactory<MyModel> {
private List<MyModel> myModels;
public MyChildFactory(List<MyModel> myModels) {
this.myModels = myModels;
}
protected boolean createKeys(List<MyModel> toPopulate) {
return toPopulate.addAll(myModels);
}
protected Node createNodeForKey(MyModel myModel) {
return new MyNode(myModel);
}
protected void removeNotify() {
this.myModels= null;
}
}
然后,实现MyNode
表示层并包装MyModel
:
public class MyNode extends AbstractNode {
public MyNode(MyModel myModel) {
this(myModel, new InstanceContent());
}
private MyNode(MyModel myModel, InstanceContent content) {
super(Children.create(
new MyChildrenChildFactory(myModel.getChildren()), true),
new AbstractLookup(content)); // add a Lookup
// add myModel to the lookup so you can retrieve it latter
content.add(myModel);
// set the name used in the presentation
setName(myModel.getTitle());
// set the icon used in the presentation
setIconBaseWithExtension("com/my/resouces/icon.png");
}
}
现在MyChildrenChildFactory
which 与它非常相似,MyChildFactory
只是它需要 aList<MyChild>
并依次创建MyChildNode
:
public class MyChildFactory extends ChildFactory<MyChild> {
private List<MyChild> myChildren;
public MyChildFactory(List<MyChild> myChildren) {
this.myChildren = myChildren;
}
protected boolean createKeys(List<MyChild> toPopulate) {
return toPopulate.addAll(myChildren);
}
protected Node createNodeForKey(MyChild myChild) {
return new MyChildNode(myChild);
}
protected void removeNotify() {
this.myChildren = null;
}
}
然后一个实现MyChildNode
非常类似于MyNode
:
public class MyChildNode extends AbstractNode {
public MyChildNode(MyChild myChild) {
// no children and another way to add a Lookup
super(Children.LEAF, Lookups.singleton(myChild));
// set the name used in the presentation
setName(myChild.getTitle());
// set the icon used in the presentation
setIconBaseWithExtension("com/my/resouces/child_icon.png");
}
}
我们将需要儿童模型,MyChild
它非常类似于MyModel
:
public class MyChild {
private String title;
public String getTitle() {
return title;
}
}
最后将其全部使用,例如与 a BeanTreeView
which 将驻留在 a TopComponent
that implements中org.openide.explorer.ExplorerManager.Provider
:
// somewhere in your TopComponent's initialization code:
List<MyModel> myModels = ...
// defined as a property in you TC
explorerManager = new ExplorerManager();
// this is the important bit and we're using true
// to tell it to create the children asynchronously
Children children = Children.create(new MyChildFactory(myModels), true);
explorerManager.setRootContext(new AbstractNode(children));
请注意,您不需要触摸BeanTreeView
,实际上它可以是平台中包含的任何视图组件。这是创建节点的推荐方法,正如我已经说过的,节点的使用是作为一个表示层,用于平台中包含的各种组件中。
如果您然后需要获得一个孩子,您可以使用ExplorerManager
您可以从TopComponent
使用实现的方法ExplorerManager.Provier.getExplorerManager()
中检索的孩子,因为您TopComponent
实现ExplorerManager.Provider
了并且实际上是视图组件本身获取节点的方式:
ExplorerManager explorerManager = ...
// the AbstractNode from above
Node rootContext = explorerManager.getRootContext();
// the MyNode(s) from above
Children children = rootContext.getChildren().getNodes(true);
// looking up the MyModel that we added to the lookup in the MyNode
MyModel myModel = nodes[0].getLookup().lookup(MyModel.class);
但是,您必须注意,使用该Children.getNodes(true)
方法获取节点将导致创建所有节点及其子节点;由于我们告诉工厂我们希望它异步创建子代,因此没有创建它。这不是访问数据的推荐方式,但您应该保留对 的引用List<MyModel>
并尽可能使用它。从文档中Children.getNodes(boolean)
:
...一般来说,如果您试图通过调用此方法来获取有用的数据,那么您可能做错了什么。通常你应该向一些底层模型询问信息,而不是子节点。
同样,您必须记住 Nodes API 是一个表示层,并用作模型和视图之间的适配器。
ChildFactory
当在不同和不同的视图中使用相同的技术时,这成为一种强大的技术。您可以在许多地方重用上面的代码,TopComponents
而无需任何修改。FilterNode
如果您只需要更改节点的一部分表示,而不必触及原始节点,您也可以使用 a 。
毫无疑问,学习 Nodes API 是学习 NetBeans 平台 API 时更具挑战性的方面之一。一旦您掌握了这个 API,您将能够利用更多平台的内置功能。
有关 Nodes API 的更多信息,请参阅以下资源: