As mentioned in my previous article, the IoC container for Flash supports two XML dialects: a simple one to wire up business objects, and another less verbose one to build user interfaces (with any user interface framework or component library, including in-house ones, that follow some common coding practices).
Following is the ErrorWindow.xml from the As2lib Chat sample application:
-
<beans xmlns:chat="org.as2lib.sample.chat" xmlns:aw="org.aswing">
-
-
<chat:ErrorWindow id="errorWindow" style="window">
-
<messageLabel>r{messageLabel}</messageLabel>
-
<aw:JPanel style="title">
-
<aw:JLabel>{messageSource.message[title.error]}</aw:JLabel>
-
</aw:JPanel>
-
<aw:Container style="content">
-
<aw:JLabel id="messageLabel"/>
-
<aw:JButton actionListener="d{errorWindow.hide}">
-
<text>{messageSource.message[button.ok]}</text>
-
</aw:JButton>
-
</aw:Container>
-
</chat:ErrorWindow>
-
-
</beans>
Namespaces are declared for packages that contain needed components: namespace ‘chat’ is mapped to package ‘org.as2lib.sample.chat’ and ‘aw’ to ‘org.aswing’.
Beans can now be declared as elements with one of the declared namespaces and the class name as local name: <chat:ErrorWindow …/> or <aw:JPanel …/>
Properties can either be elements with the element name as property name (<messageLabel>…</messageLabel>) or attributes (actionListener=”…”).
Note that there are some reserved attributes like ‘id’, ’style’ and ‘class’. If a property has the name of one of these reserved attributes, it must be declared with an element.
You may have noticed that not all inner bean definitions are wrapped by a property element. For example the ‘JLabel’ and ‘JButton’ beans inside the ‘Container’ bean. So to which property of the ‘Container’ bean are they set? To the default property! If you parse the ErrorWindow.xml with the ‘AsWingBeanDefinitionParser’ the default property is ‘append’ which fits most needs. If you just use the ‘UiBeanDefinitionParser’ there is no default property, but you may specify it with the ‘default-property’ attribute in the root element as global default-property and/or in any bean definition as local default-property.
Property values with one of the following patterns are interpreted in a special way:
* p{} or {} is a property get access: {messageSource.message[title.error]} is interpreted as messageSource.getMessage(”title.error”)
* r{} is a bean reference: r{messageLabel}
* d{} creates a delegate: d{errorWindow.hide}
* v{} retrieves a variable: v{org.aswing.WindowLayout.TITLE}
* m{} invokes a method
The reserved ’style’ attribute maps a bean definition to a style class in a style sheet. Here’s an excerpt from the style.css file of the As2lib Chat (how it is loaded was shortly mentioned in the previous article):
-
@namespace {
-
aw: org.aswing;
-
ab: org.aswing.border;
-
}
-
.window {
-
x: 200;
-
y: 150;
-
width: 400;
-
height: 110;
-
resizable: false;
-
modal: true;
-
}
-
.window .content {
-
layout: aw|SoftBoxLayout(axis=v[org.aswing.SoftBoxLayout.Y_AXIS], gap=5);
-
border: ab|EmptyBorder(insets=aw|Insets(5, 5, 5, 5));
-
}
-
.window .content JPanel {
-
layout: aw|SoftBoxLayout(axis=v[org.aswing.SoftBoxLayout.X_AXIS], gap=5);
-
}
The ‘.window’ style class is quite simple. It just declares the position and size and whether the window is resizable and modal.
The ‘.content’ style class is a little more complex. It declares the layout and border of the window’s content, which are both instances in AsWing.
A bean (instance) can be declared with a namespace to specify the package (optional) and a class name followed by left and right parenthesis: aw|SoftBoxLayout(…). Between the parenthesis are either constructor argument or property definitions separated by commas: aw|Insets(5, 5, 5, 5) or aw|SoftBoxLayout(axis=v[org.aswing.SoftBoxLayout.Y_AXIS], gap=5) respectively. Constructor argument definitions are simple values; property definitions consist of the property name followed by ‘=’ and the property value.
As you can see in the property definition example, it is also possible to retrieve constants: v[org.aswing.SoftBoxLayout.Y_AXIS]
Applications mostly have multiple screens and windows. Defining all these in a single file would be unmaintainable. Every screen and window is normally defined in its own file. For example the error window is needed by the chat screen to show errors to the users. The chat screen can import the error window as follows:
-
<beans … xmlns="*.xml">
-
-
<chat:Chat id="chat" init-method="init" style="frame">
-
<errorWindow>r{errorWindow}</errorWindow>
-
…
-
</chat:Chat>
-
-
…
-
-
<ErrorWindow id="errorWindow" class="org.as2lib.context.support.AsWingApplicationContext"/>
-
-
</beans>
Declare a namespace for importing external definitions: xmlns=”*.xml”
Declare an imported bean as any other bean with the import namespace and the file name, and the class of the context which shall manage the imported bean: <ErrorWindow id=”errorWindow” class=”org.as2lib.context.support.AsWingApplicationContext”/>
You can give the imported bean an ‘id’ to reference it: <errorWindow>r{errorWindow}</errorWindow>
You may also declare properties for the imported bean: <Chat width=”800″ height=”600″ visible=”true” …/>
The use cases explained above are the most common ones; they probably fit 90% of all needs. I’m going to explain more special use cases in the next article.
Download the As2lib Chat sample application with all needed libraries: As2lib Chat
