I have two JTrees instances (leftTree and rightTree). User can select some nodes from left tree and add the same to right tree. I have the below code in add button action listener to expand and select the node in rightTree after the node has been added.
rightTree.updateUI();
TreePath[] paths = leftTree.getSelectionPaths();
if (null != paths && paths.length > 0)
{
TreePath path = paths[0];
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
rightTree.scrollPathToVisible(new TreePath(node.getPath()));
rightTree.setSelectionPaths(paths);
}
leftTree.clearSelection();
This code seems to work fine for some nodes but it cannot work for some other nodes in leftTree. The problem is even after the above code is executed, the rightTree is in collapsed state and I cannot see the selected node.
I have tried using other methods in JTree like setExpandsSelectedPaths(true), expandPath(new TreePath(node.getParent())). Also, tried calling rightTree.repaint() or rightTree.validate() after the above code is executed. But still the problem exists. But rightTree.isExpanded(new TreePath(node.getParent())) retruns true;
My tree is about 7-8 levels deep. Please help me to solve this and let me know if you need more information.
For me the approach is incorrect. TreePath is in fact sequence of nodes from the current node to top most parent. In other words TreePath from node is created by calling getParet() till tull is reached.
So if you get a node from one tree and create path the path is sequence of node in the original tree and the path is futile in the second tree because some nodes in the path just don't exists in the target tree model.
You need to get selected node and find an appropriate one in the second tree. Guess a node with the same user object. The for the found node in the target tree (if we found it) create TreePath and select/expand.
Related
I've the following problem: I created a tree viewer and bind a data model. The tree is comlete collapsed.
Now I want to select a specific node in the tree:
treeViewer.setSelection(new StructuredSelection(person), true);
Person is one of my custom objects in the data model. The node will be found and selected if the tree is expanded.
Because the node is a child of another node (3. level), nothing happens if the tree is collapsed.
Is it possible to select/focus the node, expand the parent items etc.?
I know I can recursively walk over all nodes and try to find the correct one but is there a method which do this work for me? Or maybe there's a different call of setSelection which let's me expand the tree path?
You can use TreeSelection for this. This takes aTreePath as an argument - which lists all the nodes in the path.
TreePath path = new TreePath(... array of nodes from root to person ...);
treeViewer.setSelection(new TreeSelection(path), true);
It would be very useful to expand a JFace tree viewer in java swt as follows:
whenever a new node is added to the tree, the tree viewer expands only the currently added node in the tree (and its children if any).
I have used the expandToLevel(getIndex()) method, but this does not expands the children of the currently added node if any.
Thank you in advance for any hints and for your interest.
I've been working on a file server program for a while, and thus far I've been able to avoid posting something here for help. But I cannot find anything on my problem and I am very confused.
I've added a popup menu with the option to create new top level folder, which really just creates a node and, after its edited sends its name to the server to create the folder. While I've got all of the editing working correctly and have the upload working, I am having a problem.
I change the JTree to be editable when the folder is created, and a while loop that continues until that node is not the one being edited, at which point it removes edit-ability from the JTree.
public static void newTopFolder(){
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); //now we have the root
DefaultMutableTreeNode newFolder = new DefaultMutableTreeNode("New Folder");//will change to increment for duplicates
DefaultMutableTreeNode empty = new DefaultMutableTreeNode("< empty >"); //easier way to have empty folder, don't worry about it
tree.setEditable(true); //sets to editable
model.insertNodeInto(newFolder, root, root.getChildCount()); //adds folder to tree
model.insertNodeInto(empty, newFolder, newFolder.getChildCount()); //adds empty to tree, not real file
TreePath nfPath = getPath(newFolder); //so we don't call getPath extra times
tree.startEditingAtPath(nfPath); //automatically selects folder to edit
System.out.println(tree.getEditingPath().toString()+":"+nfPath.toString()+";"); //returns [\user\, New Folder]:[\user\, New Folder]; which shows the two are equal
while(tree.getEditingPath().equals(nfPath)){//when nothing is selected null if nothing is being edited, and path to other objects if selected
}
tree.setEditable(false); //changes to node will have been committed and editing disable
sendFolderToServer(nfPath); //sends folder to server after formatting as a String used in new File(Paths.get(nfPath));
}
Unfortunately, the while check tree.getEditingPath().equals(nfPath) always returns true, thus it remains editable.
But I don't understand why it remains true, it clearly shouldn't. In case it helps/ changes anything, this is run in a separate thread (otherwise the while loop would stop the GUI from rendering)
So what should / can I do, is there a better way to do this, or at least one that works?
UPDATE:
While I haven't found a solution to the clear problem above, If I instead test for tree.isPathSelected(nfPath) That works fine and the tree is set to not be editable afterward!
Get editing path doesn't remove the variable of the path being edited... Therefore, after it's done editing the most recently edited path is still the correct path.
Instead using tree.isPathSelected(path) will work
JTree jtree has a mouse listener attached to it.when the user clicks on a Jtree component node, I get it's row integer via
jtree.getRowForLocation(evt.getX(), evt.getY());
the problem is that the return row integer is different when there are jtree nodes which are expanded and when it's collapsed.
I need a way to somehow get a unique and absolute ID of each jtree nodes clicked so that there is no confusions.
Is there a way to add data to the Jtree component?
Otherwise, I need a way to listen to when nodes are expanded and recalculate the row returned from that above function....
In your current approach you are relying on the state of the tree view to identify the node. However, as you have found out the state of the view can change. What does not change is the tree model that is underlying the view.
If you need a unique ID for each node then you should add this directly to each tree node in your tree model. In the mouse listener you can then detect the node that you clicked on and access its unique ID.
Paths uniquely identify nodes, so getPathForLocation will give you the path, but that is a TreePath object, so if you have to have an integer represent the ID you would need to write a method that translates TreePaths to integers.
I have a tree and a TreePath to one of its nodes. How do I programatically select this node?
Will setSelectionPath of the JTree object alone work?
Yes. From the Java Documentation
If any component of the path is hidden
(under a collapsed node), and
getExpandsSelectedPaths is true it is
exposed (made viewable).