mrgrechkinn
mrgrechkinn

Reputation: 908

Multi selections in subtrees of JTree

I have a tree with a few subtrees (category), How I can allow a multi selection action only in specified subtree, for example: I can multi select nodes in category, but if I will try to select a node in other category it will be deselect nodes in current subtree and select a new one.

Upvotes: 2

Views: 3560

Answers (2)

jblazevic
jblazevic

Reputation: 21

No need to implement the TreeSelectionModel, it is enough to implement a TreeSelectionListener with the default model. Here's a semi-working example, needs a bit more tweaking to work perfectly but it illustrates the principle:

    JFrame f = new JFrame("JTree test");
    f.setSize(300, 300);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JTree t = new JTree();
    DefaultTreeModel model = (DefaultTreeModel) t.getModel();
    final TreeSelectionModel selectionModel = t.getSelectionModel();

    selectionModel.setSelectionMode(TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
    selectionModel.addTreeSelectionListener(new TreeSelectionListener() {
        @Override
        public void valueChanged(TreeSelectionEvent e) {
            // detect additive selections
            if (e.isAddedPath()) {
                TreePath selection = e.getPath();
                DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selection
                        .getLastPathComponent();

                // a contrived way to detect selection of items within a category
                if (((String) selectedNode.getUserObject())
                        .startsWith("Item")) {
                    // get the new selection's category node
                    DefaultMutableTreeNode category = (DefaultMutableTreeNode) selection
                            .getParentPath().getLastPathComponent();

                    // deselect everything outside that category
                    ArrayList<TreePath> deselectList = new ArrayList<TreePath>();
                    for (TreePath path : selectionModel.getSelectionPaths()) {
                        if (!category.equals(path.getParentPath()
                                .getLastPathComponent())) {
                            deselectList.add(path);
                        }
                    }
                    selectionModel.removeSelectionPaths(deselectList
                            .toArray(new TreePath[deselectList.size()]));
                } else {
                    // completely prevent selection of categories
                    selectionModel.removeSelectionPath(selection);
                }
            }
        }
    });

    DefaultMutableTreeNode root = new DefaultMutableTreeNode();
    DefaultMutableTreeNode category1 = new DefaultMutableTreeNode("Category 1");
    DefaultMutableTreeNode category2 = new DefaultMutableTreeNode("Category 2");
    DefaultMutableTreeNode item1 = new DefaultMutableTreeNode("Item 1");
    DefaultMutableTreeNode item2 = new DefaultMutableTreeNode("Item 2");
    DefaultMutableTreeNode item3 = new DefaultMutableTreeNode("Item 3");
    DefaultMutableTreeNode item4 = new DefaultMutableTreeNode("Item 4");

    category1.add(item1);
    category1.add(item2);
    category2.add(item3);
    category2.add(item4);

    root.add(category1);
    root.add(category2);

    t.setRootVisible(false);
    model.setRoot(root);

    f.getContentPane().add(new JScrollPane(t));
    f.setVisible(true); 

Upvotes: 2

Guillaume Polet
Guillaume Polet

Reputation: 47608

Change the default selection model of the JTree by using setSelectionModel

Provide your own implementation of the TreeSelectionModel

Upvotes: 5

Related Questions