簡體   English   中英

重新分配JTree后,getLastSelectedPathComponent()返回null

[英]After re-assign the JTree,getLastSelectedPathComponent() returns null

我的JFrame中有一個JTree,並使用getLastSelectedPathComponent()修改選擇節點的值。 在我重新分配JTree之后,getLastSelectedPathComponent()返回null。 我重新分配JTree的代碼如下:

protected void refreshTree(JScrollPane jsptree) {
    DefaultMutableTreeNode rootNode;
    File rootSaveFile = new File(System.getProperty("user.dir") + "\\doc");
    if (rootSaveFile.exists()) {
        rootNode = new DefaultMutableTreeNode(rootSaveFile.getName());
        createFiles(rootNode, rootSaveFile.listFiles());
    } else {
        rootNode = new DefaultMutableTreeNode("error");
    }
    this.jtree = new JTree(rootNode);

    this.jsptree.updateUI();
    jsptree.setViewportView(jtree);
    jtree.setEditable(true);

}

您不應構建新的JTree。 您應該改為更新它的模型。

另外,您可能需要一種算法來還原擴展/選定狀態。

我正在做類似的事情,我會發布一些代碼,但是要小心,它沒有經過測試。 這段代碼在TreeModel實現中。

public void refresh() {
    final TreePath[] selectionPaths = files.getSelectionPaths();
    final Enumeration<TreePath> expandedDescendants = files.getExpandedDescendants(new TreePath(root));
    SwingWorker sw = new SwingWorker() {

        @Override
        protected Object doInBackground() throws Exception {
            //HttpUtils.fetchSrc() returns a TreeNode
            syncModel(root, HttpUtils.fetchSrc()); 
            return null;
        }

        @Override
        public void done() {
            //Expand old paths

            //Select old paths

            files.repaint();
        }
    };
    sw.execute();
}

/**
 * Sync two tree nodes. This should be used when refreshing the files tree model.
 * @param localNode Local node
 * @param remoteNode Remote node
 */
private void syncModel(DirOrFile localNode, DirOrFile remoteNode) {
    // Remove deleted nodes
    for (int i = 0; i < localNode.getChildCount(); i++) {
        DirOrFile currentChild = (DirOrFile) localNode.getChildAt(i);
        // Search the 2nd tree for this child
        DirOrFile corespondent = null;
        for (int j = 0; j < remoteNode.getChildCount(); j++) {
            DirOrFile current = (DirOrFile) remoteNode.getChildAt(j);
            if (current.getUserObject().equals(currentChild.getUserObject())) {
                corespondent = current;
            }
        }
        // Corespondent not found, we need to remove this node from local tree
        if (corespondent == null) {
            localNode.remove(currentChild);
            notifyListeners(localNode); // Fire tree model change event
        } else if (corespondent.isDirectory()){
            // Recurively sync
            syncModel (currentChild, corespondent);
        }
    }

    // Add missing nodes
    for (int i=0; i < remoteNode.getChildCount(); i++) {
        DirOrFile remoteCurrent = (DirOrFile) remoteNode.getChildAt(i);
        // Search the 1st tree node to see if this node should be added.
        DirOrFile corespondent = null;
        for (int j=0; j < localNode.getChildCount(); j++) {
            DirOrFile localCurrent = (DirOrFile) localNode.getChildAt(j);
            if (localCurrent.getUserObject().equals(remoteCurrent.getUserObject())) {
                corespondent = remoteCurrent;
            }
        }
        // If no corespondent was found in local tree, add remote node
        if (corespondent == null) {
            localNode.insert(remoteCurrent, i);
            notifyListeners(localNode); // Fire tree model change event
        }
    }
}

我剛遇到此問題,而閱讀您遇到的同一問題有助於我解決此問題。 我認為這是正在發生的事情。 通過將tree變量重新分配給新樹來“重建”樹時,您會將原始樹交換為完全不同的樹, 包括listeners 因此,在銷毀舊樹並將其替換為舊樹后調用的getLastSelectedComponent()是A)調用舊版本,仍然指向基本上不再存在的舊樹(返回null),或B)調用新版本,該新版本未在視覺上表示出來,而是坐着,在某處不可見,沒有選擇任何內容(返回null)。 編輯:如果您可以直觀地確認添加的新節點在那,那么它肯定是A而不是B(假設兩者之一是正確的)。 如果新樹不可見,您將看不到新節點添加到新樹中(除非您將其添加到舊樹中, 然后使用相同的根創建了新樹)

我不確定其中哪個更正確,也許都不代表實際情況,但是當我通過使用model = (DefaultTreeModel) tree.getModel(); model.insertNodeInto(newNode, (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(), 0);更新樹時model = (DefaultTreeModel) tree.getModel(); model.insertNodeInto(newNode, (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(), 0); model = (DefaultTreeModel) tree.getModel(); model.insertNodeInto(newNode, (DefaultMutableTreeNode)tree.getLastSelectedPathComponent(), 0); 如果不將tree變量分配給新樹,它就會按預期開始工作,並且我相信您也會遇到同樣的情況。

只需repaint()revalidate() JTree

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM