Skip to content

CodeRADViews

Steve Hannah edited this page Jun 30, 2021 · 9 revisions

CodeRAD Views

CodeRAD views are written using XML, and are converted into Java classes by the CodeRAD annotation processor. View XML files are placed in the common/src/main/rad/views directory of a Codename One Maven project, following the standard Java rules for package hierarchy.

E.g. To create a view "MyView" in the "com.example.views", package, you would create a file named "MyView.xml" inside the common/src/main/rad/views/com/example/views directory. This view will automatically be converted into a Java View class (i.e. extending AbstractEntityView) by the CodeRAD annotation processor whenever the project is compiled.

AnnotationProcessorDiagram
Figure 1. The view MyView.xml is processed by the CodeRAD annotation processor, generating a View, a Model, and a Controller class.

Hello World

A very basic "Hello World" view would look like:

<?xml version="1.0"?>
<y> (1)
    <title>Hello World</title> (2)
    <label>Hello World</label> (3)
</y>
  1. Creates a Container with BoxLayout.Y layout.

  2. Sets the title of the form to "Hello World", if this view is used as the main content of a Form.

  3. Places a Label with text "Hello World" on the form.

Suppose this view is in the file com/example/views/MyView.xml (inside the common/src/main/rad/views directory), then, when you build the project, the CodeRAD annotation processor will process it and convert it into 3 Java classes:

MyView

A View class extending com.codename1.rad.ui.entityviews.AbstractEntityView.

MyViewController

A FormController that can be used for displaying this view in a Form.

MyViewModel

A CodeRAD model that is used for the view’s model. In this case, the view didn’t include any <define-tag> tags, so the model would not contain any properties. Note that the annotation processor would further generate two concrete implementations of MyViewModel: MyViewModelImpl, and MyViewModelWrapper. See Models for more information about these.

If you wanted to display this view from Java code you could use the MyViewController class as follows:

new MyViewController(parentController).show();
Note
The parentController reference we pass to the MyViewController constructor can either be the Application controller instance, if the form should be "top-level" and include no back button, or another FormController that will be treated as the form’s parent. See Controllers for more details about the Controller hierarchy.
ViewAnnotationProcessorFlow
Figure 2. More detailed visualization of how the CodeRAD annotation processor processes View XML files.

View Syntax

With CodeRAD XML, you have access to any Component in the your app’s classpath. To create a component, just add a tag with its simple classname. E.g. To create a TextField component, you could use the <textField> tag.

Tip
Tag names are case-insensitive, though the convention is to use camel-case with the first character in lower case.

Component Properties

Component properties are set using XML tag attributes and Java bean naming conventions. E.g. If the component class has a single-arg method named "setName()", then we say that the component has a "name" property, and it can be specified in XML by setting the "name" attribute.

e.g.

<textField name="UsernameField"/>

is roughly equivalent to the Java:

TextField textField = new TextField();
textField.setName("UsernameField");

Setting "Sub"-Properties

When creating components, sometimes you need to set properties of "sub"-components. For example, you might be wondering how to do the following in XML:

// Set foreground color to red
textField.getStyle().setFgColor(0xff0000);

The equivalent XML of this is:

<textField style.fgColor="0xff0000"/>
Tip
Sub-properties are set with null-safety, so that if an intermediate part for the chain is null, it will fail silently. E.g. With the style.fgColor example, if getStyle() was null, then it wouldn’t set the fgColor, but it also wouldn’t throw a NullPointerException. It would check that the style is non-null first, before calling setFgColor() on it.

Attribute Values

Attribute values will either be interpreted as String literals, or a Java expressions, depending on the property type. You can provide an optional prefix to explicitly declare that the value should be interpreted in a different way than the default. E.g. The "string:" prefix explicitly tells the processor to treat the value as a string literal. The "java:" prefix will cause it to interpreted as a Java expression.

For attributes of type java.lang.String, the default interpretation is as a string literal. For all other attributes, the default interpretation is as a Java expression.

To continue the above TextField example, name="MyTextField" translates to tf.setName("MyTextField"), meaning that it iterpreted "MyTextField" as a string literal - because the setName() method parameter type is a java.lang.String.

The style.fgColor="0xff0000" attribute is interpreted as a Java expression because setFgColor() takes an int as an argument.

Some Examples:

Assume these attributes are added to the <textField> tag (in the XML column) and called on the TextField class (in the Java column).

XML Java

name="SomeName"

setName("SomeName")

name="string:SomeName"

setName("SomeName")

name="java:SomeName"

setName(SomeName)

preferredH="100"

setPreferredH(100)

preferredH="java:100"

setPreferredH(100)

preferredH="string:100"

setPreferredH("100") → Will result in compile error since setPreferredH() requires an int.

The above examples all involved single values, but, when the value is interpreted as a Java expression, you can use any valid Java expression.

E.g.

<textField preferredW="CN.getDisplayWidth()/2"/>

is perfectly fine, and will set the preferredW property to half the display width.

Scalar Units for int attributes

When setting an "int" property, you can specify the value with one of the following units, and it will automatically convert the value to the appropriate number of pixels at runtime.

Some examples using units to set the preferredW property.

XML Description

preferredW="50vw"

50 percent of the display width in pixels.

preferredW="50vh"

50 percent of the dislay height in pixels.

style.paddingTop="1rem"

Padding top set to default font’s line height in pixels.

style.marginBottom="2mm"

Bottom margin set to 2 millimeters.

style.marginBottom="2"

Bottom margin set to 2 pixels.

Enum Literals for Enum Attributes

When setting the value of an enum property, you can simply specify enum value you want to set.

For example, suppose you have:

// An enum definition
public enum Color {
    Red,
    Green,
    Blue
}

// A Component that has a Color property:
public class MyComponent extends Component {
    /// ...

    public void setColor(Color color) {
        //...
    }
}

Then you could do the following in your XML view:

<myComponent color="Red"/>

And this would be equivalent to the Java:

MyComponent cmp = new MyComponent();
cmp.setColor(Color.Red);

"http://.." URLs for Image attributes

When setting an com.codename1.ui.Image property, you can specify the attribute value as an http://.. URL, in which case it will set the property to an instance of URLImage that loads the image at that URL. When doing this, you can also append properties to the URL after a space, to set things like the image width, height, aspect ratio, and fill options.

Examples:

<!-- Image with width 90% of screen width, and 1:1 aspect ratio -->
<label icon="https://example.com/myimage.png width:90vw; aspect:1.0"/>

<!-- Image with a circle mask, and width 50% of screen width -->
<label icon="https://example.com/myimage.png mask:circle;width:50vw"/>

<!-- Image with roundrect mask, and 50% of screen width -->
<label icon="https://example.com/myimage.png mask:roundrect;width:50vw"/>

<!-- Image loaded from resources (via jar:// url) With circle
    mask, 50% width, and scaled to fill the images bounds -->
<label icon="jar:///chromebook.jpg width:50vw; scale:fill; mask:circle"/>

Image Settings

When using "http://" URLs to specify an image, you can provide the following settings along with the URL as key-value pairs, as shown in the above examples. The possible settings are:

width

The width of the placeholder image. Can be specified in scalar units such as vh, vw, vmin, vmax, rem, and mm.

height

The height of the placeholder image. Can be specified in scalar units such as vh, vw, vmin, vmax, rem, and mm.

aspect

The aspect ratio of the placeholder image. A double value representing the w:h aspect ratio.

scale

The scale settings for the image. Possible values include none, fit, and fill.

mask

The mask settings for the image (whether to apply a mask). Possible values are circle, roundrect, and none.

String[] attributes with csv: prefix

When setting properties of type String[], you can provide the attribute value as a comma-delimited list of strings if you prefix it with "csv:".

E.g.

<label>Pick a color</label>
<picker strings="csv:Red, Green, Blue" />

This would be equivalent to the Java:

Picker cmp = new Picker();
cmp.setStrings(new String[]{"Red", "Green", "Blue"});

The View Model

In order to realize the full potential of CodeRAD views, you need to bind the view to a view model. A view model is automatically generated for each view by the annotation processor, but by default, the model doesn’t contain any properties. You can add properties to the view model via the <define-tag> tag, which will define a "Tag", and create a property in the view model with this tag. You can then bind UI elements to this tag.

MVC SequenceDiagram

Clone this wiki locally