Lewis
asked on
JTree and JList: data reference
I want to put something together like the Windows Explorer.
A JTree on the left showing a hierarchy, a JList presenting
the contents of a selected node.
How do I get references to actual data into a JTree and
a JList? It is quite easy to fill both with strings.
But how do I get a reference to the underlying data of
each node? Is it possible to store a reference together
with the string in a node?
I want double click a node and then a window with
the respective data comes up! Consequently I will
have to supply the MouseListener with some data!
Regards, Lewis.
A JTree on the left showing a hierarchy, a JList presenting
the contents of a selected node.
How do I get references to actual data into a JTree and
a JList? It is quite easy to fill both with strings.
But how do I get a reference to the underlying data of
each node? Is it possible to store a reference together
with the string in a node?
I want double click a node and then a window with
the respective data comes up! Consequently I will
have to supply the MouseListener with some data!
Regards, Lewis.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
You can put any object you want into a DefaultMutableTreeNode.
You can also put any object you want into a JList's
ListModel. I believe that by default the TreeCellRenderer
and ListCellRenderer will call the object's toString()
method and get the string to display that way. So, you can
either make your objects put out their text that way and
use the default renderer, or you can create custom cell
renderers if you want more control.
You can also put any object you want into a JList's
ListModel. I believe that by default the TreeCellRenderer
and ListCellRenderer will call the object's toString()
method and get the string to display that way. So, you can
either make your objects put out their text that way and
use the default renderer, or you can create custom cell
renderers if you want more control.
ASKER
I just yesterday found that information about
models (MVS).
Can you explain (in easy words) this model
idea to me? I haven't quite understood it!
models (MVS).
Can you explain (in easy words) this model
idea to me? I haven't quite understood it!
I'll give it a shot. Most JFC components are made up of three
parts:
1) The component class like JTree or JButton. This class
stores information about the external state of itself --
things like its border, button icon, button text, background
color, etc.
2) The model class like DefaultButtonModel or DefaultTreeModel.
This class stores data associated with the component (like the
tree nodes) and internal state information (like whether a
button is pressed, whether the component is disabled, etc.).
For JTree, the model class also allows access to the tree's
data.
3) A look-and-feel class like BasicButtonUI. This class
is responsible for drawing the component. For a JButton, it
asks the JButton class for its text string and icon (if any),
and asks the DefaultButtonModel (which it gets from the JButton
class) for information about whether the button is pressed,
etc. so it can draw the component properly. This class doesn't
store data itself because a different look-and-feel could be
plugged-in at any moment and BasicButtonUI could be replaced
with something like RoseButtonUI. The look-and-feel class
is also responsible for reacting to events like mouse clicks
within itself. So, when you press on a JButton, the look-and-
feel class is notified. It then asks the model class if it
is enabled. If so, it tells the model it is now pressed and
repaints itself. When the mouse is then released, the look-
and-feel class tells the model class that it is no longer
pressed and generates an ActionEvent which is broadcast to
any registered ActionListeners.
This is a somewhat simplified explanation of a topic that
still confuses me, but I hope it helps.
parts:
1) The component class like JTree or JButton. This class
stores information about the external state of itself --
things like its border, button icon, button text, background
color, etc.
2) The model class like DefaultButtonModel or DefaultTreeModel.
This class stores data associated with the component (like the
tree nodes) and internal state information (like whether a
button is pressed, whether the component is disabled, etc.).
For JTree, the model class also allows access to the tree's
data.
3) A look-and-feel class like BasicButtonUI. This class
is responsible for drawing the component. For a JButton, it
asks the JButton class for its text string and icon (if any),
and asks the DefaultButtonModel (which it gets from the JButton
class) for information about whether the button is pressed,
etc. so it can draw the component properly. This class doesn't
store data itself because a different look-and-feel could be
plugged-in at any moment and BasicButtonUI could be replaced
with something like RoseButtonUI. The look-and-feel class
is also responsible for reacting to events like mouse clicks
within itself. So, when you press on a JButton, the look-and-
feel class is notified. It then asks the model class if it
is enabled. If so, it tells the model it is now pressed and
repaints itself. When the mouse is then released, the look-
and-feel class tells the model class that it is no longer
pressed and generates an ActionEvent which is broadcast to
any registered ActionListeners.
This is a somewhat simplified explanation of a topic that
still confuses me, but I hope it helps.
ASKER
So, if I understand you correctly, I have to build a
model of my tree to store the data?
Could you give me example code of
1) how to associate data with a tree node
(in my case I would have to store something
like: "CN=Peter,OU=Sales Dept.,O=Company Inc., C=US"
which is the reference to an entry in an LDAP
server.)
2) how to put a Listener into the whole thing
(When I double click the tree node "Peter"
from the example above I need to get that
reference back and put it in a method call
like:
getAttributes("the_string_ from_above ");
This method will then return the values
which refer to "Peter", like his e-mail
address, his age, ...)
model of my tree to store the data?
Could you give me example code of
1) how to associate data with a tree node
(in my case I would have to store something
like: "CN=Peter,OU=Sales Dept.,O=Company Inc., C=US"
which is the reference to an entry in an LDAP
server.)
2) how to put a Listener into the whole thing
(When I double click the tree node "Peter"
from the example above I need to get that
reference back and put it in a method call
like:
getAttributes("the_string_
This method will then return the values
which refer to "Peter", like his e-mail
address, his age, ...)
To create a DefaultMutableTreeNode with an object in it:
// Create the object.
String nodeString1 = new String( "CN=..." );
// Create the node.
DefaultMutableTreeNode node =
new DefaultMutableTreeNode( nodeString1 );
You create a root node and you can either explicitly use
it to create a DefaultTreeModel, or you can create a JTree
with the node and that implicitly creates a DefaultTreeModel:
JTree tree = new JTree( node );
To find out which node was double-clicked, listen for the
JTree's mouse events, and when you get a double-click, use
the MouseEvent's x and y coordinates to ask the JTree for
the node at that location. Use the getPathForLocation(..)
method. That gives you a TreePath, and you can use its
getLastPathComponent() method to get the actual double-
clicked node. Then call the node's getUserObject() method
to get its contents.
// Create the object.
String nodeString1 = new String( "CN=..." );
// Create the node.
DefaultMutableTreeNode node =
new DefaultMutableTreeNode( nodeString1 );
You create a root node and you can either explicitly use
it to create a DefaultTreeModel, or you can create a JTree
with the node and that implicitly creates a DefaultTreeModel:
JTree tree = new JTree( node );
To find out which node was double-clicked, listen for the
JTree's mouse events, and when you get a double-click, use
the MouseEvent's x and y coordinates to ask the JTree for
the node at that location. Use the getPathForLocation(..)
method. That gives you a TreePath, and you can use its
getLastPathComponent() method to get the actual double-
clicked node. Then call the node's getUserObject() method
to get its contents.
ASKER
Sorry, but it took me a while to figure this out.
You certainly wait for your points.
Final questions:
1. I can put any Object into a DefaultMutableTreeNode
and the toString method of that object is responsible
for delivering a String that is displayed by the tree?
2. I have to check the x and y position in order to
find a selected node? No better way?
3. I don't have to register a Listener with every node?
Instead I provide on [?]TreeListener and pass the node
to it that I just found out via the TreePath?
4. What exatly are TreePaths? Objects that contain an
absolute path?
5. What's the difference between calling JTree with
a DefaultTreeModel versus DefaultMutableTreeNode?
Regards.
You certainly wait for your points.
Final questions:
1. I can put any Object into a DefaultMutableTreeNode
and the toString method of that object is responsible
for delivering a String that is displayed by the tree?
2. I have to check the x and y position in order to
find a selected node? No better way?
3. I don't have to register a Listener with every node?
Instead I provide on [?]TreeListener and pass the node
to it that I just found out via the TreePath?
4. What exatly are TreePaths? Objects that contain an
absolute path?
5. What's the difference between calling JTree with
a DefaultTreeModel versus DefaultMutableTreeNode?
Regards.
Yes, I believe DefaultMutableTreeNode displays the user
object's toString() result.
To track selections in a JTree, register your class as a
TreeSelectionListener. Then, when you are notified of a
tree selection change (the valueChanged() method is called),
you can get the path of the selected node using the
TreeSelectionEvent's getPath() method, then you can use1
TreePath's getLastPathComponent() method.
You definitely do not need to register with each node. As
long as you register as a TreeSelectionListener, you will
be notified when any node is selected or deselected.
A TreePath is basically a thing that contains an array of
TreeNodes that gets you from one node (usually root) to
another node. When you get a selected TreePath, the
node that is actually selected is the last node in the
TreePath.
When you create a JTree with a DefaultMutableTreeNode, the
JTree takes care of creating the DefaultTreeModel. So,
there really isn't much difference.
object's toString() result.
To track selections in a JTree, register your class as a
TreeSelectionListener. Then, when you are notified of a
tree selection change (the valueChanged() method is called),
you can get the path of the selected node using the
TreeSelectionEvent's getPath() method, then you can use1
TreePath's getLastPathComponent() method.
You definitely do not need to register with each node. As
long as you register as a TreeSelectionListener, you will
be notified when any node is selected or deselected.
A TreePath is basically a thing that contains an array of
TreeNodes that gets you from one node (usually root) to
another node. When you get a selected TreePath, the
node that is actually selected is the last node in the
TreePath.
When you create a JTree with a DefaultMutableTreeNode, the
JTree takes care of creating the DefaultTreeModel. So,
there really isn't much difference.
ASKER
Do you anything about memory usage?
Do I have to free the whole tree
recursively if I do not need it any
longer? Or is it sufficient to set
root to null and let the garbage
collector take care of it?
Anyway, here are your points.
Thanks, your advice was very helpful!
Do I have to free the whole tree
recursively if I do not need it any
longer? Or is it sufficient to set
root to null and let the garbage
collector take care of it?
Anyway, here are your points.
Thanks, your advice was very helpful!
Yes, just set root to null and the garbage collector will
deal with the rest.
Good luck!
deal with the rest.
Good luck!
ASKER
but the data I want to display is not stored
in files, I get it from another server.
So, I need to store general information in a
node, not File objects. Is it possible to
put objects of type Object there?
Do you know anything about JList, concerning
the same problem?