Jtree没有更新

时间:2014-03-27 11:49:39

标签: java jtree

我开发了一个应用程序来搜索JTree中的节点。只要单击“获取原始树”按钮,就应使用原始数据填充clonedRoot。所有处理都在clonedRoot上进行。

除了更新的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");
        }
执行搜索操作后

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

1 个答案:

答案 0 :(得分: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,并在更新后再次添加它。