问题
I'm trying to find a solution the problem of collapse in JTree
after reload it.
The situation:
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
Now I have to add the Office A.1.3
. To do this I get the Office A.1
and with the method add(DefaultMutableTreeNode aNode)
I add Office A.1.3
.
OfficeA1.add(OfficeA13);
After this I call the reload
method on the DefaultTreeModel
of the tree.
The problem is that after this call the tree collapse all:
[+] Office A
[+] Office B
And I have to manually expand the node Office A
to be sure that the node is added...
[-] 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);
and when I add node...
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);
The problem is whit the officesRoot
node. The usersRoot
and groupsRoot
node are not hierarchical.
Is there a way to avoid this behavior ? Thanks.
Probably another way to ask can be which is the way to add/remove node from a tree without causing collapse of all tree ?
p.s. I also read this post but it did not help me.
回答1:
Consider using DefaultTreeModel#insertNodeInto(DefaultMutableNode, DefaultMutableNode, int) which should inform the JTree
table that a new node has become available, cause the JTree
to be updated, but shouldn't effect the current expanded state of the tree
This example is based on the example found in 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();
}
});
}
}
来源:https://stackoverflow.com/questions/22683092/jtree-avoid-collapse-after-reload