Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent node selection on node expansion in a JTree

Tags:

java

swing

jtree

I have created a JTree with some of its nodes being custom to show them as expandable although they don't have any children (yet). I have followed this thread to implement that.

Why? I want do load the tree dynamically so when the tree gets expanded, I retrieve further information from the server and show it on the tree.

The problem I am experiencing is that when I expand one of these nodes, it becomes selected, which is not the default behavior for the default nodes (you can expand them without changing the tree selection).

How to solve this to prevent this node to become selected on expansion?

like image 466
spuas Avatar asked Jan 30 '26 20:01

spuas


1 Answers

I don't get that problem with the code below. You must be doing something else that we can't guess without seeing your code. Try taking the code below and modify it to reproduce the problem you are seeing. By doing that, there is a great chance that you will find what you are doing differently and why you get that behaviour (see also SSCCE).

The code has been taken from here

import java.awt.BorderLayout;
import java.awt.Container;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;

public class DynamicTree extends JFrame {

    public class OutlineNode extends DefaultMutableTreeNode {
        private boolean areChildrenDefined = false;
        private int outlineNum;
        private int numChildren;

        public OutlineNode(int outlineNum, int numChildren) {
            this.outlineNum = outlineNum;
            this.numChildren = numChildren;
        }

        @Override
        public boolean isLeaf() {
            return false;
        }

        @Override
        public int getChildCount() {
            if (!areChildrenDefined) {
                defineChildNodes();
            }
            return super.getChildCount();
        }

        private void defineChildNodes() {
            // You must set the flag before defining children if you
            // use "add" for the new children. Otherwise you get an infinite
            // recursive loop, since add results in a call to getChildCount.
            // However, you could use "insert" in such a case.
            areChildrenDefined = true;
            for (int i = 0; i < numChildren; i++) {
                add(new OutlineNode(i + 1, numChildren));
            }
        }

        @Override
        public String toString() {
            TreeNode parent = getParent();
            if (parent == null) {
                return String.valueOf(outlineNum);
            } else {
                return parent.toString() + "." + outlineNum;
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new DynamicTree(5);
            }
        });
    }

    public DynamicTree(int n) {
        super("Creating a Dynamic JTree");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedLookAndFeelException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Container content = getContentPane();
        JTree tree = new JTree(new OutlineNode(1, n));
        content.add(new JScrollPane(tree), BorderLayout.CENTER);
        setSize(300, 475);
        setVisible(true);
    }
}
like image 108
Guillaume Polet Avatar answered Feb 02 '26 09:02

Guillaume Polet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!