首页 文章

JTree在重新加载后避免崩溃

提问于
浏览
0

我正在尝试在重新加载后找到解决 JTree 崩溃的问题 . 情况:

JTree

[-] Office A
 |---[-] Office A.1
 |    |---[-] Office A.1.1
 |    |---[-] Office A.1.2
[-] Office B
 |---[-] Office B.1
 |    |---[-] Office B.1.1
 |    |    |---[-] Office B.1.1.1

现在我必须添加 Office A.1.3 . 要做到这一点,我得到 Office A.1 并使用方法 add(DefaultMutableTreeNode aNode) 我添加 Office A.1.3 .

OfficeA1.add(OfficeA13);

在此之后,我在树的 DefaultTreeModel 上调用 reload 方法 .

问题是在这次调用之后树崩溃了所有:

[+] Office A
[+] Office B

我必须手动扩展节点 Office A 以确保添加节点...

[-] Office A
 |---[-] Office A.1
 |    |---[-] Office A.1.1
 |    |---[-] Office A.1.2
 |    |---[-] Office A.1.3
[+] Office B

My code...

DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root not visibile");
   DefaultMutableTreeNode usersRoot = new DefaultMutableTreeNode("Utenti");
   DefaultMutableTreeNode groupsRoot = new DefaultMutableTreeNode("Gruppi");
   DefaultMutableTreeNode officesRoot = new DefaultMutableTreeNode("Uffici")
   root.add(usersRoot);
   root.add(groupsRoot);
   root.add(officesRoot);

   JTree ccTree = new JTree(root);

当我添加节点...

Office anOffice = //get the correct office object
DefaultTreeModel model = (DefaultTreeModel)competenzaTree.getModel();
DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot();

DefaultMutableTreeNode n = (DefaultMutableTreeNode)root.getChildAt(0);

n.add(new DefaultMutableTreeNode(anOffice));
model.reload(n);

问题是 officesRoot 节点 . usersRootgroupsRoot 节点不是分层的 .

有没有办法避免这种行为?谢谢 .

可能是另一种提问方式可能是 which is the way to add/remove node from a tree without causing collapse of all tree ?

附:我也读过this post但它没有帮助我 .

1 回答

  • 2

    考虑使用DefaultTreeModel#insertNodeInto(DefaultMutableNode, DefaultMutableNode, int),它应该通知 JTree 表新节点可用,导致 JTree 更新,但不应影响树的当前展开状态

    此示例基于How to use trees中的示例

    import java.awt.BorderLayout;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.UIManager;
    
    import javax.swing.JTree;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.TreeSelectionModel;
    import javax.swing.event.TreeSelectionEvent;
    import javax.swing.event.TreeSelectionListener;
    
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.tree.TreePath;
    
    public class TestTree extends JPanel {
    
        private JTree tree;
        private DefaultTreeModel model;
        private JButton btnAdd;
        private int childCount;
    
        public TestTree() {
            super(new BorderLayout());
    
            //Create the nodes.
            DefaultMutableTreeNode top = new DefaultMutableTreeNode("The Java Series");
            createNodes(top);
    
            model = new DefaultTreeModel(top);
    
            //Create a tree that allows one selection at a time.
            tree = new JTree(model);
            tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    
            //Create the scroll pane and add the tree to it. 
            JScrollPane treeView = new JScrollPane(tree);
    
            //Add the split pane to this panel.
            add(treeView);
    
            btnAdd = new JButton("Add");
            btnAdd.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    TreePath treePath = tree.getSelectionPath();
                    if (treePath != null) {
                        DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath.getLastPathComponent();
                        DefaultMutableTreeNode child = new DefaultMutableTreeNode("Child " + (++childCount));
                        model.insertNodeInto(child, node, node.getChildCount());
                    }
                }
            });
    
            add(btnAdd, BorderLayout.SOUTH);
        }
    
        private class BookInfo {
    
            public String bookName;
    
            public BookInfo(String book) {
                bookName = book;
            }
    
            public String toString() {
                return bookName;
            }
        }
    
        private void createNodes(DefaultMutableTreeNode top) {
            DefaultMutableTreeNode category = null;
            DefaultMutableTreeNode book = null;
    
            category = new DefaultMutableTreeNode("Books for Java Programmers");
            top.add(category);
    
            //original Tutorial
            book = new DefaultMutableTreeNode(new BookInfo("The Java Tutorial: A Short Course on the Basics"));
            category.add(book);
    
            //Tutorial Continued
            book = new DefaultMutableTreeNode(new BookInfo("The Java Tutorial Continued: The Rest of the JDK"));
            category.add(book);
    
            //JFC Swing Tutorial
            book = new DefaultMutableTreeNode(new BookInfo("The JFC Swing Tutorial: A Guide to Constructing GUIs"));
            category.add(book);
    
            //Bloch
            book = new DefaultMutableTreeNode(new BookInfo("Effective Java Programming Language Guide"));
            category.add(book);
    
            //Arnold/Gosling
            book = new DefaultMutableTreeNode(new BookInfo("The Java Programming Language"));
            category.add(book);
    
            //Chan
            book = new DefaultMutableTreeNode(new BookInfo("The Java Developers Almanac"));
            category.add(book);
    
            category = new DefaultMutableTreeNode("Books for Java Implementers");
            top.add(category);
    
            //VM
            book = new DefaultMutableTreeNode(new BookInfo("The Java Virtual Machine Specification"));
            category.add(book);
    
            //Language Spec
            book = new DefaultMutableTreeNode(new BookInfo("The Java Language Specification"));
            category.add(book);
        }
    
        /**
         * Create the GUI and show it. For thread safety, this method should be
         * invoked from the event dispatch thread.
         */
        private static void createAndShowGUI() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                ex.printStackTrace();
            }
    
            //Create and set up the window.
            JFrame frame = new JFrame("TreeDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            //Add content to the window.
            frame.add(new TestTree());
    
            //Display the window.
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            //Schedule a job for the event dispatch thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    
    }
    

相关问题