JTree leaf association to an object

T

Tim Hoffman

I build a jtree from a flat file wtih tab delimited records.
The leaf strings are not unique. They indicate warning messages from
files names that are unique and form the branch that the leafs are on.

My question is: How do I associate a non unique leaf string to a
particular object that represents information from the record that the
leaf is created from... so that I can retrieve the object information
when that leaf is selected?

file x
warning xyz
warning abc
warning xyz
file y
warning abc
warning xyz

Is there some information that I can get when the leaf is selected
that I can associate to information at the time the leaf is created so
that I can access its object?

Many thanks in advance

Tim Hoffman (java newbie)
 
S

SPG

Hi Tim,

When you create your TreeNodes, I would accept the root object as a
parameter in the constructor.
Then I would have a getRootObject() method that allows you access to the
object that the node represents.
It is also worth implementing an equals() method that delegaes to the root
object so you can test for equality directly to the node.

eg:

public class MyLeafNode implements TreeNode{
private Object rootObj;

public MyLeafNode(Object rootObj){
this.rootObj = rootObj;
}
public Object getRootObject(){
return this.rootObj;
}
public boolean equals(Object o){
return getRootObject().equals(o);
}

//Now add your normal tree node interface implementation here!

}

HTH

Steve
 
C

Chris Smith

Tim said:
I build a jtree from a flat file wtih tab delimited records.
The leaf strings are not unique. They indicate warning messages from
files names that are unique and form the branch that the leafs are on.

My question is: How do I associate a non unique leaf string to a
particular object that represents information from the record that the
leaf is created from... so that I can retrieve the object information
when that leaf is selected?

Easy: you parse the information, store it in data structures as
appropriate, and then you write a TreeModel implementation and an
accompanying TreeCellRenderer implementation that are used to let the
JTree understand and display this information as desired.

Your question about storing values associated with non-unique warning
names is easy: you'd probably store the name-value mapping in different
data structures. Perhaps it would be appropriate to have a top-level
List, and the elements of that list would be an object, whose members
would be a name (i.e., 'x' and 'y' below) and a List of name/value
pairs. That data structure should be changed as needed, depending on
how your application will actually use the information. More
importantly, your question has absolutely nothing to do with JTree.

(One exception to that last sentence: if the data will be mutable, you
should keep in mind that notifying others of changes somehow is probably
a requirement of this data structure. However, if the data doesn't
change once it's read, then this isn't a concern. Moreover, if the data
layer doesn't provide this functionality, it's still possible to adapt
the data to a JTree, but it will simply require a manual refresh when
data changes.)

The second part of your task is to write the model adapter (an
implementation of TreeModel) and the cell renderer (implementing
TreeCellRenderer... though it's generally more convenient to extend
DefaultTreeCellRenderer). These classes are responsible for defining a
mapping from your data structures to the JTree class. They determine
things like how the data layer maps to nodes in the JTree (for example,
your TreeModel defines that there's a top-level node for each file, and
a subnode for each warning in the file); the label and icon that will be
used in the JTree for each node (for example, your TreeCellRenderer
defines that a file called 'x' should appear in the tree as 'file x' and
not as just 'x' or 'message group x' or some such thing).
Is there some information that I can get when the leaf is selected
that I can associate to information at the time the leaf is created so
that I can access its object?

When you right your TreeModel, you will designate an object to represent
each node of the tree. You should choose an object that provides all
the information you need to know about that node to handle its being
selected. That object preferably comes directly from your data layer,
but if you don't have a suitable object from your data layer, you may
choose to synthesize an object of your own making. For example, you
might choose to create an instance of a custom class to represent each
leaf node, and the custom class might look like this:

class MessageNode
{
private MessageFile sourceFile;
private int messageNumber;

...
}

(The implication is that the MessageFile class you've previously written
as part of your data layer would provide you with the ability to
retrieve a message by a unique message number. You would use that to
get at the information when the node is selected. Incidentally, your
TreeCellRenderer implementation would also use that to get information
about the message and determine what it should look like in the tree.)

Most importantly, don't pay any attention to the classes and interfaces
in the Java API called DefaultTreeModel, TreeNode, or
DefaultMutableTreeNode. These classes are there to encourage naive
programmers to make a mess of their application by ignoring good design
principles.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Tim Hoffman

I dont know if anyone has the stomach to look at this but it is a little of
the code Im trying to get right with. Basically I need to get information
from the fileObjectArray when a leaf of the tree is selected. Do I create
my array of fileObject first and the build the tree or do I add my file
information into some kind of mutableTreeNode extension? I am very
confused.

DefaultMutableTreeNode root = new
DefaultMutableTreeNode(filename);
DefaultMutableTreeNode source = new DefaultMutableTreeNode();
DefaultMutableTreeNode warning = new DefaultMutableTreeNode();
jTree1 = new JTree(root);
jTree1.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)
jTree1.getLastSelectedPathComponent();

if (node == null) return;
TreePath path = jTree1.getSelectionPath();
Object nodeInfo = node.getUserObject();
if (node.isLeaf()) {
// System.out.println(enum + " " + node.getRoot() + " "
+ path);
}
}
});

int i = 0;
fileObjectArray[] fileObject = new fileObjectArray[100];
BufferedReader in = new BufferedReader(new FileReader(data));
String sourceNameSave = "";
String line = in.readLine();
while (line != null){
StringTokenizer t = new StringTokenizer(line, "\t\n");
String sourceName = t.nextToken();
String lineNumString = t.nextToken();
int lineNum = Integer.parseInt(lineNumString);
String msgType = t.nextToken();
String msgDesc = t.nextToken();
if(!sourceName.equals(sourceNameSave)){
sourceNameSave = sourceName;
source = new DefaultMutableTreeNode(sourceName);
root.add(source);
}

fileObject = new fileObjectArray();
fileObject.setSourceName(sourceName);
warning = new DefaultMutableTreeNode(msgDesc);
source.add(warning);
line = in.readLine();
i++;
}
in.close();
jScrollPane1.setViewportView(jTree1);
jSplitPane1.setLeftComponent(jScrollPane1);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top