Other projects
-
Tutorial 5 : Dynamic Data Display
- Requirement
-
Display dynamic data
- Create a custom Data Provider
- Create a new frame and a new screen to handle user actions and display data.
- Set the content for the new screen in the XML file
- Implement the user actions
- Add the translation labels to the messages.properties
- Add action to pass from HelloWorld screen to dynamic screen
- Using the data provider to update a radio group value
- Screenshot
Tutorial 5 : Dynamic Data Display
Requirement
Please read the Tutorial 4 first.
Display dynamic data
In the last section of this HelloWorld Tutorial we will point out the capabilities of Kuix to dynamicaly display data. We are going to display two kind of information : a runtime value - a value read at runtime like the device platform name - and a runtime dynamic value - like a variable for instance.
In a second time, we are going to use the variable to set the value of a radio group.
Download this tutorial step.
Create a custom Data Provider
The data provider is a special object that inherits from the org.kalmeo.kuix.core.model.DataProvider class and so, has the ability to provide the Kuix Core engine with dynamic values: it works like an "unidirectional bind" between a reference (ie. an alias) an the value.
In this example, we will create a data provider for 2 dynamic data. One called platformName with the device platform name detected by Kuix, and another one with a variable called gender.
To customize our Data Provider, we need to override at least the getValue() method. In addition, we will create an accessor to set the gender value. Hereafter is the code suggested for the implementation.
public class DynamicDataProvider extends DataProvider {
// Declare static values to identify the provided data
private static final String PLATFORM_NAME_PROPERTY = "platformName";
private static final String GENDER_PROPERTY = "gender";
// create a value variable
private String gender = "unknown";
// create an accessor to dispatch an event when value is set
public void setGender(String gender) {
this.gender = gender;
dispatchUpdateEvent(GENDER_PROPERTY);
}
// override the parent method to handle user defined value
protected Object getUserDefinedValue(String property) {
// handle custom properties requests
if (PLATFORM_NAME_PROPERTY.equals(property)) {
return Kuix.getCanvas().getPlatformName();
}
if (GENDER_PROPERTY.equals(property)) {
return this.gender;
}
// default behavior if the property has not been found
return null;
}
}
Create a new frame and a new screen to handle user actions and display data.
Start creating a new frame called DynamicFrame for instance. This frame implements the Frame interface.
Implement the appropriate methods so that we can display the content of an XML file called dynamic-display.xml.
public class DynamicFrame implements Frame {
// Associate a screen to the frame
protected Screen screen;
// Associate our data provider to the frame
protected DynamicDataProvider dataProvider = new DynamicDataProvider();
public boolean onMessage(Object identifier, Object[] arguments) {
return true;
}
public void onAdded() {
// Load the content from the XML file with Kuix.loadScreen static method
screen = Kuix.loadScreen("dynamic-display.xml", dataProvider);
// set the application current screen
screen.setCurrent();
}
public void onRemoved() {
// destroy the screen
screen.cleanUp();
// unreference the screen object to free the memory
screen = null;
}
}
Set the content for the new screen in the XML file
Create the XML file that will be loaded with the previous Frame (dynamic-display.xml).
<screen>
<_title>%DYNAMIC_DISPLAY%</_title>
<container style="layout:inlinelayout(false,fill);align:center">
<text style="padding: 0 0 15 0">%PLATFORM_NAME(@{platformName})%</text>
<container style="layout:gridlayout(2,1)">
<button onAction="btn_female" shortcuts="1">%FEMALE_BTN%</button>
<button onAction="btn_male" shortcuts="2">%MALE_BTN%</button>
</container>
<text>%GENDER(@{gender})%</text>
</container>
<screenFirstMenu onAction="back">%BACK%</screenFirstMenu>
<screenSecondMenu>
%MORE%
<menuPopup>
<menuItem onAction="about">
%ABOUT%
</menuItem>
<menuItem onAction="exitConfirm">
%EXIT%
</menuItem>
</menuPopup>
</screenSecondMenu>
</screen>
This screen contains 2 dynamic text widgets: @{platformName} and @{value}. Note the special syntax used to translate only a substring of the text widget (refer to the i18n tutorial of this tutorial for more details).
<_ATTRIBUTENAME>value</_ATTRIBUTENAME>
Implement the user actions
Open the frame created at step 1 to implement the onMessage() method. Thanks to the frame stack and the event dispatcher, "about", "exit" and "exitConfirm" actions will be handled by the HelloworldFrame. The following code implements the user actions referenced in the XML file.
public boolean onMessage(Object identifier, Object[] arguments) {
// handle the "back" button on the screen
if ("back".equals(identifier)) {
// remove the current frame from the framehandler stack
Kuix.getFrameHandler().removeFrame(this);
// and display the main screen
Kuix.getFrameHandler().getTopFrame().onAdded();
// do not propagate the message through the rest of the frame stack
return false;
} else if ("btn_female".equals(identifier)) {
// use the data provider to set its value
dataProvider.setGender("F");
} else if ("btn_male".equals(identifier)) {
// use the data provider to set its value
dataProvider.setGender("M");
}
// let the next frames in the stack, process the message
return true;
}
The back button returns to the main screen whereas button 1 and 2 actions change the value of the data provider.
Add the translation labels to the messages.properties
Here is the translation table for the new labels introduced in the dynamic-display.xml file that you need to add to the messages.properties file.
DYNAMIC_DISPLAY=Dynamic Display
PLATFORM_NAME=Platform name: {0}
GENDER=Gender: {0}
FEMALE_BTN=Female
MALE_BTN=Male
BACK=Back
Add action to pass from HelloWorld screen to dynamic screen
Add the folowing code into the onMessage method of the HelloWorldFrame class.
if ("showDynamic".equals(identifier)) {
// push next frame
Kuix.getFrameHandler().pushFrame(new DynamicFrame());
return false;
}
Edit the HelloWorld.xml and add the folowing menuItem tag :
<menuItem onAction="showDynamic">
%DYNAMIC_DISPLAY%
</menuItem>
Using the data provider to update a radio group value
A data provider can have many use cases as the form fill, real-time screen update, etc. The syntax is always the same as in step 3.
With a radio group for instance, we can use the value of a DataProvider to change the current selection. Look at the example below for more details:
<radioGroup onChange="">
<_value>@{gender}</_value>
<radioButton value="F" enabled="false">female</radioButton>
<radioButton value="M" enabled="false">male</radioButton>
</radioGroup>
In the previous example, the value attribute of the radioGroup is binded to the data provider.
note: this example does not support data update if the user change the radio button selection. Therefore, we disabled the button so that the user cannot click directly on a button. If a bi-directional binding is needed, you can use the onChange attribute on the radioGroup to update the Data provider accordingly.
Update your CSS file with the following code to skin your radio buttons and make them visible:
radiobutton {
bg-image: url(rb_off.png);
bg-align: left;
bg-repeat: 1 1;
padding: 0 0 0 20;
border: 1 1 1 1;
}
radiobutton:hover {
border-color: #f19300;
}
radiobutton:selected {
bg-image: url(rb_on.png);
}
note: do not forget to replace the image files with the appropriate ones
Screenshot


