As described in the Using Components topic, to use components in JDiagram you need to instantiate them and add them to the Components collection of a CompositeNode. JDiagram provides a more convenient method for defining component hierarchies - through XML.
Each node in the source XML represents a component or an object. The child nodes in the XML represent child components. The XML attributes represent either property assignments or event handler attachments. A simple component hierarchy defined in XML is illustrated below:
XML
![]() |
---|
<SimplePanel> |
Because the XML documents have a single root, the component hierarchies defined through XML can have a single root too. In the case when a hierarchy needs to have more than one root each root can be defined in its own XML or all the root components can be grouped under a single component container.
As is observed in the sample above the components can be specified through shortcut names. The following table lists all available shortcuts:
Component | Shortcut Name |
---|---|
Border | |
Button | |
CheckBox | |
Edit | |
Image | |
Shape | |
Text | |
NumericEdit | |
Slider | |
Spinner |
The components can also be defined using their full names.
Some properties have too complex values and cannot be represented with attributes. Consider for example the collection properties, such as the Columns and Rows properties of the GridPanel. These properties can be defined as child nodes using the specialized syntax illustrated below:
XML
![]() |
---|
<ComponentName> |
For example, to define Content of a ButtonComponent, you can use the following syntax:
XML
![]() |
---|
<Button> |
Images can be defined in XML using Bitmap objects and string paths. Here is an example:
XML
![]() |
---|
<Image> |
In the example above "Images/MyImage.png" will be interpreted as an image path and the loader will attempt to create a new java.awt.Image instance by passing the file path to the Toolkit.getImage method.
The Shape of shape components can be defined in XML by either specifying the name of a predefined shape or by using the specialized syntax for graphical paths. The example below defines two ShapeComponent instances in a StackPanel. The first shape component uses the predefined Ellipse shape and the second uses a custom arrow shape:
XML
![]() |
---|
<StackPanel Spacing="1"> |
The specialized graphical path syntax supports the following subset of operations:
Command | Description |
---|---|
MX,Y | Moves to point (X, Y). |
LX,Y | Draws a line from the current point to point (X, Y). |
CX1,Y1 X2,Y2 X3,Y3 | Draws a curve from the current point to (X3, Y3) using points (X1, Y1) and (X2, Y2) as control points. |
AW,H R A D X,Y | Draws an arc with size (W, H) using rotation R and an end point (X, Y). A specifies whether to draw the large arc (1 - large arc, 0 - small arc) and D specifies direction - (1 - positive angle, 0 - negative). |
z | Closes the figure. |
Component hierarchies defined in XML can be loaded using the XmlLoader class. The class provides several static load method overloads for loading XML from different sources - a content string, Stream or XML Document. Each of the Load methods returns a ComponentBase representing the root of the loaded hierarchy. This component can then be added to a CompositeNode or as a child of another component. The following example illustrates how to use the XmlLoader:
C#
![]() |
---|
CompositeNode node = new CompositeNode(); |
Unlike MindFusion.Diagramming libraries for other platforms, Java version cannot attach handlers to events by names specified in XML. Instead, you will have to add an event listener explicitly after loading a template:
XML
![]() |
---|
<StackPanel Orientation="Vertical" GridColumn="1"> |
Java
![]() |
---|
ButtonComponent button = (ButtonComponent)node.findComponent("Button"); |
The XmlLoader is capable of resolving external (non-component) types found in the source XML by calling Class.forName. However, this can be slow in certain scenarios. In addition certain types might not resolve properly because the loader always uses the first type that matches the specified name regardless of namespace. For these reasons, the XmlLoader provides means to manually resolve external types. In order to take advantage of this, you have to implement the TypeResolver interface and pass an instance of your class to the corresponding load overload. For any external type found, the loader will invoke the resolveType method. If the method returns null the loader will attempt to resolve the type using its default logic.
It is not unusual for the XmlLoader to throw an exception when loading components from XML. There are many reasons for this to happen, including ill-formatted XML. Therefore it is recommended to always try and catch exceptions when loading components from XML.