NonJavaBeans example: abstract model variant
Describes how to display a set of Java™ objects that are not JavaBeans™ by subclassing the abstract class
IlvAbstractSDMModel.
Presents an example that displays the contents of a Swing JTree object as a graph.
Explains how to create a Swing JTree object.
Describes how to write a data model that transforms the tree data into an SDM model.
Describes the
TreeSDMNode class, which represents the nodes of the graph.
Describes the
TreeSDMLink class, which represents the links of the graph.
Shows how to load the data model and style sheet into the diagram component.
The Tree Model example
The Tree Model example displays the contents of a Swing JTree object as a graph. The nodes of the graph are the items in the tree (also called tree nodes), and the links of the graph represent the parent-child relationships between the items., see the following figure.
The Tree Model example: Swing JTree
This example uses the base class
IlvAbstractSDMModel and implements nodes and links using the
IlvSDMNode and
IlvSDMLink interfaces, for the following reasons:
The nodes to be represented (the tree nodes) are existing Java™ objects, but they are not JavaBeans™.
The links do not exist as Java objects; you need to create them.
The example is supplied with Rogue Wave® JViews Diagrammer in the directory
<installdir>/jviews-diagrammer/codefragments/datamodel/treemodel.
The Swing JTree
The data to be displayed is the contents of a Swing JTree. The example simply uses the contents of a default JTree, which contains names of various colors, sports and food. You create the JTree object as shown in the following code example.
TreeModel treeModel = new JTree().getModel();
The TreeSDMModel class
To display the data model of a tree in a diagram component, you must write a data model that transforms the tree data into an SDM model. In this example, the model is implemented by the class
TreeSDMModel, which is a subclass of
IlvAbstractSDMModel. Its definition is as shown in the following code example.
public class TreeSDMModel extends IlvAbstractSDMModel
{
...
Root of the tree
The nodes of the graph will be represented by instances of a class TreeSDMNode. The TreeSDMModel class creates a node that represents the root of the tree, and keeps a reference to it as shown in the following code example.
private TreeSDMNode root;
public TreeSDMModel(TreeModel treeModel)
{
root = new TreeSDMNode(treeModel, null, treeModel.getRoot());
}
When asked to return the top-level objects of the graph, the getObjects method just returns a single element: the root of the tree, as shown in the following code example.
public Enumeration getObjects()
{
Vector v = new Vector();
v.addElement(root);
return v.elements();
}
Model is not editable
The clear method must be implemented, but it will never be called since the TreeSDMModel class in this example represents a model that is not editable. The following code example shows the method implementation.
public void clear()
{
// Nothing, this model is immutable.
}
}
The TreeSDMNode class
The class TreeSDMNode represents the nodes of the graph. Its definition is as shown in the following code example.
public class TreeSDMNode implements IlvSDMNode
{
Data stored
Each node in the graph (graphic object) has a reference to the corresponding node in the tree (model object). References to the parent node (graphic object) and the tree model are also needed. The children of the node are stored in a vector.
Keeping track of the data: current node, parent, children, and model
private TreeSDMNode parent;
private TreeModel treeModel;
private Object treeNode;
private Vector children;
public TreeSDMNode(TreeModel treeModel, TreeSDMNode parent, Object treeNode)
{
this.parent = parent;
this.treeModel = treeModel;
this.treeNode = treeNode;
createChildren();
}
Children vector
Note that the constructor calls the method createChildren. This method traverses the tree model and creates a TreeSDMNode instance for each item in the tree. In addition, it creates an instance of TreeSDMLink to draw a link between the parent node and each child node.
Creating the child nodes and links (graphic objects)
private void createChildren()
{
children = new Vector();
// scan all the children of the root tree node, and create
// a TreeSDMNode for each:
//
int count = treeModel.getChildCount(treeNode);
for(int i = 0; i < count; i++){
Object childTreeNode = treeModel.getChild(treeNode, i);
// Create the TreeSDMNode. Note that this will recursively create
// the SDM nodes for all sub-nodes.
//
TreeSDMNode childSDMNode = new TreeSDMNode(treeModel, this, childTreeNode);
children.addElement(childSDMNode);
// Create a parent/child link:
//
TreeSDMLink childSDMLink = new TreeSDMLink(this, childSDMNode);
children.addElement(childSDMLink);
}
}
Implementation of the IlvSDMNode interface
The following methods are the implementations of the methods belonging to the
IlvSDMNode interface, which are inherited by
TreeSDMNode.
The getTag method returns the type (or “tag”) of the node. In this example, the type is treenode.
Retrieving the node type: the getTag method
public String getTag()
{
return "treenode";
}
The getID method returns the identifier of the node. The identifier of a node is its hash code.
Retrieving the node ID: the getID method
public String getID()
{
return String.valueOf(hashCode());
}
The getChildren method returns the children of the node, which are stored in the children data member.
Retrieving the child objects: the getChildren method
public Enumeration getChildren()
{
return children.elements();
}
The getParent method returns the parent node of the current node.
Retrieving the parent object: the getParent method
public IlvSDMNode getParent()
{
return parent;
}
The getProperty and getPropertyNames methods must be implemented to give the diagram component access to the properties of the node. In this example, there is support for two properties, userObject and CSSclass:
The
userObject property returns the sample food, color, and sports names.
The
CSSclass property returns the type of item:
food,
color, or
sport.
Retrieving a property: the getProperty method
public Object getProperty(String property)
{
if(treeNode instanceof DefaultMutableTreeNode){
if(property.equals("userObject")){
return ((DefaultMutableTreeNode)treeNode).getUserObject();
}
if(property.equals("CSSclass") && ((DefaultMutableTreeNode)treeNode).getParent() != null){
return ((DefaultMutableTreeNode)((DefaultMutableTreeNode)treeNode).getParent()).getUserObject();
}
}
return null;
}
The getPropertyNames method retrieves the two property names.
Retrieving property names: the getPropertyNames method
public String[] getPropertyNames()
{
if(treeNode instanceof DefaultMutableTreeNode)
return new String[] { "userObject", "CSSclass" };
else
return new String[0];
}
The TreeSDMLink class
The class TreeSDMLink represents the links of the graph. Its definition is as shown in the following code example.
public class TreeSDMLink implements IlvSDMLink
{
...
The link implementation can therefore make use of all the predefined methods of the
IlvSDMLink interface.
Data Stored
Each link has a reference to a parent node and a child node, which can be retrieved using the
getFrom and
getTo methods, see the following code example.
Keeping track of link data: parent and child
private TreeSDMNode parent, child;
public TreeSDMLink(TreeSDMNode parent, TreeSDMNode child)
{
this.parent = parent;
this.child = child;
}
public IlvSDMNode getFrom()
{
return parent;
}
public IlvSDMNode getTo()
{
return child;
}
Implementation of the IlvSDMNode interface
The
IlvSDMLink interface inherits from the
IlvSDMNode interface and so the same methods must be implemented as for a node.
The tag (type) of links is treelink. and this value can be retrieved using the getTag method, see the following code example.
public String getTag()
{
return "treelink";
}
The remaining methods are mostly empty, since in this example links have no properties.
Loading the data model and style sheet into the diagram component
The Tree Model sample is a subclass of
IlvDiagrammerApplication. It therefore has the full application facilities as described in
Customizing the predefined application.
The Data model
To load the
TreeSDMModel object, the sample overrides the
createDiagrammer method to perform extra operations, see the following code example.
protected IlvDiagrammer createDiagrammer()
{
// Create a default tree model. The JTree creates one
// if you don't specify a model: let's use it.
//
TreeModel treeModel = new JTree().getModel();
// Create the IlvDiagrammer instance.
//
IlvDiagrammer diagrammer = super.createDiagrammer();
// Create a default tree model. The JTree creates one
The sample creates an instance of TreeSDMModel, giving it a default tree model as a parameter, see the following code example.
// Create the Tree -> SDM model adapter.
//
TreeSDMModel sdmModel = new TreeSDMModel(treeModel);
The sample then gets the SDM engine for the
IlvDiagrammer instance and sets the data model to the
TreeSDMModel instance, as shown in the following code example.
// Tell the IlvDiagrammer to use this model:
//
diagrammer.getEngine().setModel(sdmModel);
return diagrammer;
}
The style sheet
To load the style sheet, you pass the relative path to the sample as a startup argument.
public TreeModelDemo()
{
super(new String[]{
"-title", "Tree Model Demo",
"-style", "data/tree.css",
});
}
The style sheet specifies a Tree layout in Radial mode with various parameters, in the two rules shown in the following code example.
SDM {
GraphLayout : "Tree";
}
GraphLayout {
flowDirection : "Bottom";
layoutMode : "RADIAL";
globalLinkStyle : "ORTHOGONAL_STYLE";
position : "300,200";
parentChildOffset : "10";
siblingOffset : "10";
}
The style sheet also specifies the colors of the various objects.
Note that the
CSSclass property of the
TreeSDMNode class is recognized automatically by the CSS engine as specifying a
CSS class because of its name, and therefore the values of this attribute can be used directly in rules. This allows you to set colors at the level of types of object with a simple syntax, see the following code example.
node.food {
fillColor2 : "lightgreen";
}
// node.treenode[userObject='food'] node.treenode {
// fillColor2 : "lightgreen";
// }
The comment lines show the alternative, longer way to set the color for food objects. This longer way relies on a parent-child construct in
CSS for Java. Note that the parent-child construct is not supported in the Designer.
Copyright © 2018, Rogue Wave Software, Inc. All Rights Reserved.