The tree node's user data object
To build a tree, you insert a root node, add children to it, add children to
those children, and so on. Swing manages the links between nodes and dbSwing manages
the data-awareness. In addition to the information it needs for housekeeping, Swing
lets you put one object, the user data object, in each node.
Goals for a user data object: Your biggest decision is what the
user data object should contain. Ideally, it will satisfy these conditions:
- It should identify a tree node uniquely. This is necessary so the data set the tree
is bound to can be synchronized properly with the tree. If there are duplicate values
in the tree, navigation in the data set will always select the first occurrence of the
value, never the second.
- It should tell the path from the root to the node. This is not essential, but is often
handy. For example, when loading the tree, you need to know where each node goes.
If the node's data itself doesn't specify this, there will have to be some associated
data that does. Depending on where the data that fills the tree comes from, you might
want to have this information be part of the node data.
- It should contain appropriate text for the node in the tree. When the tree is displayed,
you want it to be clear what each node represents. If it isn't, you'll need a cell
renderer to substitute a better caption for each node.
- It should be compact. Whenever possible, the data values stored in both the tree and
the data set it's bound to should be fairly small.
A String data object: If your data meets these conditions, it will
be a String. This is good. It's easy to build a tree when the user data object is
a String because Swing and dbSwing do more of the work: Swing uses the String as
the caption for the node, and dbSwing can find the node that matches a data value
from the data set without any help from you. The tree for this help system is close
to this ideal. Our user data object is a String, but it is a value like
"\Overview\MainCategory\TopicName". We want to display only "TopicName" in the tree,
so we do need a cell renderer.
When your data object is not a String: Often, you won't be able
to satisfy all the conditions for node data of type String. For example, you might
plan to use a unique numeric code to represent each node. You'll put just this code
in the data set column that your tree is bound to, and you'll put the code and a
String interpretation of it in the tree node. In this case, you have to do three
tasks that weren't necessary in the simpler case above:
- Define a class - we'll call it MyNodeObject - containing these two data items
and any methods you need that manipulate them. Make MyNodeObject the user data object
in the tree node.
- Override the default definition of equals() in MyTree. JdbTree and JdbNavTree
use equals() to compare values in the tree with values in the data set. Because
equals() returns true only for identical object instances, dbSwing
will never find a match. Your version of equals() should compare the value from
the data set column with the corresponding value from an instance of MyNodeObject.
In this example, we specified that you store a numeric code and a string in MyNodeObject,
but only the numeric code in the data set. This is common: the value in the data set is
smaller and easier to work with, and you can look up its interpretation when you need
it. So your equals() method should extract the numeric code from MyNodeObject and
compare it to the value from the data set.
- Because MyNodeObject is not a String, you'll need to define a cell renderer that
displays an appropriate String translation of it in the tree.
To summarize: If the data you want to carry in each node of a tree
can be a simple, unique string, working with the tree is easy. If the data is a String
but doesn't work well as the node's caption, add a cell renderer. If it's a code,
or several data items, Swing and dbSwing can't interpret your user data object without
help, so you must
- Define a user data object class. Remember to override equals() in it.
- Define a cell renderer to display a caption for the node.