Group outline nodes
I'm developing an XTEXT 2.0 plugin. I'd like to group some nodes inside my outline in a "virtual" node. Which is the right way to achieve this result?
Currently if i want to group nodes of type "A", in my OutlineTreeProvider I define the following method
protected void _createNode(IOutlineNode parentNode, A node) {
if(this.myContainerNode == null){
A container = S3DFactoryImpl.eINSTANCE.createA();
super._createNode(parentNode, container);
List<IOutlineNode> children = parentNode.getChildren();
this.myContainerNode = children.get(children.size()-1);
}
super._createNode(this.myContainerNode, node);
}
Reading the Xtext 2.0 documenta开发者_StackOverflowtion i saw also that there is a EStructuralFeatureNode. I didn't understand exactly what this type of node is and how to use it. Can you explain what EStructuralFeatureNode is used for?
Many thanks
There are a couple of problems with your code:
this.myContainerNode
: There is no guarantee that your provider is a prototype; someone could configure the instance as singleton. Therefore, avoid instance fields.
There are two solutions to this problem:
- Search the parent node for your container node whenever you need it (slow but simple)
- Add a cache to your instance (see How do I attach some cached information to an Eclipse editor or resource?)
super._createNode()
: Don't call the methods with _
, always call the plain version (super.createNode()
). That method will figure out which overloaded _create
* method to call for you. But in your case, you can't call any of these methods because you'd get a loop. Call createEObjectNode()
instead.
Lastely, you don't need to create an instance of A
(S3DFactoryImpl.eINSTANCE.createA()
). Nodes can be backed by model elements but that's optional.
For grouping, I use this class:
public class VirtualOutlineNode extends AbstractOutlineNode {
protected VirtualOutlineNode( IOutlineNode parent, Image image, Object text, boolean isLeaf ) {
super( parent, image, text, isLeaf );
}
}
In your case, the code would look like so:
protected void _createNode(IOutlineNode parentNode, A node) {
VirtualOutlineNode group = findExistingNode();
if( null == group ) {
group = new VirtualOutlineNode( parentNode, null, "Group A", false );
}
// calling super._createNode() or super.createNode() would create a loop
createEObjectNode( group, node );
}
精彩评论