2014-03-27 51 views
0

我開發了一個應用程序來搜索JTree中的節點。每當「獲取原始樹」按鈕被點擊時,clonedRoot應填充原始數據。所有的處理都在clonedRoot上執行。Jtree未更新

除了更新的clonedRoot未在面板上呈現外,一切工作正常(推導控制檯輸出)。

clonedRoot填充了原始數據 enter image description here

if(ae.getSource()==getOriginalTree) 
     { 
      System.out.println("Get original tree"); 
      System.out.println("Nodes present under cloned Root before deep copying"); 
      DisplayNodes(clonedRoot); 
      getDeepCopy(); 
      System.out.println("Nodes present under cloned Root after deep copying"); 
      DisplayNodes(clonedRoot); 
      DefaultTreeModel newModel = new DefaultTreeModel(clonedRoot); 
      clonedTree.setModel(newModel); 
      for (int i = 0; i < clonedTree.getRowCount(); i++) 
      { 
      clonedTree.expandRow(i); 
      } 
      System.out.println("Updated tree"); 
     } 

後執行搜索操作 enter image description here

Console Output on clicking "Get Original Tree"- 

    Get original tree 

    Nodes present under cloned Root before deep copying 

    A 
    A1 

    Cloning done 

    Nodes present under cloned Root after deep copying 

    A 
    A1 
    A2 
    A3 
    B 
    B1 
    B2 
    B3 
    C 
    C1 
    C2 
    C3 
    D 
    D1 
    D2 
    D3 
    E 
    E1 
    E2 
    E3 

    Updated tree 


Initialization Code in ctor 
{ 

     root = new DefaultMutableTreeNode("Root"); 
     tree = new JTree(root); 
     setLAF(); 
     populateTree(); 
     copyBuilder = new DeepCopyJTreeAlt(tree); 
     getDeepCopy(); 
     System.out.println("Original Tree"); 
     displayTree(tree); 
     System.out.println("Cloned Tree"); 
     displayTree(clonedTree); 
     label = new JLabel("Serach Node"); 
     field = new JTextField(); 
     for (int i = 0; i < clonedTree.getRowCount(); i++) 
     { 
     clonedTree.expandRow(i); 
     } 
     tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 
     pane = new JScrollPane(clonedTree); 
     centralPanel = new JPanel(); 
     centralPanel.setLayout(new BorderLayout()); 
     submit = new JButton("Search"); 
     submit.addActionListener(new SearchActionListener()); 
     getOriginalTree = new JButton("Get Original Tree"); 
     getOriginalTree.addActionListener(new SearchActionListener()); 
     buttonPanel = new JPanel(); 
     buttonPanel.setLayout(new GridLayout(0, 4)); 
     buttonPanel.add(label); 
     buttonPanel.add(field); 
     buttonPanel.add(submit); 
     buttonPanel.add(getOriginalTree); 
     centralPanel.add(pane, BorderLayout.CENTER); 
     centralPanel.add(buttonPanel, BorderLayout.SOUTH); 
     frame = new JFrame(); 
     frame.add(centralPanel); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(600, 500); 
     frame.setVisible(true); 

    } 

    private void populateTree() 
{ 
     A = addAFile("A", root); 
     A1 = addAFile("A1", A); 
     A2 = addAFile("A2", A); 
     A3 = addAFile("A3", A); 
     B = addAFile("B", root); 
     B1 = addAFile("B1", B); 
     B2 = addAFile("B2", B); 
     B3 = addAFile("B3", B); 
     C = addAFile("C", root); 
     C1 = addAFile("C1", C); 
     C2 = addAFile("C2", C); 
     C3 = addAFile("C3", C); 
     D = addAFile("D", root); 
     D1 = addAFile("D1", D); 
     D2 = addAFile("D2", D); 
     D3 = addAFile("D3", D); 
     E = addAFile("E", root); 
     E1 = addAFile("E1", E); 
     E2 = addAFile("E2", E); 
     E3 = addAFile("E3", E); 

    } 

private DefaultMutableTreeNode addAFile(String fileName, DefaultMutableTreeNode parentFolder) { 

     DefaultMutableTreeNode newFile = new DefaultMutableTreeNode(fileName); 

     parentFolder.add(newFile); 

     return newFile; 
    } 
+0

你可以在初始化樹相關組件(clonedTree,原始樹,它們的模型和它們添加的面板)時添加代碼嗎? – Slimu

+0

如果我用相同的模型創建一個新的JTree,它會渲染原始樹。不知道爲什麼它不能與clonedTree一起工作。 –

+0

從你的代碼我看你只顯示克隆的樹。你爲什麼要用2棵樹? – Slimu

回答

0

我想你應該叫treeModel.reload()後clonedRoot你設置模型

if(ae.getSource()==getOriginalTree) 
    { 
     System.out.println("Get original tree"); 
     System.out.println("Nodes present under cloned Root before deep copying"); 
     DisplayNodes(clonedRoot); 
     getDeepCopy(); 
     System.out.println("Nodes present under cloned Root after deep copying"); 
     DisplayNodes(clonedRoot); 
     DefaultTreeModel newModel = new DefaultTreeModel(clonedRoot); 
     clonedTree.setModel(newModel); 
     newModel.reload(); 
     for (int i = 0; i < clonedTree.getRowCount(); i++) 
     { 
     clonedTree.expandRow(i); 
     } 
     System.out.println("Updated tree"); 
    } 

我做了一個簡單的類,它有點像你所擁有的。正如你所看到的,在設置完按鈕後,樹會被新模型刷新。由於你的代碼很相似,我認爲你的clonedTree可能顯示不正確,也許它不是窗口中唯一的樹。

public class JTreeTest extends JPanel { 

private static DefaultMutableTreeNode root; 

public static void main(String[] args) { 

    JPanel panel = new JPanel(new GridLayout()); 
    JFrame frame = new JFrame("Test"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setContentPane(panel); 
    frame.setSize(400, 400); 

    root = new DefaultMutableTreeNode("A"); 
    DefaultTreeModel model = new DefaultTreeModel(root); 
    model.insertNodeInto(new DefaultMutableTreeNode("A1"), root, 0); 
    model.insertNodeInto(new DefaultMutableTreeNode("A2"), root, 0); 
    model.insertNodeInto(new DefaultMutableTreeNode("A3"), root, 0); 

    final JTree tree = new JTree(model); 
    tree.setRootVisible(true); 
    panel.add(tree); 

    JButton refresh = new JButton("Refresh") ; 
    panel.add(refresh); 
    refresh.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(final ActionEvent e) { 
      root = new DefaultMutableTreeNode("B"); 
      DefaultTreeModel newModel = new DefaultTreeModel(root); 
      tree.setModel(newModel); 
     } 
    }); 

    frame.setVisible(true); 
    } 
} 

我已經把你的代碼測試類,並提出以下clone方法:

private static void cloneRoot(DefaultMutableTreeNode updatableRoot) { 
    updatableRoot.removeAllChildren(); 
    for (int i = 0; i < root.getChildCount()/2; i++) { 
     updatableRoot.add((javax.swing.tree.MutableTreeNode) root.getChildAt(i)); 
    } 
} 

但一些測試後,我實現了一個大錯,我做。 DefaultMutableTreeNode.add()方法從父節點中刪除節點並將其放在新的父節點下。你做了一個節點的深層副本嗎?

一個正確的方法克隆這將是

private DefaultMutableTreeNode cloneRoot() { 
    DefaultMutableTreeNode updatableRoot = new DefaultMutableTreeNode("Root"); 
    for (int i = 0; i < root.getChildCount(); i++) { 
     DefaultMutableTreeNode parent = new DefaultMutableTreeNode(root.getChildAt(i)); 
     updatableRoot.add(parent); 
     Enumeration<DefaultMutableTreeNode> children = root.getChildAt(i).children(); 
     while (children.hasMoreElements()) { 
      parent.add(new DefaultMutableTreeNode(children.nextElement())); 
     } 
    } 
    return updatableRoot; 
} 

我發現了什麼問題。你getDeepCopy()方法是這樣的:

public void getDeepCopy() { 
     clonedTree = copyBuilder.cloneTree(); 
     TreeModel model = clonedTree.getModel(); 
     clonedRoot = (DefaultMutableTreeNode) model.getRoot(); 
    } 

這意味着你正在創建一個新的JTree,並將其分配給clonedTree變量你製作副本各一次。通過這樣做,您就失去了在構造函數中創建並顯示在JFrame上的初始JTree的引用。我添加了下面一個問題的解決方案,通過更新getDeepCopyMethod()

private void getDeepCopy() { 
     final JTree initialTree = copyBuilder.cloneTree(); 
     final TreeModel model = initialTree.getModel(); 
     clonedRoot = (DefaultMutableTreeNode) model.getRoot(); 
     if (clonedTree != null) { 
      clonedTree.setModel(model); 
     } else { 
     clonedTree = initialTree; 
     } 
    } 

另一種解決方案是從JScrollPane中刪除clonedTree,然後重新添加你更新後。

+0

:Nopes無法正常工作。 –

+0

那應該不是這樣,因爲當我搜索一個節點時樹被更新了。 –

+0

我看到你有一棵克隆樹,你窗戶裏有另一棵樹嗎? – Slimu