Andy
Andy

Reputation: 3532

JTree how to set a leaf node as expandable

I'm a little lost as what to search for here as I can't seem to find anything.

Basically I'm using a JTree to display a server and the structures that live within it. I don't want to load the whole structure as it takes a long time to query, so instead I'd like to load it in as the user expands nodes.

The structure looks something like this (where I always know the root server node)

Server -Tables -Columns

I'd like to first add 'Server', then when the user expands it I'd like to add 'Tables', then when the user expands that I'd like to add 'Columns'.

I've follows a tutorial on setting up the whole TreeWillExpandListener, here is my code:

public class ServerViewer extends JScrollPane
    implements TreeModelListener, TreeExpansionListener, TreeWillExpandListener  {

/**
 * 
 */
private static final long serialVersionUID = 1L;

public ServerViewer(
        final Model model) {

    Validate.isTrue(model != null, "'model' must not be null.");

    this.model = model;

    // Create root node of tree
    DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Servers (2)");
    createNodes(rootNode);

    // Create tree model
    DefaultTreeModel treeModel = new DefaultTreeModel(rootNode);
    treeModel.addTreeModelListener(this);

    // Create tree
    this.browserTree = new JTree(treeModel);
    //this.browserTree.setRootVisible(false);
    this.browserTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    this.browserTree.addTreeExpansionListener(this);
    this.browserTree.addTreeWillExpandListener(this);

    // Add components
    this.getViewport().add(this.browserTree);
}

/**
 * Populates the root node with the expected default nodes.
 * 
 * @param rootNode The node to populate.  Must not be null.
 */
private void createNodes(DefaultMutableTreeNode rootNode) {

    Validate.isTrue(rootNode != null, "'rootNode' must not be null.");

    for (ServerModel server: this.model.getServers()) {

        DefaultMutableTreeNode serverNode = new DefaultMutableTreeNode(server, true);
        rootNode.add(serverNode);
    }
}

/**
 * @return The tree which this uses as a browser.  Will not be null.
 */
public JTree getBrowserTree() {

    return this.browserTree;
}

@Override
public void treeNodesChanged(
        TreeModelEvent arg0) {

    DefaultMutableTreeNode node = (DefaultMutableTreeNode)arg0.getTreePath().getLastPathComponent();

    /*
     * If the event lists children, then the changed
     * node is the child of the node we have already
     * gotten.  Otherwise, the changed node and the
     * specified node are the same.
     */
    try {

        int index = arg0.getChildIndices()[0];
        node = (DefaultMutableTreeNode)node.getChildAt(index);
    } 
    catch (NullPointerException exc) {}

    System.out.println("The user has finished editing the node.");
    System.out.println("New value: " + node.getUserObject());
}

@Override
public void treeNodesInserted(
        TreeModelEvent arg0) {
}

@Override
public void treeNodesRemoved(
        TreeModelEvent arg0) {
}

@Override
public void treeStructureChanged(
        TreeModelEvent arg0) {
}

@Override
public void treeCollapsed(TreeExpansionEvent arg0) {
}

@Override
public void treeExpanded(TreeExpansionEvent arg0) {
}

@Override
public void treeWillCollapse(
        TreeExpansionEvent arg0) throws ExpandVetoException {

    TreePath path = arg0.getPath();
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
    String data = node.getUserObject().toString();
    System.out.println("WillCollapse: " + data);
}

@Override
public void treeWillExpand(
        TreeExpansionEvent arg0) throws ExpandVetoException {

    TreePath path = arg0.getPath();
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
    String data = node.getUserObject().toString();
    System.out.println("WillExpand: " + data);
}

/**
 * The model which this is viewing.
 */
private Model model;

/**
 * Displays the contents of a database.
 */
private JTree browserTree;
}

My issue is that When I put the 'Server' Node in, it has no children, so it doesn't have a control to expand it. This means that 'treeWillExpand()' is never called for that node. How can I make it so that it has the expand control?

Also, what's the right terminology to use here as it seems like a very typical thing to do, but I couldn't find anything on Google.

Upvotes: 2

Views: 979

Answers (1)

Andy
Andy

Reputation: 3532

As per aterai's answer:

treeModel.setAsksAllowsChildren(true)

Upvotes: 2

Related Questions