DynamicTreeNodepublic class DynamicTreeNode extends DefaultMutableTreeNode DynamicTreeNode illustrates one of the possible ways in which dynamic
loading can be used in tree. The basic premise behind this is that
getChildCount() will be messaged from JTreeModel before any children
are asked for. So, the first time getChildCount() is issued the
children are loaded.
It should be noted that isLeaf will also be messaged from the model.
The default behavior of TreeNode is to message getChildCount to
determine this. As such, isLeaf is subclassed to always return false.
There are others ways this could be accomplished as well. Instead of
subclassing TreeNode you could subclass JTreeModel and do the same
thing in getChildCount(). Or, if you aren't using TreeNode you could
write your own TreeModel implementation.
Another solution would be to listen for TreeNodeExpansion events and
the first time a node has been expanded post the appropriate insertion
events. I would not recommend this approach though, the other two
are much simpler and cleaner (and are faster from the perspective of
how tree deals with it).
NOTE: getAllowsChildren() can be messaged before getChildCount().
For this example the nodes always allow children, so it isn't
a problem, but if you do support true leaf nodes you may want
to check for loading in getAllowsChildren too. |
Fields Summary |
---|
protected static float | nameCountNumber of names. | protected static String[] | namesNames to use for children. | protected static Font[] | fontsPotential fonts used to draw with. | protected static Random | nameGenUsed to generate the names. | protected static final int | DefaultChildrenCountNumber of children to create for each node. | protected boolean | hasLoadedHave the children of this node been loaded yet? |
Constructors Summary |
---|
public DynamicTreeNode(Object o)Constructs a new DynamicTreeNode instance with o as the user
object.
super(o);
|
Methods Summary |
---|
public int | getChildCount()If hasLoaded is false, meaning the children have not yet been
loaded, loadChildren is messaged and super is messaged for
the return value.
if(!hasLoaded) {
loadChildren();
}
return super.getChildCount();
| public boolean | isLeaf()
return false;
| protected void | loadChildren()Messaged the first time getChildCount is messaged. Creates
children with random names from names.
DynamicTreeNode newNode;
Font font;
int randomIndex;
SampleData data;
for(int counter = 0; counter < DynamicTreeNode.DefaultChildrenCount;
counter++) {
randomIndex = (int)(nameGen.nextFloat() * nameCount);
if(fonts != null)
font = fonts[randomIndex];
else
font = null;
if(counter % 2 == 0)
data = new SampleData(font, Color.red, names[randomIndex]);
else
data = new SampleData(font, Color.blue, names[randomIndex]);
newNode = new DynamicTreeNode(data);
/* Don't use add() here, add calls insert(newNode, getChildCount())
so if you want to use add, just be sure to set hasLoaded = true
first. */
insert(newNode, counter);
}
/* This node has now been loaded, mark it so. */
hasLoaded = true;
|
|