[All]
Adapting the JTree component
By: Islam El-maddah
Abstract: JTrees when used wisely and precisely can be very fruitful. An MDI application that adapts the JTree components to represent a recursive relationship between goals is presented
Adapting the JTree component
to be fruitful
Islam A. El-Maddah
JTrees when used
wisely and precisely can be very fruitful. Software applications becoming
more sophisticated; in many situations, programmers face a problem of representing
non-linear sequence of objects. This problem widely covers different areas,
such as natural language processing NLP, structured text and media (where
the main text is divided to subsections and sub subsections), and structured
goals/rules applications. I will provide a brief example to show how the
JTree component can be adapted to contribute to the total credit of the
developed applications.
When the application
to be developed has elements that possess a recursive relation, it is not
convenient to store the elements using a linear container like a JList
component. Furthermore, the application user is less probable to accept
navigating through these elements sequentially using linear links, which
is both slow and cannot provide him/her an entire picture. Thanks to the
JTree componenet and DefaultMutableTreeNode class, it is more convenient
to stroe and browse the elements neatly and in a standard way.
This article
presents an example from a real project, I have been involved in. I used
the tree data structure to model a recursive relation of goal entity. A
tool was developed to create and analyse abstract algorithms composed of
goals that can be refined to sub goals. Thus, the main issue was to represent
the goals that possess super-sub relationship. I adapted the JTree component
to display the entire goal tree and therefore, the user can access the
different goals, collapse or expand them in the standard way as dealing
with the directories and files in most of the operating systems.
I will focus
on the work related to the JTree and the DefaultMutableTreeNode classes
assuming that the other work is straightforward. The application creates
trees of goals and enables the user to expand these trees, create new trees,
delete trees, edit tree details, move the goals within the trees, copy,
paste, cut, and add new goals. Moreover, the cells of the JTree have been
rendered to reflect the type of the goals that they contain. Besides, the
other classes and their methods are documented with comments to provide
enough explanation for the JBuilder progammers. The application is composed
of the following classes:
| Class |
type |
Brief Descrpition |
| Deasktop |
Desktop frame |
this class represents the desktop
window that contains the goal trees and the goal tree index. |
| goaltest |
Data |
this is the class of the individual
objects contained in each tree cell. The different values of the goal attributes
affect the appearance of the JTree cells. |
| GoalModelFrame |
Internal frame |
this class is the window for each
goal tree. This is basically an internal frame that can be maximized, minimized,
moved, or iconised within the desktop. |
| goalmodel |
Data |
this class has the attributed related
to goal tree as a whole, such as goal tree name and description function
of the tree. |
| GModelFrame |
Internal Frame |
this represents an internal frame
within the desktop space that contains a list of the goal tree within a
JList component. This frame can be used as a fast accessing criteria to
access/edit/delete the goal trees. |
| EditGoalModelDialog |
Dialogue Box |
this is a dialogue box enabling
the user to update the information of each goal (tree cell individually) |
| NewGoalModelDialog |
Dialogue Box |
this dialogue box enables the user
to edit the details of each goal tree. The user can change the default
goal tree name as well as the description. |
| NewGoalDialog |
Dialogue box |
this is a dialog box enabling the
user to create a new goal tree and hence add it to the list of the goal
trees. |
| ExampleFileFilter |
Data |
this is used to add filters when
saving and loading the goal trees. |
| SampleTreeCellRender |
Data |
this is a basic class to
show how to render the JTree cells and change the way they look when they
are collapsed and expanded. |
| GoalModelListModel |
Data |
this class extends AbstractListModel
class and contains the information about each goal tree within the application.
Also this class is the JList interface in the goal tree frame; so to add
or delete a goal tree, this class needs to be accessed first. The list
can be update using fireContentsChanged() method. |
It is more
important to stress on the important issues related to the goal trees.
In addition to adapting and utilizing of the JTree and DefaultMutableTreeNode
classes. One of the keypoint in representing the goals was the separation
between the goal attribues which are stroed within goaltest objects and
the links ( reference to child goals and parent goal) which is already
defined in DefualtMutableTreeNode.
Figure 1, the desktop of the application
showing the JTree components after rendering them.
Figure 1 shows
the desktop of the application with different goal tree frames and the
goal trees list frame. You can notice the different appearance of the goals.
The following are some of the importnat
issues that can be considered when adapting JTree components.
Rendering the shape of the tree
cells
Each of the
tree cells can be rendered in way that affects the displayed text, the
icons displayed, the selection color, background color and foreground color.
Changing the default icons
As already
pointed out each JTree Cell is an object of the type JLabel which has icon
that can represent the current goal refinement type. I have created two
sets of icons for the collapsed and expanded states as well as an icon
when the node is leaf to represent the terminal goals.
Writing listeners for selection
change
It will be
important to provide small details for the goals when the user browses
them and moves down or up; this can be achieved through setting a listener
for the tree selection change (each time the selection change the node
information is retrieved and the text of the label in the frame is set
to the goal description)
Adding a new goal tree
Within, the
goal tree fame, user can add new internal frame representing the different
goal trees. Using a pop up menu that can be activated by right click on
the goal tree frame, user can select add new goal tree (model) and a dialogue
box similar to the one shown in figure 2 will be displayed, after the user
clicks ok a new internal frame will be created containing a single root
goal with the same name as the goal tree name.
Figure 2, the new Goal Tree Dialogue
Box
Editing goal trees
The goal tree
frame allow the user to change the goal tree names and descriptions through
using the pop up menu and selecting Edit Goal Tree; A Dialogue box similar
to one displayed in figure 2 will appear to enable the user change the
information.
Adding new goals
When creating
a new goal, a new node of the type DefaultMutableTreeNode will be created
and placed within the structure of the tree; this will happen by adding
it to the model of the JTree component. And then, a new object of type
goaltest will be created with default values to represent the new goal
within the goal tree.
Moving the goals up and down
The goals
can be moved up and down simply by cutting the node from one place and
place it again in the new place. User needs to be careful when calculating
the new place after removing the node to be removed.
Copying/ deleting / pasting the
goals
Goal trees
and sub trees can be copied and pasted within the desktop space this has
been achieved by creating global variable for the desktop frame that can
be used to pass the goal trees or sub trees from one goal tree frame to
another.
When pasting the goals two issues can be noticed:
The user usually needs to create a new copy of the sub
tree rather than copy the pointer; since the nodes of the type DefualtMutableTreeNode
are basically pointers as the other object reference in Java, we had to
produce a second copy of the selected tree or sub tree. Method copyTree()
is used for this propose.
When pasting the tree to a goal there can be different
situation the user may need to overwrite the goal by the copied tree or
add the copied tree as a child tree, add the copied tree as a predecessor
to the current selected goal. I chose two options: either paste as a new
child or paste into which replace the existing goal.
Editing the goals
Goals can
be edited by selecting their goal tree frame then selecting them from within
the JTree components; when editing a goal first the selected node within
the tree needs to be identified then the user object of this node which
contains the goal details can be retrieved after editing the goal a new
goal object can be set as the userObject of the selected node.
Figure 3, editing the selected
goal attributes
Saving the goal tree
Saving the goal model trees to the file is important to retrieve them later.
Basically, For each goal model we save the entire attributes that describe
the entire tree first like goal tree name and description and then save
the goals, then save the tree elements in a pre order manner, in which
the root node details is saved followed by details of its sub nodes; since
the node itself will not be saved we have to save the number of child nodes
in order to retrieve exact number of goal trees. The writing to text file
operation is achieved by invoking a goaltest method called write than can
be useful in achieving a level of separation between the goal object and
goal tree; this separation can make it possible to change the container
goal model or the contents the goals easily with less impacts.
Loading the goal tree
Loading the goal trees is straightforward. The attributes of each entire
goal tree is read first followed by depth first retrieval and construction
of the tree by first reading the main goal, creating a container node for
the main goal, reading the number of sub goals, reading these goals and
creating nodes containing them. Linking the node of the main goal to the
nodes of the sub goals using add function.
Expanding the trees
This utility
makes the user life much easier especially, in those applications where
the user needs to see the entire JTree expanded. The JTree component has
a method that can expand a single row. Thus, starting from this point we
implemented a while loop to expand each row that is collapsed; after expanding
a previously collapsed node the child nodes are checked to expand them
in turn. The programmer should notice that after the tree expanded one
of its nodes the row indices would be different.
In conclusion,
the JTree Component can be utilized nicely to fulfill the programmer needs.
Although in this application all the tree cells are of the same type (goaltest),
the objects contained within the tree do not have to be homogenous; But,
if the tree cells contain objects from different classes, the programmer
needs to modify the rendering class so that it detects the object class
and hence provide the suitable rendering.
Islam A. El-Maddah
islam-elmaddah@ieee.org
|
|
Connect with Us