Reputation: 13284
I have a Jtree, and 2 buttons to select and unselect all nodes. I made an attempt like this:
selectAll = new JButton("Select all");
selectAll.addActionListener(new ActionListener (){
@Override
public void actionPerformed(ActionEvent e) {
int row = 0;
while (row < curvesTree.getRowCount())
{
curvesTree.expandRow(row);
row++;
}
int entradasTree = curvesTree.getRowCount();
for(int i=0; i<entradasTree; i++){
TreePath path = curvesTree.getPathForRow(i);
curvesTree.setSelectionPath(path);
}
}
});
unselectAll = new JButton("Unselect all");
unselectAll.addActionListener(new ActionListener (){
@Override
public void actionPerformed(ActionEvent e) {
curvesTree.clearSelection();
}
});
The unselect button seems to be working, but the select all only expands the JTree and selects the last node. I think every time a node is selected programatically, I'm unselecting the former one.
JTree is configured like this:
curvesTree = new JTree(rootNode);
curvesTree.setExpandsSelectedPaths(true);
curvesTree.getSelectionModel().setSelectionMode(TreeSelectionModel.
DISCONTIGUOUS_TREE_SELECTION);
Upvotes: 5
Views: 6368
Reputation: 6188
I would like to add to kleopatra's answer (based on my own growing pains).
In my particular problem, I needed to add a "Select All Children" menu item to the JTree
node popup menu. Therefore, this solution applies to all children of a selected node.
TreeNode selectedNode = tree.getSelectionPath().getLastPathComponent();
// Expand tree from selected node...
List<TreePath> paths = new ArrayList<TreePath>();
determineTreePaths(selectedNode, paths); // Recursive method call...
TreePath[] treePaths = new TreePath[paths.size()];
Iterator<TreePath> iter = paths.iterator();
for (int i = 0; iter.hasNext(); ++i)
{
treePaths[i] = iter.next();
}
if (paths.size() > 0)
{
TreePath firstElement = paths.get(0);
setSelectionPath(firstElement);
scrollPathToVisible(firstElement);
}
The determineTreePaths(selectedNode, paths)
recursive call is needed to traverse the tree from the selected node all the way down to the leaf nodes. This solution works regardless of depth (to the best of my knowledge). What I cannot say is that it is the most efficient solution. Anyone with a better solution, please feel free to post a different solution or edit this one.
The method implementation is as follows:
private void determineTreePaths(TreeNode currentNode, List<TreePath> paths)
{
paths.add(new TreePath(((DefaultTreeModel) getDefaultTreeModel()).getPathToRoot(currentNode));
// Get all of my Children
Enumeration<?> children = currentNode.children();
// iterate over my children
while (children.hasMoreElements())
{
TreeNode child = (TreeNode) children.nextElement();
determineTreePaths(child, paths);
}
}
Upvotes: 0
Reputation: 51536
the unselect happens because you are setting a new selection path instead of adding. In the loop after expanding, instead do
curvesTree.addSelectionPath(...)
EDIT
reading api is always instructive, even after years ;-) Just found a much simper method, which leaves all the work to the tree:
tree.setSelectionInterval(0, tree.getRowCount());
Upvotes: 6
Reputation: 109823
yes is that possible, for example:
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
public class TreeWithMultiDiscontiguousSelections {
public static void main(String[] argv) {
JTree tree = new JTree();
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
int treeSelectedRows[] = {3, 1};
tree.setSelectionRows(treeSelectedRows);
TreeSelectionListener treeSelectionListener = new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent treeSelectionEvent) {
JTree treeSource = (JTree) treeSelectionEvent.getSource();
System.out.println("Min: " + treeSource.getMinSelectionRow());
System.out.println("Max: " + treeSource.getMaxSelectionRow());
System.out.println("Lead: " + treeSource.getLeadSelectionRow());
System.out.println("Row: " + treeSource.getSelectionRows()[0]);
}
};
tree.addTreeSelectionListener(treeSelectionListener);
JFrame frame = new JFrame("JTree With Multi-Discontiguous selection");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(tree));
frame.setPreferredSize(new Dimension(380, 320));
frame.setLocation(150, 150);
frame.pack();
frame.setVisible(true);
}
private TreeWithMultiDiscontiguousSelections() {
}
}
Upvotes: 0