Purpose of this project is to define a declarative XML-based syntax for defining Vaadin user interfaces. Also another goal is to provide support annotation-based binding of data sources and event handlers. Starting from version 0.5.0 Clara supports only Vaadin 7. A separate branch exist for Vaadin 6, but it is not maintained anymore.
Project also serves as a part of my Master's thesis at the University of Turku and also derives from the work done by Joonas Lehtinen on his [xmlui Vaadin add-on](http://vaadin. com/addon/xmlui). A lot of the functionality is also inspired by GWT UiBinder.
Maven is used to build the add-on and the demo application modules (thanks to vdemeester for help). Travis CI is used for automated testing.
To package and install the Clara add-on to your local repository, just run the following command:
mvn install
If you want to run and/or package the demo application, you must also compile the widgetset.
cd clara-demo
mvn vaadin:compile jetty:run
Packaging the distributable add-on zip (that can be uploaded to Vaadin Directory) can be done as follows.
cd clara
mvn clean package assembly:single
The project is licensed under the Apache License, Version 2.0.
A good starting point to try things out is the online demo application demonstrating the current version of the project.
- claraxsd-maven-plugin – A Maven plugin to generate XML schemas to enable code completion and validation.
See the forked SimpleAddressbook example that is modified to use Clara.
Quickstart is written for Clara 1.0.0.
-
Create a new Vaadin 7 project.
-
Download the latest version of Clara to WEB-INF/lib from Vaadin Directory (or use the Maven dependency).
-
Create a new Java package that will contain the XML layout definition and the controller class (see steps 4 and 5).
-
Create a new XML file (name it
MyFirstClaraLayout.xml
) for the layout definition and save it to the Java package you just created. You can copy the example below. Notice the special "urn:vaadin:parent" namespace on the componentAlignment attribute which means that the componentAlignment property belongs to the containing layout instead of the component itself.
<?xml version="1.0" encoding="UTF-8"?>
<VerticalLayout xmlns="urn:import:com.vaadin.ui" xmlns:l="urn:vaadin:parent">
<Label id="my-label" value="Hello Clara!" />
<Button id="my-button" caption="Click me!" width="200px" l:componentAlignment="MIDDLE_CENTER" />
</VerticalLayout>
- Create a plain old Java class with the name
MyFirstClaraController
and add it to the same Java package as the XML file. Binding this controller to the components in the XML layout is done with annotations. Add the following two methods to your controller class.
// The value "my-button" of the annotation is a reference to the id attribute in the XML layout.
@UiHandler("my-button")
public void handleMyButtonClick(ClickEvent event) {
Notification.show("Clicked!");
}
@UiDataSource("my-label")
public Property<String> getLabelProperty() {
return new ObjectProperty<String>("Hello from Controller!",
String.class);
}
By using the @UiField
annotation on a field, you could bind a field directly to a component instance with a certain id. For example:
@UiField("my-label")
private Label myLabel;
- Now you can instantiate the XML definition to a Vaadin component in your Java code. See the example below.
// Use the static "create" method to instantiate the XML into a Vaadin component.
VerticalLayout layout = (VerticalLayout) Clara.create(
"MyFirstClaraLayout.xml", new MyFirstClaraController());
// Now the layout is ready to be used.
setContent(layout);
- Congratulations, you just created your first application that uses Clara. As next steps you might want to see the other static methods contained in the
Clara
class to see more ways to use Clara.
Attribute filters enable runtime modification of any attributes read from the declarative XML layout file. The most obvious use case for this is to provide internationalization of text displayed in the user interface.
To create an attribute filter, you must implement the single-method AttributeFilter
interface and pass it to the Clara.create
method. The sole method in the interface is called filter
and it takes a single argument of type AttributeContext
. You can modify the value before it's assigned by calling the setValue
method of the AttributeContext
. You should always call the proceed
method to pass the value forward to next filter (or to finally assign the value). If you do not call the proceed
method, the attribute value will never be assigned (which might sometimes be the desired effect).
Simple example of an AttributeFilter
implementation:
AttributeFilter filter = new AttributeFilter() {
@Override
public void filter(AttributeContext attributeContext) {
if (attributeContext.getValue().getClass() == String.class) {
String value = (String) attributeContext.getValue();
if (value.startsWith("{i18n:")) {
String translatedValue = getTranslation(value);
attributeContext.setValue(translatedValue);
}
}
try {
attributeContext.proceed();
} catch (Exception e) {
e.printStackTrace();
}
}
};