问题
I looked for answer but wasn't able find anything to solve this. I have two array lists containing Strings that're changing dynamically after user click, and now creating JTree that will show elements from one list depends on some type in another list. I have a problem because I always add and delete something in my list and need JTree to show that changes. It will add all elements from List correctly till I expand, after that it's impossible to update content of JTree, at least for me. If I empty my list it will show like it's collapsed but all content is still showing like it's expanded even it gives in console that childcount is 0, and if I add something to my list it's going to add it but won't show it. So basically the problem is to visually show changes of JTree.
public class JSelectedTree extends JPanel{
private JTree selectionTree;
private DefaultTreeModel treeModel;
public DefaultMutableTreeNode point;
public DefaultMutableTreeNode polygon;
public DefaultMutableTreeNode line;
public JSelectedTree() {
initGUI();
}
public void initGUI() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
point = new DefaultMutableTreeNode("Point");
polygon = new DefaultMutableTreeNode("Polygon");
line = new DefaultMutableTreeNode("Line");
root.add(point);
root.add(polygon);
root.add(line);
treeModel = new DefaultTreeModel(root);
selectionTree = new JTree(root);
selectionTree.setRootVisible(false);
selectionTree.setShowsRootHandles(false);
selectionTree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
JScrollPane scroll = new JScrollPane(selectionTree);
scroll.setBorder(BorderFactory.createTitledBorder("Selected"));
setLayout(new BorderLayout());
add(scroll, BorderLayout.CENTER);
}
public void resetTree(){
if(!MultiSelectTool.selectedObject.isEmpty()){
polygon.removeAllChildren();
point.removeAllChildren();
line.removeAllChildren();
treeModel.reload();
int n = MultiSelectTool.selectedObject.size();
for(int i = 0; i < n; i++){
if(MultiSelectTool.selectedCoords.get(i).contains("(((")){
DefaultMutableTreeNode child = new DefaultMutableTreeNode(MultiSelectTool.selectedObject.get(i));
treeModel.insertNodeInto(child, polygon, polygon.getChildCount());
}else if(MultiSelectTool.selectedCoords.get(i).contains("((")){
DefaultMutableTreeNode child = new DefaultMutableTreeNode(MultiSelectTool.selectedObject.get(i));
treeModel.insertNodeInto(child, line, line.getChildCount());
}else{
DefaultMutableTreeNode child = new DefaultMutableTreeNode(MultiSelectTool.selectedObject.get(i));
treeModel.insertNodeInto(child, point, point.getChildCount());
}
}
}else{
polygon.removeAllChildren();
point.removeAllChildren();
line.removeAllChildren();
treeModel.reload();
}
}
}
回答1:
Try to use an MVC pattern so you can update the view:)
回答2:
Solved by taking some parts from DynamicTreeDemo and here is code if somebody need something like this
public class JSelectedTree extends JPanel{
static JButton addButton;
public static DynamicTree treePanel;
public DefaultMutableTreeNode point;
public DefaultMutableTreeNode polygon;
public DefaultMutableTreeNode line;
DefaultMutableTreeNode p1, p2, p3;
public JSelectedTree() {
treePanel = new DynamicTree();
populateTree(treePanel);
addButton = new JButton("Add");
addButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(!MultiSelectTool.selectedObject.isEmpty()){
treePanel.clear();
populateTree(treePanel);
int n = MultiSelectTool.selectedObject.size();
for(int i = 0; i < n; i++){
if(MultiSelectTool.selectedCoords.get(i).contains("(((")){
String child = new String(MultiSelectTool.selectedObject.get(i));
treePanel.addObject(p1,child, true);
}else if(MultiSelectTool.selectedCoords.get(i).contains("((")){
String child = new String(MultiSelectTool.selectedObject.get(i));
treePanel.addObject(p2,child, true);
}else{
String child = new String(MultiSelectTool.selectedObject.get(i));
treePanel.addObject(p3,child, true);
}
}
}else{
treePanel.clear();
populateTree(treePanel);
}
}
});
treePanel.setPreferredSize(new Dimension(200, 200));
add(treePanel, BorderLayout.CENTER);
treePanel.setBorder(BorderFactory.createTitledBorder("Selected"));
}
public void populateTree(DynamicTree treePanel) {
String p1Name = new String("Polygon");
String p2Name = new String("Point");
String p3Name = new String("Line");
p1 = treePanel.addObject(null, p1Name, true);
p2 = treePanel.addObject(null, p2Name, true);
p3 = treePanel.addObject(null, p3Name, true);
}
}
class DynamicTree extends JPanel {
protected DefaultMutableTreeNode rootNode;
protected DefaultTreeModel treeModel;
protected JTree tree;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
public DynamicTree() {
super(new GridLayout(1, 0));
rootNode = new DefaultMutableTreeNode("Root Node");
treeModel = new DefaultTreeModel(rootNode);
tree = new JTree(treeModel);
tree.setEditable(true);
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.setShowsRootHandles(true);
JScrollPane scrollPane = new JScrollPane(tree);
add(scrollPane);
}
/** Remove all nodes except the root node. */
public void clear() {
rootNode.removeAllChildren();
treeModel.reload();
}
/** Remove the currently selected node. */
public void removeCurrentNode() {
TreePath currentSelection = tree.getSelectionPath();
if (currentSelection != null) {
DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) (currentSelection
.getLastPathComponent());
MutableTreeNode parent = (MutableTreeNode) (currentNode.getParent());
if (parent != null) {
treeModel.removeNodeFromParent(currentNode);
return;
}
}
// Either there was no selection, or the root was selected.
toolkit.beep();
}
public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
Object child) {
return addObject(parent, child, false);
}
public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
Object child, boolean shouldBeVisible) {
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child);
if (parent == null) {
parent = rootNode;
}
// It is key to invoke this on the TreeModel, and NOT DefaultMutableTreeNode
treeModel.insertNodeInto(childNode, parent, parent.getChildCount());
// Make sure the user can see the lovely new node.
if (shouldBeVisible) {
tree.scrollPathToVisible(new TreePath(childNode.getPath()));
}
return childNode;
}
class MyTreeModelListener implements TreeModelListener {
public void treeNodesChanged(TreeModelEvent e) {
DefaultMutableTreeNode node;
node = (DefaultMutableTreeNode) (e.getTreePath().getLastPathComponent());
/*
* If the event lists children, then the changed node is the child of the
* node we've already gotten. Otherwise, the changed node and the
* specified node are the same.
*/
int index = e.getChildIndices()[0];
node = (DefaultMutableTreeNode) (node.getChildAt(index));
System.out.println("The user has finished editing the node.");
System.out.println("New value: " + node.getUserObject());
}
public void treeNodesInserted(TreeModelEvent e) {
}
public void treeNodesRemoved(TreeModelEvent e) {
}
public void treeStructureChanged(TreeModelEvent e) {
}
}
}
来源:https://stackoverflow.com/questions/37967989/jtree-dynamically-updating-with-arraylist-changes