Communication from ChildNode to ParentNode in Java

Hello UR community,

I am having difficulties making child nodes communicate with their parent node, cause I’d like the children to somehow communicate with each other (through the parent if necessary).

Let me explain what I know so far:

  • Nodes don’t share datamodels.
  • There is a useful CustomAPI URCAP sample that shows how to communicate parent to children.
  • Parents can interact with children through the “ProgramNodeVisitor”, but children supposedly can’t, as the
    “ProgramNodeVisitor” needs a TreeNode object, which only shows the nodes from the current Node and downwards, so a child wouldn’t be able to see its parent through the Visitor.

The thing is, I have seen other URCAPs (not the sample ones) create a “sibling” node from the children, and I don’t know how they can do that, but it proves that communication children-> parent is certainly possible.

Would you help me shed some light on the topic?

Thanks in advance.

Best Regards

Sure. Everything you’re saying and have observed is correct. I got around this (seemingly arbitrary restriction) by simply passing a reference of my parent node as a parameter to the child node’s constructor. This DOES require that child nodes only get inserted as an action that you can trigger from the parent node. IE you can’t insert child nodes from the left side of the screen like normal. Otherwise you don’t have an active reference to the parent.

So basically something like:

onAddNewChildNodeButtonClicked() {
  TreeNode root = programModel.getRootTreeNode(this);
  createNewChildNode(root)
}

Then in your constructor for the new child node, you can just assigned the parameter to a TreeNode (I called it parent). This lets you do things like “parent.[functionsDefinedOnTheParentNode]” By doing this, you can insert sibling nodes by calling “createChildNode()” of the parent node THROUGH the child node.

1 Like

Hello Eric,

Thanks for your answer and apologies for my late response.

I have tried to apply your answer but I haven’t succeeded, I am having problem with the createNewChildNode(root). Let me explain my problem: For creating a new URCap node, you need to use the following function:

final ProgramNodeFactory nodeFactory = programModel.getProgramNodeFactory();
nodeFactory.createURCapProgramNode(NodeService.class);

The “createURCapProgramNode” functions needs to receive a generic Class (not an instance of that class) such as the following:

Class<? extends URCapProgramNodeService> urcapProgramNodeService

Being that the case and not being able to initialize the Service (to pass the TreeNode parameter in there), I can’t figure out how to pass that parameter into the node Service class before passing it to the “createURCapProgramNode” function. Does that make sense?

The only thing I could think of is to use the “ProgramNodeVisitor” and an API to pass the parent TreeNode through it, after the ChildNode has been created by the “createURCapProgramNode” function.

Could you be so kind to tell me if you could figure out a way of passing that parameter to the Child Node in any other way? I am now curious after diving into various different solutions that didn’t quite work for me!

Thanks again!

Ah. Yeah. My bad. I looked back at my code and you’re right, you don’t pass it as a parameter. You access it through a custom API and just assign the property that way. You don’t need to use the programNodeVisitor though.

root = programModel.getRootTreeNode(this);
final URCapProgramNode programNode = programModel.getProgramNodeFactory().createURCapProgramNode(myChildNode.class);
((URCapProgramNode) root.locateDescendantTreeNode(programNode).getProgramNode()).getAs(myCustomAPI.class).setParent(root);

As long as the child node Implements the myCustomAPI.class and you define the “setParent()” method to take as an input a URCAPprogramNode, you can then assign the node to that class’s parent variable.

2 Likes

Thanks! That’s solved then! I didn’t ever see that you could get the ProgramNode from the creation method, makes so much sense!

Thanks again Eric.

Hi @eric.feldmann,

This approach works for when the user creates a child node when he presses the button.
But what about child nodes that were added when the program is loaded?
These nodes are created by PolyScope itself, so you cannot pass a parent parameter.

The only thing that I can think of, is to program a sleeper thread that checks when the child nodes have been added, when program is loaded. Once the nodes have been added, you can use the

.getAs(myCustomAPI.class).setParent(root);

But then again, there might be synchronization difficulties.
Or have you found another solution for this?

Also, why do you do:

((URCapProgramNode) root.locateDescendantTreeNode(programNode).getProgramNode()).getAs(myCustomAPI.class).setParent(root);

and not simply

programNode.getAs(myCustomAPI.class).setParent(root);

Kind regards
Dieter

You are running into exactly the same problem I had. In fact, at the time the program loads, if you call something like “Print myParentNode.getChildren.count()” you will see an output of 0. The parent loads before the child and has no knowledge of them!

I came to the same conclusion you did and simply put a thread in each parent that waits until it sees that it has children and then assigns itself to them via the setParent() method. I had the same reservations as you as far as synchronization, but in my experience it’s been pretty solid.

As for why I did that long-winded way of assigning the parent…No idea. Probably I copy/pasted that from somewhere else in my code where it was actually required and just didn’t fix it.