How to delete a specific urcap node

Hello! I can’t figure out how to delete a specific urcap node using the button on this node

I’m trying to make an analog of a button from a standard waypoint tab

image

Take a peek at the TreeNode data type. Each node can be accessed as a TreeNode, which has a removeChild() method. I can’t say I’ve seen that button you’re referring to. I have only worked with the e-series, so maybe that’s a CB? I’m not sure what it’s functionality is. If you can delete the node from itself, you will likely have to do a fair bit of additional work, as you will need to create a custom interface so you can access different contributions from within others in order to call something like “parent.removeChild(activeTreeNode).”

Essentially you call a function from a different contribution (in this case it would be the Move node) and pass it a TreeNode from the active contribution (the waypoint node) in order to delete itself. It is, unfortunately, not as trivial as you would think.

Hi! Thanks for the answer! In the course of work, I came across the fact that the getChildren() function gives a different result every time it is called) Perhaps you know why this can happen?

Yeah, dealing with the TreeNode structure is pretty strange. Lets pretend the node you’re calling getChildren() on is called “root.” Basically, any time you’re dealing with root, put this line first:

root = programModel.getRootTreeNode(exampleContribution.this);

Then do something like root.getChildren(). For some reason the exact reference changes, but calling this every time before using it seemed to fix it for me. It’s a solution I’d found posted somewhere else here on the forum as well.

Likewise, the exact ID of the children might change too, if I remember correctly. For this you might have to get creative about how you identify each child. You could use their indexed position of the array returned from getChildren(), or add a custom type of something like NodeType and check for this if you’re populating the tree with custom UR Cap nodes. Not knowing your exact use case, I can’t get much more specific than that.

Hi!

I am currently working on this and i face faced a little issue: i have a main custom node and as a child i want to insert a customNode1. I have successufully added this customNode1 as a consequence of enable of a checkbox. Now my goal is to remove this customNode1 as i disable the checkbox.

I have created my customNode1 as ProgramNode since i need to insert it inside a .insertChildAfter() which only supports promanNodes and not casting. Unfortunately the removeNode() works only with TreeNodes and not with ProgramNodes.

Unfortunately i could not find a solution to my issue

has someone faced this issue?

Can you post a screenshot of your Polyscope so I can see the tree structure you have going on? Yes there’s a way to do what you’re asking, I just want to make sure I understand what you want first.

I’m also assuming the checkbox you’re using is on the parent node?

Hi!

As you can see, on the right i have a checkbox: by pressing the checkbox i am able to insert the green Instructions

Here i have two problems:

  • As you can see, once i have pressed this checkbox, the program adds twice my instruction and this behavior goes on increasingly as i add other custom main program.

  • As I press a second time on y checkbox, i want to be able to remove the green instruction. here i have uploaded a snippet of my code that does not work (i have seen that this instruction works only if i give him as input a treeNode. In this case i am using a programNode since the .insertChildAfter used to set the green instruction works only with a programNode as second argument. I have tried to use a cast in order to cast a ProgramNode to a TreeNode but this does not work

	
	public void removeNodes() {
		ProgramModel programModel = apiProvider.getProgramAPI().getProgramModel();
		final TreeNode rootTreeNode = programModel.getRootTreeNode(this);
		undoRedoManager.recordChanges(new UndoableChanges(){
			@Override
		
		public void executeChanges() {
			try {
				rootTreeNode.removeChild((TreeNode) Node);
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			}
		});
	}

Do you have any ideas about this behavior?

If you are wanting what I think you want, can you use the “locateDescendantTreeNode()” method on your parent node? It takes a programNode as a parameter and returns it as a TreeNode.

So basically, replace (TreeNode) Node in your code above with

rootTreeNode.removeChild(rootTreeNode.locateDescendantTreeNode(Node))

Good morning.

Thank you for your help!
in my set-up i have declared at the beginning of my contribution the following:

private ProgramNode StitchNode;

I have tried doing the proposed substitution and reading some api but i keep getting the following error on the locateDescendantTreeNode method:

The method locateDescendantTreeNode(ProgramNode) is undefined for the type TreeNode

i can’t figure this out since the stitchNode is a programNode and it is the only parameter that i pass to this function.

In addition to this, as you can see, the rootTreeNode is declared as TreeNode and the locateDescendantTreeNode is a property of treeNodes.

has this happend to you too?

I’m just kinda looking through some of my code, and it looks like the type I’m using is actually “URCapProgramNode” instead of just ProgramNode. Maybe try that?

I have just tired your suggestion!

Unfortunately it did not work. I assume that the displayed errore refers to the “treeNode” being “rootTreeNode” since now my error has become

The method locateDescendantTreeNode(URCapProgramNode) is undefined for the type TreeNode

due to the fact that i have changed the type of my custom node from ProgramNode to URCapProgramNode.

the quick-fix suggest to add a cast to rootTreeNode but this does not make sense in my mind since the locateDescendand works with treeNodes and rootTreeNode is a treeNode.

i have tried various casting types but this does not work

OK I agree with your assessment. Last thing I can think of then is that there are technically 2 TreeNode data types.

import javax.swing.tree.TreeNode;

and

import com.ur.urcap.api.domain.program.structure.TreeNode;

Can you verify you have imported the 2nd option here, the one that includes urcap.api?

Hi!

I have just checked and the library that i have installed is

import com.ur.urcap.api.domain.program.structure.TreeNode;

so it looks like it is the correct one. Could this be a problem of the compiler? i am using Eclipse

Version: 2020-03 (4.15.0)
Build id: 20200313-1211

with

openjdk version "1.8.0_292"
OpenJDK Runtime Environment (build 1.8.0_292-8u292-b10-0ubuntu1~16.04.1-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)

Weeeeeellllll Now I’m stumped. Maybe it’s something to do with the compiler? I’m using Eclipse as well, same version as you…

Same JDK version too I think, 1.8. What version of the URCap API are you using? I’m using 1.10 for reference.

i am using sdk-1.13.0 and i am woking with the following simulato`

ursim-5.11.0.108249

EDIT: just opened the pom.xml file and found this

com.ur.urcap.api*;version="[1.7.0,2.0.0)", * 

could this be the problem in your mind? how can i perform an update of the api without causing troubles?

OK so I went to the API manual here: https://plus.universal-robots.com/urcap-basics/api-reference-docs/?v=1.7.0
and checked version 1.7, since that’s what you found you’re running. There is no locateDescendant method under TreeNode.

If you switch it to the 1.10 version of the API, it shows this method exists. Not exactly sure which version this got added in, but it sounds like this is the answer as to why you’re getting this error.

I’m a little out of my element when it comes to Maven and the pom file. I’ve mostly managed by just poking around at it until it works, but here’s what I have to use API ver 1.10, placed into the dependecies section:

<dependency>
  <groupId>com.ur.urcap</groupId>
  <artifactId>api</artifactId>
  <version>1.10.0</version>
  <scope>provided</scope>
</dependency>

I guess my advice would be to (of course) backup your code to git or wherever you’re storing it, then try changing the API version. The “without causing troubles” part is where I can’t really help much haha. I cause plenty of troubles for myself all the time.

Since i am not familiar with Maven, the only approach i had in my mind was to brutforce-fully change the pom file from 1.7.0 to 1.10.0 :joy:

I am very good in creating troubles in a almost-working code myself too haha

Now i will try and let you know if something happens

UPDATE: i have updated the api by just changing the name in the dependency section.
Unfortunately, in addition to this, i had to implement some workaround due to the following facts:

  • from api 1.7.0 to 1.13.0, you should add the compatibility flags that were not required or needed in api 1.7.0
	<dependency>
			<groupId>com.ur.urcap</groupId>
			<artifactId>api</artifactId>
			<version>1.13.0</version>
			<scope>provided</scope>
		</dependency>

  • i have changed the configuration section in the pom file as it follows
<configuration>
					<instructions>
						<!--********** DO NOT MODIFY THE ENTRIES OF THIS SECTION **********-->
						<Bundle-Category>URCap</Bundle-Category>
						<Bundle-Activator>com.StudioRatio.WeldURCap.impl.Activator</Bundle-Activator>
						<Bundle-Vendor>${urcap.vendor}</Bundle-Vendor>
						<Bundle-ContactAddress>${urcap.contactAddress}</Bundle-ContactAddress>
						<Bundle-Copyright>${urcap.copyright}</Bundle-Copyright>
						<Bundle-LicenseType>${urcap.licenseType}</Bundle-LicenseType>
						<Bundle-Description>${urcap.description}</Bundle-Description>
						<URCapCompatibility-CB3>${urcap.compatibility.CB3}</URCapCompatibility-CB3>
						<URCapCompatibility-eSeries>${urcap.compatibility.eSeries}</URCapCompatibility-eSeries>
						<!--***************************************************************-->
						<Import-Package>
							com.ur.urcap.api*;
							*
						</Import-Package>
					</instructions>
				</configuration>

This worked for me for the API update. Regarding the removeNode, i still have some problems: the api recognises the locate structure but it still does not remove the custom child.

it says that the program is unable to retrieve the TreeNode

com.ur.urcap.api.domain.program.structure.ProgramNodeNotInSubTreeException: TreeNode not found. Program node not in the tree.

Did you implement an interface to the child node in order to achieve this goal?

EDIT: with some workaround, it finally worked.

thank you for your help

Here i have added a new post about the issue that i have with the checkbox inside another checkbox