2014-03-27 7 views
0

JTree에서 노드를 검색하는 응용 프로그램을 개발했습니다. "원본 트리 가져 오기"버튼을 클릭 할 때마다 clonedRoot에 원래 데이터가 채워 져야합니다. 모든 처리는 clonedRoot에서 수행됩니다.Jtree가 업데이트되지 않았습니다.

업데이트 된 clonedRoot이 패널에 렌더링되지 않는 것을 제외하면 모든 것이 잘 작동합니다 (콘솔 출력 추정). 원본 데이터 enter image description here

로 채워

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); for (int i = 0; i < clonedTree.getRowCount(); i++) { clonedTree.expandRow(i); } System.out.println("Updated tree"); } 

clonedRoot 후 검색 작업 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

코드에서 clonedTree 만 표시되는 것을 볼 수 있습니다. 왜 2 그루의 나무를 사용합니까? – Slimu

답변

0

내가 (당신이 treeModel.reload를 호출해야한다고 생각)을 수행 한 후 당신은 모델을 설정

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); 
    } 
} 

내가 테스트 클래스에 코드를 넣어 다음과 같은 복제 방식했습니다 :

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

: 작동하지 않습니다. –

+0

노드를 검색 할 때 트리가 업데이트되어서는 안됩니다. –

+0

클론 트리를 보았습니다. 창문에 또 다른 나무가 있습니까? – Slimu

관련 문제