在JTree中分享父母之间的孩子

时间:2010-10-03 11:21:31

标签: java swing jtree

我有一个自定义的DefaultMutableTreeNode类,旨在支持许多类型的数据属性之间的健壮连接(对我来说,这些属性可以是字符串,用户定义的标记或时间戳)。

在汇总数据时,我想向用户提供我们目前为止所见的存储数据的实时预览。出于效率原因,我只想保留一个特定属性的副本,这个属性可能与其他属性有很多连接。

示例:用户定义的标记“LOL”出现在五个不同的时间(由TimeStamps表示)。所以我的JTree(显示此信息的类)将有五个父节点(每次发生标记时都有一个节点)。那些父节点应该为“LOL”标签定义的DefaultMutableTreeNode的ALL SHARE ONE INSTANCE。

不幸的是,使用add(MutableTreeNode newChild)从当前父节点的WHATEVER中删除newChild。这真的太糟糕了,因为我希望所有父节点都有THE SAME子节点。

这是一张做错的图片(柯蒂斯是作者,他应该出现在所有的节目中)

alt text

如何在Java中轻松完成此任务?

更新

我一直在查看DefaultMutableTreeNode.add()的代码......我很惊讶它的工作方式(评论是我的):

public void add(MutableTreeNode child)
{
    if (! allowsChildren)
        throw new IllegalStateException();

    if (child == null)
        throw new IllegalArgumentException();

    if (isNodeAncestor(child))
        throw new IllegalArgumentException("Cannot add ancestor node.");

    // one of these two lines contains the magic that prevents a single "pointer" from being
    // a child within MANY DefaultMutableTreeNode Vector<MutableTreeNode> children arrays...
    children.add(child); // just adds a pointer to the child to the Vector array?
    child.setParent(this); // this just sets the parent for this particular instance
}

3 个答案:

答案 0 :(得分:3)

如果您希望轻松,您应该放弃共享实际的TreeNodes本身。整个模型建立在每个节点只有一个父节点的假设之上。我将重点放在设计自定义TreeNode上,以便多个节点都可以从同一个地方读取数据,从而保持它们的同步。

答案 1 :(得分:2)

我不确定它是否符合 easy 的条件,但您可以通过实施TreeModel来查看Creating a Data Model,“DefaultMutableTreeNode”不要求here代表节点1}}对象,甚至那些节点都实现了TreeNode接口。“除了教程示例之外,还有一个引用{{3}}的文件系统示例。

答案 2 :(得分:0)

不幸的是,我认为答案是肯定的。为了做你正在谈论的事情,你需要让DefaultMutableTreeNode的内部userObject成为某个String的指针,以便所有相应的DefaultMutableTreeNode' s可以指向并共享相同的String对象。

但是,您不能使用任何此类DefaultMutableTreeNode.setUserObject()指针调用String,因为Java在C或C ++的级别上没有这样的概念。查看this outstanding blog article关于Java中传递值和传递引用的令人困惑的误解。

更新:在答案空间中回复您的评论,以便我可以提供代码示例。是的,Java确实在内部使用指针......有时您必须克隆对象引用以避免对原始内容进行不必要的更改。但是,长话短说(阅读上面的博客文章),这不是其中之一。

public static void main(String[] args) {

    // This HashMap is a simplification of your hypothetical collection of values,
    // shared by all DefaultMutableTreeNode's
    HashMap<String, String> masterObjectCollection = new HashMap<String, String>();
    masterObjectCollection.put("testString", "The original string");

    // Here's a simplification of some other method elsewhere making changes to 
    // an object in the master collection
    modifyString(masterObjectCollection.get("testString"));

    // You're still going to see the original String printed.  When you called 
    // that method, a reference to you object was passed by value... the ultimate
    // result being that the original object in you master collection does 
    // not get changed based on what happens in that other method.
    System.out.println(masterObjectCollection.get("testString"));
}

private static void modifyString(String theString) {
    theString += "... with its value modified";
}

您可能需要查看the JIDE Swing extensions,其中一些组件是商业广告,而其他组件是开源的,免费的,如啤酒。您可能会发现某种组件更接近于完成您想要的任务。