-
Notifications
You must be signed in to change notification settings - Fork 17
CodeRADViews
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.
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>-
Creates a Container with
BoxLayout.Ylayout. -
Sets the title of the form to "Hello World", if this view is used as the main content of a Form.
-
Places a
Labelwith 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
FormControllerthat 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 ofMyViewModel:MyViewModelImpl, andMyViewModelWrapper. 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.
|
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 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");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 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 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
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.
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 |
|---|---|
|
50 percent of the display width in pixels. |
|
50 percent of the dislay height in pixels. |
|
Padding top set to default font’s line height in pixels. |
|
Bottom margin set to 2 millimeters. |
|
Bottom margin set to 2 pixels. |
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);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"/>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, andmm. - height
-
The height of the placeholder image. Can be specified in scalar units such as
vh,vw,vmin,vmax,rem, andmm. - aspect
-
The aspect ratio of the placeholder image. A double value representing the
w:haspect ratio. - scale
-
The scale settings for the image. Possible values include
none,fit, andfill. - mask
-
The mask settings for the image (whether to apply a mask). Possible values are
circle,roundrect, andnone.
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"});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.