Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 属性中的引用在两个JTree中都会更改_Java_Swing_Jtree - Fatal编程技术网

Java 属性中的引用在两个JTree中都会更改

Java 属性中的引用在两个JTree中都会更改,java,swing,jtree,Java,Swing,Jtree,首先,我很抱歉我的英语不好,如果有什么不可理解的,请告诉我 我有两棵树。显然,每棵树都有相同的信息。其中唯一更改的是包含每个节点的属性的名称 乙二醇 JTree1有一个ID和一个ParentID。这些属性具有名称和值。姓名:ID_Tree1。值:TESTID1//Name:ParentID\u Tree1。值:TESTPID1 在JTree2中具有相同的值​​与JTree1一样,但名称不同 有一个时刻,我将一个节点从JTree1传输到JTree2来创建它。传输/创建是正确的,但当我读取节点时,它

首先,我很抱歉我的英语不好,如果有什么不可理解的,请告诉我

我有两棵树。显然,每棵树都有相同的信息。其中唯一更改的是包含每个节点的属性的名称

乙二醇 JTree1有一个ID和一个ParentID。这些属性具有名称和值。姓名:ID_Tree1。值:TESTID1//Name:ParentID\u Tree1。值:TESTPID1 在JTree2中具有相同的值​​与JTree1一样,但名称不同

有一个时刻,我将一个节点从JTree1传输到JTree2来创建它。传输/创建是正确的,但当我读取节点时,它具有不同的属性名称体系结构(Jtree1 arch.),无法读取,因为需要使用JTree2体系结构。我使用函数changeAttributesNamesFromDOORSToTC()来解决这个问题,因为它只是将名称更改为正确的名称,并且对于JTree2来说是可以理解的

真正的问题是:该函数在JTree2的节点中进行更改,但同时更改了JTree1中相同节点的值名称。我认为它是参考数据而不是作业

我怎样才能解决这个问题

谢谢

JTree treeDOORSCode; //JTree1
JTree treeTCCode;  //JTree2
主要代码:

//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);
用于更改属性名称值的函数:

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;
        }

    }
}

如果需要更多信息,请告诉我

java中的对象分配实际上是一个引用副本

NodeClass newActualNode=actualNode

这一行并不意味着“将object actualNode的值放入object newActualNode”,因为实际上变量actualNode不是NodeClass的实例,而是对NodeClass实例的引用。因此,当您执行
NodeClass newActualNode=actualNode您正在复制引用,现在两个变量有效地指向同一个实例

然后,当您更改其中一个中的属性名称时,“另一个”也会更改,因为没有其他属性,所以它在内存中的位置相同

现在,您需要做的是使用所需的值创建一个新的NodeClass实例。有几种方法可以做到这一点,我很难知道哪种方法更合适,因为我不知道内部结构,但最终你需要:

  • 为newActualNode变量创建新的NodeClass实例
  • 将actualNode的值(字段)放入newActualNode
  • 在newActualNode中指定所需的属性名称
所以,它可能是这样的:

NodeClass newActualNode = new NodeClass(actualNode);  //copy constructor  NodeClass(NodeClass anotherNode);
newActualNode.changeAttributesNamesFromDOORSToTC(); //assuming the constructor doesn't put them right
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;
}
NodeClass newNode = new NodeClass();
newNode = insertNodeInfo(actualNode);
newNode.changeAttributesNamesFromDOORSToTC();
DefaultMutableTreeNode newSelectedTreeNode = new DefaultMutableTreeNode();
newSelectedTreeNode.setUserObject(newNode);
treeModelTC.insertNodeInto(newSelectedTreeNode, parent, 0);
或者,您可以在NodeClass构造函数中使用一个标志来指示需要哪种类型的属性名

复制构造函数应该如下所示:

NodeClass newActualNode = new NodeClass(actualNode);  //copy constructor  NodeClass(NodeClass anotherNode);
newActualNode.changeAttributesNamesFromDOORSToTC(); //assuming the constructor doesn't put them right
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;
}
NodeClass newNode = new NodeClass();
newNode = insertNodeInfo(actualNode);
newNode.changeAttributesNamesFromDOORSToTC();
DefaultMutableTreeNode newSelectedTreeNode = new DefaultMutableTreeNode();
newSelectedTreeNode.setUserObject(newNode);
treeModelTC.insertNodeInto(newSelectedTreeNode, parent, 0);
你可以对这段代码略知一二,有几种方法可以做到这一点,如果有的话,差别是很微妙的。重要的是,您需要为另一棵树创建另一个实例

编辑

如果这不起作用,我的猜测是,要么您需要执行
newSelectedTreeNode.setUserObject(newNode)在插入之前,如下所示:

NodeClass newActualNode = new NodeClass(actualNode);  //copy constructor  NodeClass(NodeClass anotherNode);
newActualNode.changeAttributesNamesFromDOORSToTC(); //assuming the constructor doesn't put them right
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;
}
NodeClass newNode = new NodeClass();
newNode = insertNodeInfo(actualNode);
newNode.changeAttributesNamesFromDOORSToTC();
DefaultMutableTreeNode newSelectedTreeNode = new DefaultMutableTreeNode();
newSelectedTreeNode.setUserObject(newNode);
treeModelTC.insertNodeInto(newSelectedTreeNode, parent, 0);

或者
parent
计算不正确,尤其是您得到的是TreeDorCode的父节点,而不是treeTCCode的父节点。

为了更好地帮助您,请尽早发布一个简短、可运行、可编译的上午左右问题,并为TreeModel提供硬编码值,您可以使用建议的任何一种方法。谢谢您的回答,但它根本不正确。你明白我的意思和需要。我需要一种克隆DefaultMutableTreeNode的方法,但我不希望它指向cloner。这是一个愚蠢的问题,但我开始发疯了……你能重新表述一下“我需要一种方法来克隆DefaultMutableTreeNode,但我不希望它指向cloner”?我想创建相同的DefaultMutableTreeNode(具有相同的属性和属性),但如果我想更改一个属性,我不想将更改复制到主节点。取消两个DefaultmutableTreeNode对象的链接。你明白吗?问题是“创造相同的”是什么意思。有两种选择。1) 您可以创建节点的副本(克隆),最初有两个具有相同值的实例,因此当您修改其中一个时,另一个不会被修改。2) 您可以有两个对同一实例的引用,每个树一个引用。在第二种情况下(你试图在你的代码中做的),不可能“取消链接”它们,它们没有链接,它们是同一个对象,完全相同,你不能取消一个对象与它本身的链接,它只是没有意义。如果你想有两个可能不同值的节点,你需要两个实例。我创建了一个新的不同的NodeClass实例,但是当我给“父对象”的值使其具有相同的值时,它仍然在两个对象中共享值,我会发疯的,因为我不知道解决这个问题的方法。。