Skip to main content

JTree node question

3 replies [Last post]
jacek
Offline
Joined: 2003-08-22

In a JTree node (DefaultMutableTreeNode in my case) how do I show the "expander" object (i.e. the thing you click on to expand a node) even when the node has no children?

I'm trying to create a directory chooser and would always like to display this expander. Only when the user clicks on it would I check the file system and evaluate whether there really is any subdirectory beneath it. If there aren't any only then would I remove the "expander" (exactly the same way windows explorer does it).

I've seen Karsten's JDiskReport do it exactly like that (in his directory chooser dialog), so I know it can be done...but how?

thanks,
Jacek

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
zander
Offline
Joined: 2003-06-13

In addition to the answer from Shannon the following.

When you use the application he pasted you will not be able to put new entries in the tree at the moment the user clicks the '+' in his tree; which is what you really want from such a lazy initialisation.

What I did was extend DefaultMutableTreeNode and use the userObject constructor to put my object in (a DirEntry in my case).

In that extending object I replaced the int getChildCount() method which constructs the additional child nodes (using a boolean so I do it only ones) and places them as child nodes using the insert(node, int) method.

Works like a charm.

If you have questions just ask and I'll point you to the code.

scott.violet
Offline
Joined: 2006-02-17

An example of this can also be found in the
SampleTree demo that ships with the JDK. Look at
the class DynamicTreeNode.

shan-man
Offline
Joined: 2006-02-17

Hi Jacek,

> In a JTree node (DefaultMutableTreeNode in my case)
> how do I show the "expander" object (i.e. the thing
> you click on to expand a node) even when the node has
> no children?
>
> I'm trying to create a directory chooser and would
> always like to display this expander. Only when the
> user clicks on it would I check the file system and
> evaluate whether there really is any subdirectory
> beneath it. If there aren't any only then would I
> remove the "expander" (exactly the same way windows
> explorer does it).
>
> I've seen Karsten's JDiskReport do it exactly like
> that (in his directory chooser dialog), so I know it
> can be done...but how?
>
> thanks,
> Jacek

You'll want to use a combination of DefaultTreeModel.setAsksAllowsChildren(boolean) and TreeNode.getAllowsChildren(). The JavaDoc for DefaultTreeModel.asksAllowsChildren seems to apply to what you are looking for:
[code]
/**
* Determines how the isLeaf method figures
* out if a node is a leaf node. If true, a node is a leaf
* node if it does not allow children. (If it allows
* children, it is not a leaf node, even if no children
* are present.) That lets you distinguish between folder
* nodes and file nodes in a file system, for example.
*

* If this value is false, then any node which has no
* children is a leaf node, and any node may acquire
* children.
*
* @see TreeNode#getAllowsChildren
* @see TreeModel#isLeaf
* @see #setAsksAllowsChildren
*/
[/code]
Here's a short runnable example that does what you're asking for. Notice that node "one" shows the expander object only until you click on it.
[code]
import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;

public class JT extends JFrame {

public JT() {
super("JT");

// true - allows children, non-leaf
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root", true);
// true - allows children, non-leaf
DefaultMutableTreeNode one = new DefaultMutableTreeNode("One", true);
// false - doesn't allow children, leaf
DefaultMutableTreeNode two = new DefaultMutableTreeNode("Two", false);
root.insert(one, 0);
root.insert(two, 1);

// true - the model should ask the nodes if they
// allow children to determine their leaf status
JTree tree = new JTree(root, true);
getContentPane().add(new JScrollPane(tree));
}

public static void main(String[] args) {
JT jt = new JT();
jt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jt.setSize(400, 400);
jt.setLocationRelativeTo(null);
jt.setVisible(true);
}
}
[/code]
Hope this helps!

Shannon