I am trying to remove nodes from a DefaultTreeModel. If I try to remove a single node, it doesn't get removed from the GUI. If I remove 2 nodes, only 1 of them is getting removed, etc.
I am using removeNodeFromParent(node); to remove the nodes.
Could someone please help me with this problem.
It sounds like your tree isn't detecting the nodesWereRemoved event that should be triggered by the removeNodeFromParent(node); method.
Are you using the standard DefaultTreeModel and JTree objects? If so, they should automatically refresh when doing a removal. If you've written a custom of either class, you're probably not handling the nodesWereRemoved event (in your custom JTree), or you're not triggering the event (in your custom DefaultTreeModel).
If you're using the standard objects, try calling JTree.revalidate(); and JTree.repaint(); after you remove the node, to force the tree to be repainted from your model change.
A final suggestion, have you tried any of the removeXXX() methods of JTree instead?
Related
I am using the JTree Swing utility to represent a Tree that actually have loops. I have a single node called root, but some of the children will eventually point back to other parts of the tree, thus not making it a true tree, but rather a graph.
My Java application keeps locking up, (no exceptions being thrown, no stack overflow... etc) when I try to use the little gray arrows to expand and contract parts of the graph.
My question is, does JTree require that none of the DefaulMutableTreeNodes not contain a loop?
If so, how do we represent something like that using a JTree utility. For example, when you are debugging an application say in eclipse, and you can infinitely use the variable tree in debug mode to keep on looking through a looped object. That is the behavior I am looking for.
Any suggestions?
I don't think it's a problem that nodes in a Jtree loop on themselves. Apparently you have a problem only with an "expand all" button, which makes sense because an expand all method will go recursively through the nodes until they have no sons.
Jtree does not have an expand all button by default, so I'm guessing yours is already customized...? My suggestion would be either remove the button, or customize the code to stop the expansion if findind a node that was already expanded higher in the hierarchy.
I have a JTree where children are instances of my class inheriting from DefaultMutableTreeNode.
At the beginning the tree has 10 nodes with two levels. Then I add children into some nodes, using add() method in my class. Then I reload my tree model:
tree.setModel(root) // root is an instance of my class.
The children are added and everything works fine. But a problem appears when I want to set the selection path (expanding added children using tree.setSelectionPath(path)). Then most nodes are truncated as if they were too long (I see an ellipsis like node).
How can this problem be solved. After commenting setSelectionPath(path) line and expanding the nodes manually, everything works fine.
After having the same problem with OpenJDK 11, the following fix works for me:
tree.expandPath(somePath);
tree.invalidate();
The key is invalidate() telling Swing that the component has to be laid out again. For more details, see Difference between validate(), revalidate() and invalidate() in Swing GUI.
I have an alternative tree implementation because Treeview did not do what I needed it to do. It works great except for one thing: event handling.
The tree consists of logical nested objects and each object is represented using a multitude of hbox, vbox, labels, etc.
When you use the tree, you want to register your event handlers on the root of the tree and intercept all the events, this works however there is not enough context information.
You might get a mouse click event from a certain instanced Label but no way of checking which item in the tree it corresponds to. When building the tree the containers for each object can intercept the events and "enhance" them to provide new context information but I'm not sure how to do this.
The copyFor() is useless as it is overriden again when you fire the event. So how can I take generic events like MouseEvent.ANY and KeyEvent.ANY and add a minimum amount of context? Am I forced to create my own events?
UPDATE
For example if we have the tree:
A
B
C
In GUI elements it could look like this:
VBox(A)
HBox(A)
Icon(A)
Label(A)
VBox(B)
HBox(B)
Icon(B)
Label(B)
VBox(C)
...
All event handler can be registered on the root VBox of A here. However suppose someone clicked on the Label(B) element, the root listener would only see that the original element is a Label. However as the listener, you want to know that it's linked to B.
IMO you can utilize the Node.setUserData() method of the label/container/treeitem/tree for keeping its related context data. Then use it first by getting the source and target nodes of desired event. Otherwise, you may have to create your own events.
I read many topics about this but still have some problems.
I'm using java desktop project from NB. I have created tree from palette and now after every click of button I want to create new tree and refresh it. So I have event action performed where I want make new jTree add some DefaultMutableTreeNode's and show this in window. Any ideas?
Maybe in other words how should I create Jtree to modify it content? I make something like this now:
in initComponents jTree1 = new JTree(nodeF);
where nodeF is my field (DefaultMutableTreeNode) initialised before initComponents
and then I want to modify this node element adding and removing another nodes.
I'm able to refresh tree ((DefaultTreeModel) jTree1.getModel()).reload(); but I'm unable to create new instance of nodeF
I fell like I'm making some stupid mistake.. dont know how to create gui right..
First idea, get away from Netbeans. Using a GUI editor prevents you from learning important parts of Swing, and generates code that is awful to debug or customize.
Second idea, it sounds like you could get away with just refreshing the existing tree and removing the current content by setting the root. That way you don't have to create a new tree each time.
Is the tree structure actually changing? Or are you just expanding/collapsing nodes in the tree? My guess is the latter.
You should probably change your data model objects to implement TreeNode. The JTree will query your TreeNode objects as needed to determine which ones have children, what the children are, etc.
To expand/contract nodes in the tree without using the built-in tree controls, use the methods in JTree, e.g. expandPath or expandRow.
I've got a JTree which I'm using to display some (unsurprisingly) hierarchical data. Part of the spec is that the user can change the data source (atm it's just between files). Now, when this happens, I can rebuild the data and the tree nodes with no problem. But, I'm having substantial difficulties getting the tree to update the changes. I tried removing it from it's scrollpane and replacing with a new JTree, but I didn't see any such. I've tried removing all from the JTree and didn't see any effect.
How can I make the JTree display changes after it's been constructed?
Ninjedit: Yes, I did call updateUI().
Another edit:
I also wanted to replace the tree's current data with my new data. However, I don't see any methods that will take the DefaultMutableTreeNode that I constructed with. Even if I just remove the JTree and call updateUI on it's containing ScrollPane, nothing happens. Or if I use repaint instead.
It could be that the proper events (the JTree internal events) are not being fired. For example, you can add nodes either by using node.add(...) or even better, model.insertNodeInto(...) (assuming you're using the DefaultTreeModel). In this case, the latter method is preferred as it will fire appropriate events that will cause the view (the JTree) to update correctly. It's possible that your problem isn't with redrawing the UI, but in fact notifying the view that the model has changed.
So, I would suggest looking in to how you're dynamically modifying your JTree, and if possible I'd suggest using the DefaultTreeModel as your model to drive the view.
And just to make sure, you've read through the Sun JTree tutorials, right?