3


我正在学习 JTrees 和 Java。
非常欢迎建设性的建议和反馈。

我想我缺少对 JTrees 的一些了解,经过 5 个小时的谷歌搜索和测试,我陷入了困境。我已经尽可能地简化了代码。

        public void actionPerformed(ActionEvent event) {
            MyNode selNode = (MyNode) m_tree.getLastSelectedPathComponent();
            if (selNode != null) {
                MyNode newNode = new MyNode("New Node");
                model.insertNodeInto(newNode, selNode,
                        selNode.getChildCount());
                MyNode[] nodes = model.getPathToRoot(newNode);
                TreePath path = new TreePath(nodes);
                m_tree.scrollPathToVisible(path);
                m_tree.setSelectionPath(path);
                // *******   The next line throws the exception shown below.  ****
                m_tree.startEditingAtPath(path);
            }


Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.plaf.basic.BasicTreeUI.startEditing(BasicTreeUI.java:2059)
at javax.swing.plaf.basic.BasicTreeUI.startEditingAtPath(BasicTreeUI.java:601)
at javax.swing.JTree.startEditingAtPath(JTree.java:2349)
at ItemCreator.ItemCreator$1.actionPerformed(ItemCreator.java:74)

代码 - 我的简单可变 JTree

1) 当向 JTree 添加新节点时,代码在线程“AWT-EventQueue-0”java.lang.NullPointerException 中抛出异常

2) 非常欢迎任何一般性的建设性反馈。

亲切的问候

4

1 回答 1

2

问题不在于 startEditingPath,而在于不正确的模型实现。基本上它无法通知其侦听器更改,因此 ui 没有机会更新其内部以包含添加的节点。

模型失败

  1. 不接受侦听器(addTreeModelListener 的空实现)
  2. 更改后甚至不尝试触发(插入,更新......)
  3. 不正确的 getPathToRoot 实现

这并非完全微不足道,而且 java doc 稍微(委婉地说)令人困惑——这就是为什么SwingX有一个经过良好测试的实用程序类TreeModelSupport来接管负担。它可以单独使用,也可以作为操作方法的蓝图。

在您的自定义模型中,一些相关更改(不完整,必须相应地修复其他修改方法,删除侦听器也必须如此):

// prepare fix issue 1: instantiate the notification support    
private TreeModelSupport support;

public ItemTreeModel(MyNode root) {
    this.root = root;
    support = new TreeModelSupport(this);
    // remove the following: a model never listens to itself
    // this.addTreeModelListener(new MyTreeModelListener());
}

// fix issue 1: accept listener
public void addTreeModelListener(TreeModelListener l) {
    support.addTreeModelListener(l);
}

// fix issue 2: notify the listeners on inserts
public void insertNodeInto(final MyNode newNode, final MyNode selNode,
        final int childCount) {
    selNode.add(childCount, newNode);
    newNode.setLocation(selNode);
    support.fireChildAdded(new TreePath(getPathToRoot(selNode)),
            childCount, newNode);
}

// fix issue 3: pathToRoot as needed in TreePath 
public MyNode[] getPathToRoot(MyNode node) {
    ArrayList<MyNode> itemArrayList = new ArrayList<MyNode>();
    // TODO - Add root node ?
    // yes, certainly - please read the java doc for TreePath
    while ((node != null)) { // && (node != root)) {
        itemArrayList.add(0, node);
        node = node.getLocation();
    }
    return itemArrayList
            .toArray(new MyNode[itemArrayList.size()]);
}
于 2012-11-15T10:53:05.130 回答