Hi @ajp
What I implemented is the following:
- All the nodes I want to add or remove have a custom API interface, following the example from @jbm:
URCap Sample: URCap CustomAPI
Node contribution:
public class MyNodeToAddAndRemoveContribution implements ProgramNodeContribution, MyNodeToAddAndRemoveCustomAPI
{
// this is my node contribution
}
Node custom api interface:
public interface MyNodeToAddAndRemoveCustomAPI
{
// this is my custom api interface
// I have myself nothing inside this interface
}
- In my root node, from which I will be able thanks to a checkbox to add and remove the node mentioned previously:
- I am using the ProgramNodeVisitor to retrieve the index of the MyNodeToAddAndRemove in my program hierarchy:
private int getMyNodeToAddAndRemoveIndex()
{
final int childIndex = new int[1];
childIndex[0] = -1;TreeNode root = apiProvider.getProgramAPI().getProgramModel().getRootTreeNode(this); root.traverse(new ProgramNodeVisitor() { @Override public void visit(URCapProgramNode programNode, int index, int depth) { if(programNode.canGetAs(MyNodeToAddAndRemoveCustomAPI.class)) { //System.out.println("Index: " + index); childIndex[0] = index; } } }); // return -1 if the node does not exist return childIndex[0];
}
- When the user enables or disables the check box:
public void setMyNodeToAddAndRemoveState(final boolean state)
{
this.undoRedoManager.recordChanges(new UndoableChanges()
{
@Override
public void executeChanges()
{// set the model state accordingly here // ... TreeNode root = this.programAPI.getProgramModel().getRootTreeNode(this); if (state) { // add the node (in try-catch) if (ProgramNodeHelper.getChildrenNb(root) > 0) root.insertChildBefore(root.getChildren().get(0), this.programNodeFactory.createURCapProgramNode(MyNodeToAddAndRemoveService.class)); else root.addChild(this.programNodeFactory.createURCapProgramNode(MyNodeToAddAndRemoveService.class)); } else { // remove the node (in try-catch) int myIndex = this.getMyNodeToAddAndRemoveIndex(); if (myIndex < 0) return; root.removeChild(root.getChildren().get(myIndex)); } } });
}
- If some sub nodes must be added anyway and are not interactable through checkboxes, they must be added from the root node constructor only if the context is a node creation:
public MyRootNodeContribution(ProgramAPIProvider apiProvider, MyRootNodeView view,
DataModel model, CreationContext context)
{
// constructor
// do something
if (context.getNodeCreationType() == NodeCreationType.NEW)
{
TreeNode root = this.programAPI.getProgramModel().getRootTreeNode(this);
// in a try-catch
root.addChild(this.programNodeFactory.createURCapProgramNode(MyPermanentNodeService.class));
}
}
Sorry for the bad indentation. Other than that, that should do the trick. Let me know if you have any questions.