【问题标题】:References in properties change in both JTree两个 JTree 中的属性引用都发生了变化
【发布时间】:2013-07-30 10:30:13
【问题描述】:

首先我很抱歉我的英语不好,如果有什么不明白的地方请告诉我。

我有 2 个 Jtree。每棵树显然都有相同的信息。它们中唯一发生变化的是具有每个节点的属性的名称。

例如 JTree1 有一个 ID 和一个 ParentID。这些属性具有名称和值。名称:ID_Tree1。值:TESTID1 //名称:ParentID_Tree1。值:TESTPID1 JTree2中的值与JTree1中的值相同,但名称不同。

有一次我将一个节点从 JTree1 转移到 JTree2 以创建它。传输/创建是正确的,但是当我读取节点时,它具有不同的属性名称架构(Jtree1 架构)并且无法读取,因为需要具有 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;
        }

    }
}

属性类:

NodeAttributesClass (String attributeName, String attributeValue)
{
    this.attributeName = attributeName;
    this.attributeValue = attributeValue;
}

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

【问题讨论】:

  • 为了获得更好的帮助,请尽快发布 SSCCE,简短、可运行、可编译,大约在上午问题,带有 TreeModel 的硬编码值,
  • 您可以使用here建议的任一方法。

标签: java swing jtree


【解决方案1】:

java中的对象赋值实际上是一个引用副本。

NodeClass newActualNode = actualNode;

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

那么当你改变一个中的属性名称时,“the other”也会改变,因为没有这样的other,它在内存中的同一个地方。

现在,您需要做的是使用您想要的值创建一个新的 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

或者你可以在 NodeClass 构造器中使用一个标志来指示你想要什么样的属性名称。

拷贝构造函数应该是这样的:

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

您可以对这段代码持保留态度,有几种方法可以做到这一点,如果有的话,差异是微妙的。重要的是您需要为另一棵树创建另一个实例。

编辑

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

NodeClass newNode = new NodeClass();
newNode = insertNodeInfo(actualNode);
newNode.changeAttributesNamesFromDOORSToTC();
DefaultMutableTreeNode newSelectedTreeNode = new DefaultMutableTreeNode();
newSelectedTreeNode.setUserObject(newNode);
treeModelTC.insertNodeInto(newSelectedTreeNode, parent, 0);

或者 parent 计算不正确,特别是您获取的是 treeDOORSCode 的父节点,而不是 treeTCCode 的父节点。

【讨论】:

  • 感谢您的回答,但它根本不正确。你明白我的意思和需要。我需要一种克隆 DefaultMutableTreeNode 的方法,但我不希望它指向克隆器。这是一个愚蠢的问题,但我开始变得疯狂......
  • 您能否改写“我需要一种方法来克隆 DefaultMutableTreeNode,但我不希望它指向克隆器”?
  • 我想创建相同的 DefaultMutableTreeNode(具有相同的属性和属性),但如果我想更改一个属性,我不希望将更改复制到主节点。取消链接两个 DefaultmutableTreeNode 对象。你明白吗?
  • 问题是“创建相同”的含义。有 2 个选项。 1)您可以创建节点的副本(克隆),最初有 2 个具有相同值的实例,因此当您修改一个时,另一个不会被修改。 2) 您可以对同一个实例有两个引用,每棵树都有一个引用。在第二个(您尝试在代码中执行的那个)中,不可能“取消链接”它们,它们没有链接,它们是同一个对象,完全相同,您不能将一个对象与其自身取消链接,它只是没有意义。如果您想拥有 2 个可能具有不同值的节点,则需要 2 个实例。
  • 我创建了一个新的不同的 NodeClass 实例,但是当我将“父对象”的值赋予相同的值时,它仍然共享两个对象中的值,我会变得疯狂,因为我不不知道解决这个问题的方法..
猜你喜欢
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-15
  • 1970-01-01
相关资源
最近更新 更多