Java: How to programmatically select and expand multiple nodes in a JTree?

java, jtree, select, swing, treenode

Solution

You are looking for the `TreeSelectionModel` of the `JTree` (use the getter). Use the `TreeSelectionModel#setSelectionPaths` for multiple paths. Now you are only setting one node selected due to your `tree.setSelectionPath(tpath);` call. The `TreeSelectionModel` also has methods to add/remove to an existing selection ,... (basically everything you might need in the future).

An interesting method for the expansion is the `JTree#setExpandsSelectedPaths` method which allows to configure the `JTree` to automatically expand selected paths. If you want to manage this manually, you can use the `JTree#setExpandedState` method

Problem

I have a `JTree` and an `awt.Canvas`. When i select multiple objects from within the `Canvas` into the `objList`, I want all the selected items to be shown inside the `JTree` as selected. That means for example if I have 2 objects selected, both their paths to root should be expanded, and also each selected object should have its corresponding `TreeNode` selected. My JTree has `TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION`. Here is a sample of the expand funcion i use : ``` public void selectTreeNodes() { HashMap <String, MyEntity> entities = ...; Iterator it = entities.keySet().iterator(); while (it.hasNext()) { String str = it.next().toString(); MyEntity ent = entities.get(str); if (ent.isSelected()) { DefaultMutableTreeNode searchNode = searchNode(ent.getName()); if (searchNode != null) { TreeNode[] nodes = ((DefaultTreeModel) tree.getModel()).getPathToRoot(searchNode); TreePath tpath = new TreePath(nodes); tree.scrollPathToVisible(tpath); tree.setSelectionPath(tpath); } } } } public DefaultMutableTreeNode searchNode(String nodeStr) { DefaultMutableTreeNode node = null; Enumeration enumeration= root.breadthFirstEnumeration(); while(enumeration.hasMoreElements()) { node = (DefaultMutableTreeNode)enumeration.nextElement(); if(nodeStr.equals(node.getUserObject().toString())) { return node; } } //tree node with string node found return null return null; } ``` In my current state, if I select a single object, it will be selected in the `JTree` and its `TreePath` will be shown. But if `entities` has more than 1 object selected, it will display nothing, my `JTree` will remain unchanged.

Original source