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


Server Response from: SC3