Search
Components and XML

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.

Definition

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  Copy Code

<SimplePanel>

  <Shape Name="Shape" Shape="Rectangle" />

  <Border Padding="2">
    <GridPanel>
      <GridPanel.Columns>
        <GridColumn Width="30" />
        <GridColumn />
      </GridPanel.Columns>
      <GridPanel.Rows>
        <GridRow />
      </GridPanel.Rows>

      <Image Name="Image" ImageAlign="Fit" />

      <StackPanel Orientation="Vertical" GridColumn="1">
        <Text Name="Title" Font="Arial, 12pt, style=Bold" TextAlignment="Near" />
        <Text Name="FullName" TextColor="Blue" TextAlignment="Near" />
        <Text Name="Text" Font="Arial, 8pt" TextAlignment="Near" />
      </StackPanel>
    </GridPanel>
  </Border>

</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

BorderComponent

Border

ButtonComponent

Button

CheckBoxComponent

CheckBox

EditComponent

Edit

ImageComponent

Image

ShapeComponent

Shape

TextComponent

Text

NumericEditComponent

NumericEdit

SliderComponent

Slider

SpinnerComponent

Spinner

The components can also be defined using their full names.

Composite Properties

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  Copy Code

<ComponentName>
  <ComponentName.PropertyName>
    <PropertyValue />
  </ComponentName.PropertyName>
</Component>

For example, to define Content of a ButtonComponent, you can use the following syntax:

XML  Copy Code

<Button>
  <Button.Content>
    <Text Text="Hello world!" />
  </Button.Content>
</Button>

Images

Images can be defined in XML using Bitmap objects and string paths. Here is an example:

XML  Copy Code

<Image>
  <Image.Image>
    <Bitmap>Images/MyImage.png</Bitmap>
  </Image.Image>
</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.

Shapes

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  Copy Code

<StackPanel Spacing="1">
  <Shape Shape="Ellipse" Width="6" Height="6" Pen="Red" Brush="Yellow" />
  <Shape Shape="M0,30 L50,30 L50,0 L100,50 L50,100 L50,70 L0,70 z" Width="6" Height="6" Pen="Green" Brush="LimeGreen" />
</StackPanel>

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.

Loading XML

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#  Copy Code

CompositeNode node = new CompositeNode();
node.getComponents().add(XmlLoader.load("<Edit Text=\"Some text\" />"));

Handling Events

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  Copy Code

<StackPanel Orientation="Vertical" GridColumn="1">
    <Button Name="Button" Width="10" Height="10"/>
    <Edit Name="Edit" Width="50" Height="30"/>
</StackPanel>

Java  Copy Code

ButtonComponent button = (ButtonComponent)node.findComponent("Button");
button.addComponentMouseEventListener(
    new ComponentMouseEventAdapter()
    {
        @Override
        public void mouseClicked(Object sender, ComponentMouseEvent e)
        {
            EditComponent edit = (EditComponent)node.findComponent("Edit");
            edit.setText("click");
        }
    });

Resolving Types

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.

Error Handling

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.