【问题标题】:Why isn't my JTree updating when the TreeModel adds new nodes?为什么当 TreeModel 添加新节点时我的 JTree 没有更新?
【发布时间】:2011-10-13 11:04:40
【问题描述】:

我正在使用DefaultTreeModel 填充DefaultMutableTreeNode 的覆盖,它支持可选地更改树中节点的显示字符串。如下面的代码所示,在我的表单中,我通过在单独的类中创建新节点然后通过我的主要数据类型的包装类将它们传递给新节点来填充树。该过程是创建一个新的覆盖DefaultMutableTreeNode,向其添加子节点(每个AccessPoint 由一个具有多个子节点的节点表示),然后将其存储以供以后在 UI 中使用。

我第一次以这种方式添加节点时,效果很好。使用以下代码添加的任何后续节点实际上都存储在DefaultTreeModel 中,但JTree 并未使用新节点进行更新。

为什么在添加第一个孩子后JTree 没有被填充?

private void populateAccessPointTreeModel(AccessPointDataWrapper wrapper) {
    //the pre-created DefaultMutableTreeNode subclass instance is
    // stored in the wrapper
    DefaultMutableTreeNode accessPointNode =
            wrapper.getAccessPointTreeNode();
    //this line updates the accessPointTree with the new node (I've looked at the
    // value in debug mode, and it does in fact add the node
    ((DefaultMutableTreeNode) accessPointTree.getRoot()).add(accessPointNode);
    //unrelated logic happens down here...
}

如有必要,我可以在其中包含创建节点的代码,但我认为这不是问题。

【问题讨论】:

  • 您是否尝试过重新绘制组件或其父组件?

标签: java swing jtree treemodel


【解决方案1】:

很可能您遇到了一些线程问题。您的 JTree 更新是某个线程,但 JTree 的重要副本,即在 Swing 事件调度线程 (EDT) 中显示的副本,对这些更改一无所知。

如果是这种情况,您必须使用以下命令更新 Swing EDT 中的 JTree:

SwingUtilities.invokeLater(new Runnable() {
  @Override public void run() { ... update jTree here }
});

我不知道 JTree...也许是您必须在 Swing EDT 中更新的 TreeModel。

【讨论】:

    【解决方案2】:

    问题是DefaultMutableTreeNode 没有通知DefaultTreeModel 其子代已更新。为此,您需要调用表模型中的适当方法(nodesChanged 或类似方法)或(最好)使用DefaultTreeModel.insertNodesInto 方法。

    DefaultTreeModel model = (DefaultTreeModel)accessPointTree.getModel();
    DefaultMutableTreeNode root = model.getRoot();
    model.insertNodeInto(accessPointNode, root, root.getChildCount());
    

    【讨论】:

    • +1,Swing 组件的更新应始终使用模型完成。
    • 这是有道理的。我之前一直在通过我保存在 UI 类中的 DefaultTreeModel 进行更新,我最终使用了 DefaultMutableTreeNode 上的 add,因为它更短。谢谢。
    • 我相信 root.getChildCount() 会在 insertNodeInto 上抛出越界异常(相信,我的意思是我从经验中知道)。 javax.swing.tree.DefaultMutableTreeNode.insert(DefaultMutableTreeNode.java:195) 处 java.util.Vector.insertElementAt(Vector.java:571) 处的线程“算法线程”中的异常 java.lang.ArrayIndexOutOfBoundsException: 1 > 0 .swing.tree.DefaultTreeModel.insertNodeInto(DefaultTreeModel.java:234)
    • 确保您使用的是实际计数,而不是 count+1 或其他任何值。 Vector.insertElementAt 允许 0..size 范围内的索引。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    相关资源
    最近更新 更多