References in properties change in both JTree - java

Before all I'm sorry for my bad english and tell me if anything is not understandable.
I have 2 Jtree. Each tree apparently has the same information. The only thing that changes in them are the names of the properties that has each node.
Eg
JTree1 has an ID and a ParentID. These properties have as a name and value. Name: ID_Tree1. Value: TESTID1 / / Name: ParentID_Tree1. Value: TESTPID1
In JTree2 has the same values ​​as in the JTree1 but the names are different.
There is a moment in which I transfer a node from JTree1 to JTree2 to create it. The transfer/creation is correct but when I read the nodes, it has a different property name architecture(Jtree1 arch.) and can't be read because need to have the JTree2 architecture. I have the function changeAttributesNamesFromDOORSToTC() to solve the problem because it just change the name to the correct name and understandable for JTree2
The real problem: The function make the change in the node of JTree2 but at the same time it change the values name of the same node in JTree1. It makes reference data instead of assignments I think.
How can I solve this!?
Thanks!
JTree treeDOORSCode; //JTree1
JTree treeTCCode; //JTree2
Main Code:
//ACTUAL NODE
DefaultMutableTreeNode selectedTreeNode = (DefaultMutableTreeNode) CurrentSelection.getLastPathComponent();
NodeClass actualNode = (NodeClass)selectedTreeNode.getUserObject();
//ACTUAL PARENT NODE
DefaultMutableTreeNode selectedParentTreeNode = (DefaultMutableTreeNode) selectedTreeNode.getParent();
NodeClass parentNode = (NodeClass) selectedParentTreeNode.getUserObject();
DefaultMutableTreeNode parent = findNode(NodeClass.getNodeParentIdentifierAttrDOORS(parentNode), treeTCCode);
//NEW NODE
DefaultMutableTreeNode newSelectedTreeNode = selectedTreeNode;
//NEW PART
NodeClass newNode = new NodeClass();
newNode = insertNodeInfo(actualNode);
//Create the Model and insert the node
DefaultTreeModel treeModelTC = (DefaultTreeModel)treeTCCode.getModel();
treeModelTC.insertNodeInto(newSelectedTreeNode, parent, 0);
//NEW PART
newNode .changeAttributesNamesFromDOORSToTC();
newSelectedTreeNode.setUserObject(newNode);
Function which change the attr Name values:
public void changeAttributesNamesFromDOORSToTC(){
for (int i = 0; i < this.attributes.size(); i++) {
if (this.attributes.get(i).attributeName.equals(DOORS_ID)){
if (this.tag.equals(TYPE_NAME_CASE)){
this.attributes.get(i).attributeName = TC_IDCASE;
}
if (this.tag.equals(TYPE_NAME_FOLDER)){
this.attributes.get(i).attributeName = TC_IDFOLDER;
}
if (this.tag.equals(TYPE_NAME_FEATURE)){
this.attributes.get(i).attributeName = TC_IDFEATURE;
}
}
if (this.attributes.get(i).attributeName.equals(DOORS_PARENTID)){
this.attributes.get(i).attributeName = TC_PARENTID;
}
if (this.attributes.get(i).attributeName.equals(DOORS_SRS)){
this.attributes.get(i).attributeName = TC_SRS;
}
}
}
Attributes Class:
NodeAttributesClass (String attributeName, String attributeValue)
{
this.attributeName = attributeName;
this.attributeValue = attributeValue;
}
Let me know if need more info!

Object assignment in java is actually a reference copy.
NodeClass newActualNode = actualNode;
That line doesn't mean "put the values of object actualNode into object newActualNode", because actually the variable actualNode is not an instance of NodeClass, but a reference to an instance of NodeClass. So when you do NodeClass newActualNode = actualNode; you are copying the reference and now both variables effectively point to the same instance.
Then when you change the attribute names in one "the other" also changes, because there is no such other, it's the same place in memory.
Now, what you need to do is to create a new instance of NodeClass with the values you want. There are several ways to do so, it's hard for me to know wich one is more suitable as I don't know the internal structures, but in the end you need to:
Create a new NodeClass instance for the newActualNode variable
Put the values (fields) of actualNode into the newActualNode
Assign the attribute names that you want in newActualNode
So, it could be something like this:
NodeClass newActualNode = new NodeClass(actualNode); //copy constructor NodeClass(NodeClass anotherNode);
newActualNode.changeAttributesNamesFromDOORSToTC(); //assuming the constructor doesn't put them right
or you could use a flag in the NodeClass construtors to indicate what kind of attribute names you want.
and the copy constructor should look like this:
public NodeClass(NodeClass anotherNode)
{
this(anotherNode.someFields); //call to your "normal" constructor, with whatever params you need
//copy the values into the new instance this, if you didn't do it in the above line
this.field1 = anotherNode.field1;
this.field2 = anotherNode.field2;
//...
this.fieldn = anotherNode.fieldn;
}
You can take this code with a grain of salt, there are several ways to do it, the differences are subtle if any. The important thing is that you need to have another instance for the other tree.
EDIT
If that doesn't work my guess would be, that either you need to do newSelectedTreeNode.setUserObject(newNode); before the insert, like this:
NodeClass newNode = new NodeClass();
newNode = insertNodeInfo(actualNode);
newNode.changeAttributesNamesFromDOORSToTC();
DefaultMutableTreeNode newSelectedTreeNode = new DefaultMutableTreeNode();
newSelectedTreeNode.setUserObject(newNode);
treeModelTC.insertNodeInto(newSelectedTreeNode, parent, 0);
or that parent is not properly calculated, in particular that you are getting the parent node of the treeDOORSCode, and not the one of the treeTCCode.

Related

Passing parameter that does not exist to method [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am fairly new to Java proramming, as I have already stated in the title I want to pass some parameters that could or could not exist as instances of a class. If it does not exist, I want to create it. My code so far:
public class TestClass {
public static void main(String[] args) {
Person Ted = new Person();
Person Jack = new Person();
Item it = new Item(Ted);
Item itSec = new Item (Pierce); //Person Pierce doesn't exist => should be created
}
}
public class Person {
public Person(){
//some code
}
}
public class Item {
public Item(Person name){
if(!(name instanceof Person)){
Person name = new Person(); //create that missing instance
}
else{
//some code
}
void getItem(Person name){
System.out.println(name);
}
}
You misunderstand some things.
You can't use an identifier before it's been declared. The following is not correct in your code:
Item itSec = new Item (Pierce);
That's because you didn't declare Pierce before this line. You don't have to create an instance of the class, but you need a valid identifier. You should have declared it before this way:
Person Pierce;
At this moment the identifier, or the reference, is empty, so to say, or it is equal null. All object references which are not local are initiated this way, or they are equal false or 0, whichever is correct for their type. The result is the same as if you declared explicitly:
Person Pierce = null;
But let's move on. Say the reference has been declared. (Btw, Java uses camelCaseNotation for variables, so pierce would be correct.) Let's say we're at a point when Pierce is null or refers to some object, we don't know. Now we call this:
Item itSec = new Item (Pierce);
new Item(Pierce) calls the constructor public Item(Person name){...} in the class Item, which you should know. But now, in that constructor there's the line:
if(!(name instanceof Person)){
which you misuse. What this line is checking is not if the variable name equals null or an existing object, but variable type of name is a subtype of Person. Which will always return true in this place, as the function heading public Item(Person name){...} says this: the function is public, is a constructor, and the argument is of type Person (so Person or a subtype).
What you want to say here is this:
public Item(Person name){
if(name==null)){ //if the reference is empty
this.name = new Person(); //I'll explain this below
}
else{
this.name = name; //otherwise the local "name" will stay null
}
}
I used this.name and it was a jump ahead. Why? In your code that is Person name = ..., which is not correct as that name wouldn't last once the constructor's finished. You need a field in the Item class object, which will hold this value. So the Item class might be defined this way:
public class Item {
Person name;
//...
}
And now the field name holds the value assigned in the line:
this.name = new Person();
You need to use this to disambiguate which name you means. One is the Item class field, the other one is Person name the constructor parameter.
Now, we go back to the main function. If you want the variable Pierce to reference the newly created Person, this still needs to be done. The assignment can take place here, but first you'd have to create a function in the class Item that returns the value of its field name. So:
getName() {
return name;
}
And now call it from the main function:
Pierce = itSec.getName();
That's it. Finally, this function doesn't make sense:
void getItem(Person name){
System.out.println(name);
}
}
It doesn't get any Item. It only prints what you pass to it. And this doesn't mean that if you call it with getItem(Pierce), you will see "Pierce" on the screen. It will call the toString function in the object Pierce denotes, and as it is, you will get a standard object identifier. But if you define a function:
void printItem() {
System.out.println(name);
}
Then you can call it this way. For an existing object itSec:
itSec.printItem();
As for a getter function, it should return what you ask for, but that's another story.
What do you expect without instancing?
Person Pierce = new Person();
Item itSec = new Item (Pierce);
You cannot use a variable that does not exist...
Item itSec = new Item (Pierce);
The snippet above will never work because Pierce is undefined.
The code:
if(!(name instanceof Person)){
Person name = new Person(); //create that missing instance
}
Does not really make any sense, because that is the same as calling
Person Ted = new Person();
Person Jack = new Person();
Wherein the Person instance does not actually contain any data (unless you have some magic going on when instantiating the Person!)
I assume what you really want to pass is not an object whose variable is the name of a person, but rather a Person object that contains the name of the person.
If so, your code should be like this:
Person p1 = new Person("Ted");
Person p2 = new Person("Jack");
If you really want to do some instantiation if something does not exist, you might be able to do something like this:
Item(String personName) {
if(isExisting(personName)) {
getPerson(personName);
} else {
Person p = new Person(personName);
}
boolean isExisting(String personName) {
// Check if person exists somewhere
}
Person getPerson(String personName) {
// Retrieve the Person instance with the same person name.
}
if(!(name instanceof Person)){
Person name = new Person();
}
is meaning less because 'name' is always object is instance of person in this situation..
Item itSec = new Item (Pierce);
Pierce is not an object.. We can pass only Person object to constructor of Item class.. There is no any method to create an object of any class by just passing unkown variable..
Item itSec = new Item (Pierce); //Person Pierce doesn't exist => should be created
If it does not exist, I want to create it.
There's no "if" about it. The code never declared that variable, so it will never exist. (And never compile in its current state. Surely your Java compiler is telling you this.) Given that it always needs to be created, just create it:
Person Pierce = new Person();
Item itSec = new Item(Pierce);
Edit: Based on ongoing comments, it sounds like you want to have something more like a Map. Consider an example:
Map<String,Person> people = new HashMap<String,Person>();
people.put("Pierce", new Person());
The Map would basically be a collection of key/value pairs where the name is the key and the Person is the value. You can dynamically add/edit/remove elements to the collection as you see fit.
Then to use it, you'd call another operation on the map:
Item itSec = new Item(people.get("Pierce"));
You could use various operations to check if a value exists in the collection, add it, etc. You might even extend the class to add your own operations which create one if it doesn't exist when trying to get it.
Java won't dynamically create variables for you if a variable doesn't exist, but operations on a Map (or potentially other similar structures) can check if an element exists, add it, remove it, etc.

Generate Nested List (Tree) from Flat List

I have a plain class named MenuModel in Java (it's for nested menu as the name suggests) like this:
public class MenuModel {
public String id;
public String parentId = null;
public String title;
public MenuModel parent = null;
public List<MenuModel> children = new ArrayList<MenuModel>();
}
My code fetch data from web API and generate a flat list of MenuModel with only id, parentId, and title fields filled with data. However, I need each MenuModel to have references to its parent and (optionally) children for further uses.
I have thought of a method which make a nested loop to pair the models each other and check if they are parent and child. But I think that costs too much (n^2 or n^3 complexity, the itemset is large) and can only fill the parent field.
What is the best way to achieve this in Java? To summarize:
Input: ArrayList<MenuModel> source
Output: ArrayList<MenuModel> result containing all MenuModel from source which has parentId = null (that means, it's top level menu), with each MenuModel has children fields filled with reference to their respective children MenuModel. Additionally, each children have reference to their parents.
Thanks in advance
Go through all the records and add them to a HashMap<String, MenuModel> (the key being the ID).
Then, for each record record:
Look up the parent ID in the above map to get parent.
Assign the parent to this record's parent variable - record.parent = parent.
Add this record to the parent's list of children - parent.children.add(record).
Running time: Expected O(n).

Java - Script let to model class with loop

I'm trying to remove some scriptlets from my jsp and almost have the same identical
code but my model class is somehow throwing an error. The main difference is the JcrUtils.getChildNodes() command which essentially calls Node.getNodes() on a node and returns an Iterable instance. I've been racking my brain for hours on this and can't figure it out:
JSP:
final String HEADER = "header"
final Node headerNode = currentNode.hasNode(HEADER)
NodeIterator childLinks = headerNode.getNodes();
while ( childLinks.hasNext() ) {
Node link = (Node) childLinks.next();
headerNode = link.getProperty("headerTitle");
//do something with more child node properties
}
MODEL CLASS:
final String HEADER = "header"
final Node headerNode = currentNode.hasNode(HEADER)
def headerNodeTitle = JcrUtils.getChildNodes(headerNode).find{ it.hasProperty("headerTitle") }
selectHeaderLabel = topicNode.getProperty("headerTitle").getString();
ERROR
No signature of method: static org.apache.jackrabbit.commons.JcrUtils.getChildNodes() is applicable for argument types: (java.lang.String) values: [true]
Based in the error message, the JcrUtils.getChildNodes(...) expects a String type parameter. Review this piece of code and also the code JcrUtils.getChildNodes(headerNode) that you invoke passing an object of Node type.

Java JPanel combobox that holds object types

So far from what I have seen combo boxes can only hold string and int types of values but this is what I am trying to achieve.
Class Node
{
//code here
}
Node a = new Node();
Node b = new Node();
//I am wondering if I can somehow achieve something like
Node item = comboBox.getSelectedItem();
So I want the combo box to hold items of type Node. The combo box will allow for a and b values but when selected they will register as Node objects. I am not sure that is even possible but just wondering. Thanks for input :)
Yes, JComboBox is able to contain any type of Object.
As of 1.7, you can also use the template definition to define the type contained.

How to get a specific JTree node given a string array

If I have a String[] such as { "root", "two", "1" } how can I get the DefaultMutableTreeNode from my JTree that is represented by this "path"?
For example if my JTree looks like this:
root
one
1
2
two
1 <-- I want this node
2
Assume all nodes are DefaultMutableTreeNodes.
First, you need to fetch the tree model with getModel() method. Once you have the model, it has the getRoot() method, to fetch the root of the tree. After that, you can follow with calls to getChild(Object parent, int index) and check if any of the children has the same name as the one provided in the String array. If you find such one, you can again call getChild(Object parent, int index), etc... until you arrive at the last String from the array. Then you have the corresponding tree node. You need to actually cast the tree nodes to DefaultMutableTreeNode, as the TreeModel uses Object as the tree elements (for pre-1.7 Java).

Categories

Resources