Copyright © 2011, Zeleos Project Team
The JavaScript API is the core component of the Zeleos Web Toolkit. It was designed to be highly extensible and it follows a strict coding convention. The result is a clean, easy to use framework to develop powerful Rich Internet Applications.
The Zeleos User Interface Description Language or ZUIDL is the second key component. It is used to describe the user interfaces of a ZWT application.
This user guide describes how you can create and develop a ZWT application.
Starting from V0.3.1, ZWT is using Maven to manage the build of both the ZWT applications and the framework.
There are several ways to obtain the ZWT's Maven artifacts, you can either directly use the Zeleos Web Toolkit Maven repository which is the recommended option or download the ZWT distribution and install them in your local repository.
In order to start working with the Zeleos Web Toolkit, you'll need to include the ZWT Maven Repository in your Web Application projects. In the pom.xml, you should have the following:
... <repositories> <repository> <id>ZeleosMvnRepository</id> <name>Zeleos Maven Repository</name> <url>http://www.zeleos.org/repository/</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>ZeleosMvnRepository</id> <name>Zeleos Maven Repository</name> <url>http://www.zeleos.org/repository/</url> </pluginRepository> </pluginRepositories> ...
It is highly recommended to use the ZWT Web Application Maven archetype to generate a proper ZWT project which will include the ZWT Maven repository by default. However if you know what you are doing or if you simply want to use the ZWT Tools Maven Plugin, you can safely add these lines to your pom.xml files.
Please refer to the download section to download the latest ZWT distribution and extract it to the location of your choice.
jkuhn@jkuhn-Studio-XPS-8100:~/tmp/zwt-release-0.3.1$ ls -l total 36 -rw-r--r-- 1 jkuhn jkuhn 432 2012-01-12 00:24 AUTHORS drwxr-xr-x 4 jkuhn jkuhn 4096 2012-01-12 00:24 docs -rw-r--r-- 1 jkuhn jkuhn 11357 2012-01-12 00:24 LICENSE drwxr-xr-x 8 jkuhn jkuhn 4096 2012-01-12 00:24 modules -rw-r--r-- 1 jkuhn jkuhn 588 2012-01-12 00:24 NOTICE -rw-r--r-- 1 jkuhn jkuhn 3896 2012-01-12 00:24 pom.xml -rw-r--r-- 1 jkuhn jkuhn 1756 2012-01-12 00:24 README jkuhn@jkuhn-Studio-XPS-8100:~/tmp/zwt-release-0.3.1$
You need then to install the ZWT artifacts to your Maven local repository:
jkuhn@inspiron-640m:~/tmp/zwt-release-0.3.1$ mvn install [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building zwt-installer 0.3.1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ zwt-installer --- [INFO] [INFO] --- maven-install-plugin:2.3.1:install (default-install) @ zwt-installer --- [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/pom.xml to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-installer/0.3.1/zwt-installer-0.3.1.pom [INFO] [INFO] --- maven-install-plugin:2.3.1:install-file (Install zwt-0.3.1) @ zwt-installer --- [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt/pom.xml to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt/0.3.1/zwt-0.3.1.pom [INFO] [INFO] --- maven-install-plugin:2.3.1:install-file (Install zwt-frmk-0.3.1) @ zwt-installer --- [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-frmk/zwt-frmk-0.3.1.war to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-frmk/0.3.1/zwt-frmk-0.3.1.war [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-frmk/pom.xml to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-frmk/0.3.1/zwt-frmk-0.3.1.pom [INFO] [INFO] --- maven-install-plugin:2.3.1:install-file (Install zwt-jsdoc-0.3.1) @ zwt-installer --- [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-jsdoc/zwt-jsdoc-0.3.1.jar to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-jsdoc/0.3.1/zwt-jsdoc-0.3.1.jar [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-jsdoc/pom.xml to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-jsdoc/0.3.1/zwt-jsdoc-0.3.1.pom [INFO] [INFO] --- maven-install-plugin:2.3.1:install-file (Install zwt-parent-0.3.1) @ zwt-installer --- [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-parent/pom.xml to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-parent/0.3.1/zwt-parent-0.3.1.pom [INFO] [INFO] --- maven-install-plugin:2.3.1:install-file (Install zwt-themes-0.3.1) @ zwt-installer --- [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-themes/zwt-themes-0.3.1.war to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-themes/0.3.1/zwt-themes-0.3.1.war [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-themes/pom.xml to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-themes/0.3.1/zwt-themes-0.3.1.pom [INFO] [INFO] --- maven-install-plugin:2.3.1:install-file (Install zwt-tools-0.3.1) @ zwt-installer --- [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-tools/zwt-tools-0.3.1.jar to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-tools/0.3.1/zwt-tools-0.3.1.jar [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-tools/pom.xml to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-tools/0.3.1/zwt-tools-0.3.1.pom [INFO] [INFO] --- maven-install-plugin:2.3.1:install-file (Install zwt-webapp-0.3.1) @ zwt-installer --- [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-webapp/zwt-webapp-0.3.1.jar to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-webapp/0.3.1/zwt-webapp-0.3.1.jar [INFO] Installing /home/jkuhn/tmp/zwt-release-0.3.1/modules/zwt-webapp/pom.xml to /home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-webapp/0.3.1/zwt-webapp-0.3.1.pom [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.357s [INFO] Finished at: Sat Jun 16 00:22:32 CEST 2012 [INFO] Final Memory: 2M/38M [INFO] ------------------------------------------------------------------------ jkuhn@inspiron-640m:~/tmp/zwt-release-0.3.1$
Everything you need is now deployed on your local repository, you can safely remove the ZWT distribution directory.
We'll rely on the ZWT Maven repository for the rest of this documentation.
It is recommended to use Eclipse IDE to develop ZWT applications, you can get Eclipse from the Eclipse web site.
In order to benefit from code assist and validation when writing ZUIDL files, you should add the ZUIDL schema to the Eclipse XML Catalog. Please open Eclipse and go to Window > Preferences and select XML > XML Catalog:
You can add the ZUIDL schema to the XML catalog by either using the path to the schema embedded in the ZWT tools jar located
in your local repository jar:file:M2_REPO/org/zeleos/zwt/zwt-tools/0.3.1/zwt-tools-0.3.1.jar!/org/zeleos/zwt/uidl/zwt.xsd
where M2_REPO
is the location of your Maven local repository or simply by using the schema deployed on the Zeleos web site http://www.zeleos.org/zwt/V0.3.1/zuidl/zwt.xsd
.
Let's specify this URL in the location field with the key: http://www.zeleos.org/zwt/zwt-uidl
.
Your environment is now properly set to create ZUIDL files with XML validation and code assist.
The ZWT runtime environment is composed of the JavaScript API, providing the ZWT system and the UI components, and the ZWT Themes. This runtime must be accessible by the application.
By default, the ZWT runtime will be included in the ZWT application WAR generated by Maven but in a production environment, you may want to deploy it in a central location on your web server so that many applications can share the same runtime.
This choice really depends on how you want to deploy your applications. During the development, it's easier to have everything available in the WAR.
The runtime configuration is specified in the HTML file that loads the application. In the header of the file, you should have the following lines:
... <script type="text/javascript" src="zwt/api/zwt.js"> </script> <script type="text/javascript"> System.setClassPath(['zwt/api/','js/']); </script> <link id="zwt_theme" rel="stylesheet" type="text/css" href="zwt/themes/Default/zwt.css"/> ...
You can modify those path to point to any runtime. Please note that it should be in the same domain as your application to avoid cross domain issues.
Now that your environment is correctly set, you can create a ZWT application.
The Maven archetype plugin makes it easy to create a new ZWT application project. You simply need to go to the location of your choice (your Eclipse workspace for instance) and use the following mvn command:
jkuhn@inspiron-640m:~/devel/working/workspace-manual$ mvn archetype:generate -DarchetypeCatalog=http://www.zeleos.org/repository/ [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Stub Project (No POM) 1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>> [INFO] [INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<< [INFO] [INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom --- [INFO] Generating project in Interactive mode [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0) Choose archetype: 1: http://www.zeleos.org/repository/ -> org.zeleos.zwt.archetypes:zwt-archetype-webapp (An archetype which contains a sample ZWT web application project.) Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 1 Define value for property 'groupId': : org.zeleos.tuto Define value for property 'artifactId': : zwtTutorial Define value for property 'version': 1.0-SNAPSHOT: : Define value for property 'package': org.zeleos.tuto: : Define value for property 'name': : ZWT Tutorial Confirm properties configuration: groupId: org.zeleos.tuto artifactId: zwtTutorial version: 1.0-SNAPSHOT package: org.zeleos.tuto name: ZWT Tutorial Y: : [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Archetype: zwt-archetype-webapp:0.3.1 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: org.zeleos.tuto [INFO] Parameter: artifactId, Value: zwtTutorial [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] Parameter: package, Value: org.zeleos.tuto [INFO] Parameter: packageInPathFormat, Value: org/zeleos/tuto [INFO] Parameter: package, Value: org.zeleos.tuto [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] Parameter: name, Value: ZWT Tutorial [INFO] Parameter: groupId, Value: org.zeleos.tuto [INFO] Parameter: artifactId, Value: zwtTutorial [INFO] project created from Archetype in dir: /home/jkuhn/devel/working/workspace-manual/zwtTutorial [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 37.575s [INFO] Finished at: Mon Oct 08 22:35:55 CEST 2012 [INFO] Final Memory: 8M/74M [INFO] --------------------------------------------------------- jkuhn@inspiron-640m:~/devel/working/workspace-manual$
A new project zwtTutorial should have been created in your Eclipse workspace.
jkuhn@jkuhn-Studio-XPS-8100:~/devel/working/workspace-manual/zwtTutorial$ tree . ├── pom.xml └── src └── main ├── webapp │ └── WEB-INF │ └── web.xml └── zuidl └── org └── zeleos └── tuto ├── zwtTutorialApp.xml └── zwtTutorialView.xml 8 directories, 4 files jkuhn@jkuhn-Studio-XPS-8100:~/devel/working/workspace-manual/zwtTutorial$
You can now use the Maven Eclipse plugin to generate the .project
and .classpath
files required to import the project in the Eclipse workspace:
jkuhn@inspiron-640m:~/devel/working/workspace-manual/zwtTutorial$ mvn eclipse:eclipse [INFO] Scanning for projects... Downloading: http://www.zeleos.org/repository/org/apache/maven/plugins/maven-metadata.xml Downloading: http://www.zeleos.org/repository/org/codehaus/mojo/maven-metadata.xml Downloading: http://www.zeleos.org/repository/org/apache/maven/plugins/maven-eclipse-plugin/maven-metadata.xml [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building ZWT Tutorial 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> maven-eclipse-plugin:2.9:eclipse (default-cli) @ zwtTutorial >>> [INFO] [INFO] --- zwt-tools:0.3.1:zuidl-compile (compile-zuidl) @ zwtTutorial --- [INFO] ==== Zeleos UIDL Compiler ==== [INFO] Load ZUIDL Generator [INFO] Load ZUIDL Parser [INFO] Processing /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/zuidl [INFO] -------------------------------------------------------------------------------- [INFO] Compiling org/zeleos/tuto/zwtTutorialView.xml [INFO] ---> Validate ZUIDL Source... [INFO] ---> Generate JavaScript: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialView.js [INFO] ---> Generate JavaScript Controller: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialViewController.js [INFO] ---> Generate JavaScript Controller Callback: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialViewController_callback.js [INFO] ---> Generate JavaScript Model: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialViewModel.js [INFO] ---> Generate CSS: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/css/org/zeleos/tuto/zwtTutorialView.css [INFO] Compiling org/zeleos/tuto/zwtTutorialApp.xml [INFO] ---> Validate ZUIDL Source... [INFO] ---> Generate Application JavaScript: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialApp.js [INFO] ---> Generate Application JavaScript Controller: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialAppController.js [INFO] ---> Generate Application JavaScript Controller Callback: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialAppController_callback.js [INFO] ---> Generate CSS: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/css/org/zeleos/tuto/zwtTutorialApp.css [INFO] ---> Generate Application HTML: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/webapp/org.zeleos.tuto.zwtTutorialApp.html [INFO] ---> Generate Application HTML (pack): /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/webapp/org.zeleos.tuto.zwtTutorialApp-pack.html [INFO] -------------------------------------------------------------------------------- [INFO] Compiled 2 file(s) with 0 error(s). [INFO] [INFO] <<< maven-eclipse-plugin:2.9:eclipse (default-cli) @ zwtTutorial <<< [INFO] [INFO] --- maven-eclipse-plugin:2.9:eclipse (default-cli) @ zwtTutorial --- [INFO] Using Eclipse Workspace: null [INFO] Adding default classpath container: org.eclipse.jdt.launching.JRE_CONTAINER [INFO] Not writing settings - defaults suffice [INFO] Wrote Eclipse project for "org.zeleos.tuto:zwtTutorial-1.0-SNAPSHOT" to /home/jkuhn/devel/working/workspace-manual/zwtTutorial. [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 10.194s [INFO] Finished at: Mon Oct 08 22:40:49 CEST 2012 [INFO] Final Memory: 10M/102M [INFO] ------------------------------------------------------------------------ jkuhn@inspiron-640m:~/devel/working/workspace-manual/zwtTutorial$
You could also use an Eclipse plugin like m2eclipse to directly import the project in your workspace or even use another IDE (NetBeans, IntelliJ IDEA...).
To import your project in Eclipse, go to File > Import.
Select "Existing project into Workspace" and select the zwtTutorial
directory.
Click on Finish, your workspace should now looks like this:
The new project contains a sample application you can compile and run using the Maven Tomcat plugin:
jkuhn@inspiron-640m:~/devel/working/workspace-manual/zwtTutorial$ mvn tomcat:run-war [INFO] Scanning for projects... Downloading: http://www.zeleos.org/repository/org/codehaus/mojo/tomcat-maven-plugin/maven-metadata.xml [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building ZWT Tutorial 1.0-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> tomcat-maven-plugin:1.1:run-war (default-cli) @ zwtTutorial >>> [INFO] [INFO] --- zwt-tools:0.3.1:zuidl-compile (compile-zuidl) @ zwtTutorial --- [INFO] ==== Zeleos UIDL Compiler ==== [INFO] Load ZUIDL Generator [INFO] Load ZUIDL Parser [INFO] Processing /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/zuidl [INFO] -------------------------------------------------------------------------------- [INFO] Compiling org/zeleos/tuto/zwtTutorialView.xml [INFO] ---> Validate ZUIDL Source... [INFO] ---> Generate JavaScript: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialView.js [INFO] ---> Generate JavaScript Controller: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialViewController.js [INFO] ---> Generate JavaScript Controller Callback: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialViewController_callback.js [INFO] ---> Generate JavaScript Model: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialViewModel.js [INFO] ---> Generate CSS: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/css/org/zeleos/tuto/zwtTutorialView.css [INFO] Compiling org/zeleos/tuto/zwtTutorialApp.xml [INFO] ---> Validate ZUIDL Source... [INFO] ---> Generate Application JavaScript: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialApp.js [INFO] ---> Generate Application JavaScript Controller: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialAppController.js [INFO] ---> Generate Application JavaScript Controller Callback: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialAppController_callback.js [INFO] ---> Generate CSS: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/css/org/zeleos/tuto/zwtTutorialApp.css [INFO] ---> Generate Application HTML: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/webapp/org.zeleos.tuto.zwtTutorialApp.html [INFO] ---> Generate Application HTML (pack): /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/webapp/org.zeleos.tuto.zwtTutorialApp-pack.html [INFO] -------------------------------------------------------------------------------- [INFO] Compiled 2 file(s) with 0 error(s). [INFO] [INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ zwtTutorial --- [debug] execute contextualize [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] Copying 0 resource [INFO] Copying 6 resources [INFO] Copying 4 resources [INFO] [INFO] --- zwt-tools:0.3.1:zjs-compile (optimize-js) @ zwtTutorial --- [INFO] ==== Zeleos ZECMA262 Compiler ==== [INFO] -------------------------------------------------------------------------------- [INFO] Processing /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js [INFO] -------------------------------------------------------------------------------- [INFO] Compiling /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialAppController_callback.js [INFO] Compiling /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialApp.js [INFO] Compiling /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialView.js [INFO] Compiling /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialAppController.js [INFO] Compiling /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialViewModel.js [INFO] Compiling /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialViewController_callback.js [INFO] Compiling /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/js/org/zeleos/tuto/zwtTutorialViewController.js [INFO] -------------------------------------------------------------------------------- [INFO] Compiled 7 file(s) with 0 error(s). [INFO] [INFO] --- zwt-tools:0.3.1:zjs-package (package-js) @ zwtTutorial --- [INFO] ==== Zeleos ZECMA262 Packager ==== [INFO] Class path: jar:file:/home/jkuhn/.m2/repository/org/zeleos/zwt/zwt-frmk/0.3.1/zwt-frmk-0.3.1.war!/;file:///home/jkuhn/devel/working/workspace-manual/zwtTutorial/target/zwtTutorial-1.0-SNAPSHOT/js; [INFO] -------------------------------------------------------------------------------- [INFO] Packaging org.zeleos.tuto.zwtTutorialApp [INFO] [INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ zwtTutorial --- [INFO] No sources to compile [INFO] [INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ zwtTutorial --- [debug] execute contextualize [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ zwtTutorial --- [INFO] No sources to compile [INFO] [INFO] --- maven-surefire-plugin:2.10:test (default-test) @ zwtTutorial --- [INFO] No tests to run. [INFO] Surefire report directory: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Results : Tests run: 0, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] --- maven-war-plugin:2.2:war (default-war) @ zwtTutorial --- [INFO] Packaging webapp [INFO] Assembling webapp [zwtTutorial] in [/home/jkuhn/devel/working/workspace-manual/zwtTutorial/target/zwtTutorial-1.0-SNAPSHOT] [INFO] Processing war project [INFO] Copying webapp webResources [/home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/css] to [/home/jkuhn/devel/working/workspace-manual/zwtTutorial/target/zwtTutorial-1.0-SNAPSHOT] [INFO] Copying webapp resources [/home/jkuhn/devel/working/workspace-manual/zwtTutorial/src/main/webapp] [INFO] Processing overlay [ id org.zeleos.zwt:zwt-frmk] [INFO] Processing overlay [ id org.zeleos.zwt.themes:zwt-themes] [INFO] Webapp assembled in [2494 msecs] [INFO] Building war: /home/jkuhn/devel/working/workspace-manual/zwtTutorial/target/zwtTutorial-1.0-SNAPSHOT.war [INFO] WEB-INF/web.xml already added, skipping [INFO] [INFO] <<< tomcat-maven-plugin:1.1:run-war (default-cli) @ zwtTutorial <<< [INFO] [INFO] --- tomcat-maven-plugin:1.1:run-war (default-cli) @ zwtTutorial --- [INFO] Running war on http://localhost:8080/zwtTutorial [INFO] Creating Tomcat server configuration at /home/jkuhn/devel/working/workspace-manual/zwtTutorial/target/tomcat
This will compile your application, generate the required JavaScript, CSS and HTML files and start a Tomcat server hosting the application.
The org.zeleos.tuto.zwtTutorialApp.html
file is the entry point of the sample application.
The sample application is pretty basic, it simply displays a button in a Part. You can access it at this location http://localhost:8080/zwtTutorial/org.zeleos.tuto.zwtTutorialApp.html:
Congratulations!!! You have compiled and run your first ZWT application.
A ZWT application is composed of one or more Parts attached to the Window. A Part represents a specific area in the page that actually contains a ZWT user interface. The Part is itself composed of UI components or widgets (Button, TextField...) the user use to interact with the application.
Model-View-Controller pattern has become an industry standard and ZWT provides facilities to implement it. You can easily
isolate the application logic from the view. For instance, a Part Controller (zwt.control.PartController
) is used to handle the user interaction with the Part (zwt.ui.Part
) and to access or modify the Model accordingly (zwt.model.Model
).
The ZUIDL compiler generates the required code to use the MVC pattern for every application and part defined in ZUIDL.
ZWT provides a complete UI Description Language: the Zeleos UI Description Language or ZUIDL. It is used to describe the graphical user interfaces of the applications. Using such language has many advantages:
In practice, user interfaces are described in XML files following the ZUIDL grammar and the ZUIDL Compiler generates the corresponding JavaScript, CSS and HTML code.
ZUIDL defines two types of files to describe user interfaces:
The HTML file is only generated if the ZUIDL source file is describing an application, this file is the entry point of the application.
ZUIDL files are located in src/main/zuidl/
, you can have a look at the Sample ZUIDL files in the zwtTutorial project. Just like in Java a ZUIDL file is stored in a directory structure that corresponds to its namespace. Sample ZUIDL
files are defined in the namespace specified during the creation of the project and stored in the corresponding directory.
org/zeleos/tuto/zwtTutorialApp.xml
describes the Tutorial application:
<?xml version="1.0" encoding="UTF-8"?> <!-- This is a sample application: - id must be the file name - namespace the path to the file --> <zwt:application id="zwtTutorialApp" namespace="org.zeleos.tuto" title="ZWT Tutorial" theme="Default" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:zwt="http://www.zeleos.org/zwt/zwt-uidl" xsi:schemaLocation="http://www.zeleos.org/zwt/zwt-uidl http://www.zeleos.org/zwt/zwt-uidl "> <!-- Sample App has only one part, you can add as many as you want When declaring a part, you must provide: - an id - the full namespace of the controller class --> <zwt:controller id="zwtTutorialApp" class="org.zeleos.tuto.zwtTutorialViewController"/> </zwt:application>
The id
of the application has to be the same as the file name and as stated before, the namespace must match the directory structure.
The title
of the application corresponds to the HTML title displayed in the web browser.
The theme
specifies the ZWT theme to use in the application.
The application contains one part controller defined by the org.zeleos.tuto.zwtTutorialViewController
class. The controller id
is used to identify the part in the Window and to specify the id of the DIV
that will host it in the page. In our example, the DIV
element should have zwtTutorialApp
as ID.
Apart from declaring the controllers of the application, you can bind any application events to an action defined in the application controller. If your Eclipse environment is correctly set, use the code assist (Ctrl+space) to see what you can do:
We can for instance map the didResizeWindow
method of the controller to the windowResize
event.
org/zeleos/tuto/zwtTutorialView.xml
describes the tutorial Part declared in the application.
<?xml version="1.0" encoding="UTF-8"?> <!-- This is the sample part definition: - id must be the file name - namespace the path to the file A part is a top UI component that can be included in an application. For each part, a controller is created that contains your custom code. --> <zwt:part id="zwtTutorialView" namespace="org.zeleos.tuto" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:zwt="http://www.zeleos.org/zwt/zwt-uidl" xsi:schemaLocation="http://www.zeleos.org/zwt/zwt-uidl http://www.zeleos.org/zwt/zwt-uidl "> <zwt:button id="HelloButton" fill="none"> <zwt:set name="Text" value="'Hello World'"/> <zwt:action name="hello" event="click"/> </zwt:button> </zwt:part>
As for the application, the id
has to be the same as the file name and the namespace must match the directory structure.
A Part is a single container (zwt.ui.container.SingleContainer
) so it can only contain one widget. In our example, it contains a button with 'Hello World' as a label. You can see that
the hello
action is bind to the click
event.
All the available widgets can be used in ZUIDL, you can refer to the ZUIDL Reference documentation to see how to use them. We can for instance use a panel to improve a bit our application.
<?xml version="1.0" encoding="UTF-8"?> <zwt:part id="zwtTutorialView" namespace="org.zeleos.tuto" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:zwt="http://www.zeleos.org/zwt/zwt-uidl" xsi:schemaLocation="http://www.zeleos.org/zwt/zwt-uidl http://www.zeleos.org/zwt/zwt-uidl "> <zwt:verticalPanel id="SamplePanel"> <zwt:button id="HelloButton" weight="1" fill="none"> <zwt:set name="Text" value="'Hello World'"/> <zwt:action name="hello" event="click"/> </zwt:button> <zwt:label id="HelloLabel" weight="1"> </zwt:label> </zwt:verticalPanel> </zwt:part>
The SamplePanel
is now the content widget of the Part, it is a vertical panel (zwt.ui.panel.VerticalPanel
) that displays widgets vertically. We have added a simple label (zwt.ui.Label
) that will be used to display some text.
The weight
attribute is used in a vertical or a horizontal panels to define the space occupied by a widget in the panel. For instance,
the HelloLabel
and the HelloButton
occupy the same space in the panel. The fill
attribute is used to indicate whether the widget should fill the available space horizontally and/or vertically. The default
setting depends on the Widget, in the case of the HelloButton
, all the space available is used.
Widget properties can be set with an attribute on the widget tag like the fill
attribute or the weight
attribute but most of the time, they are set through accessor methods using the set
tag.
... <zwt:widget id="MyWidget"> ... <zwt:set name="$NAME" value="$VALUE"/> ... </zwt:widget> ...
Once again, the properties you can set depend on the Widget, so please refer to the ZUIDL schema or the ZWT JavaScript API to find out the accessor methods defined for a given widget.
The value of the property is specified in JavaScript so if the property Text
is a String, you need to enter 'My text'
, otherwise you'll get a JavaScript error at runtime.
A user typically interacts with an application through its user interface which basically emits events on user actions like
a mouse click or a key press. The action
tag is used to bind an event to a controller's action.
... <zwt:widget id="MyWidget"> ... <zwt:action name="$NAME" event="$EVENT_TYPE"/> ... </zwt:widget> ...
The name of the action correponds to the name of the controller's method to execute. The event type depends on the Widget, for instance a button and a list box don't emit the same type of events.
The ZUIDL Compiler generates an empty method in the Controller class for each action defined on a Widget.
As for the properties, please refer to the ZUIDL schema or the ZWT JavaScript API to find out the type of events emitted by a given Widget.
There's almost no limit in what you can do with ZUIDL. I encourage you to have a look at the ZUIDL Reference documentation and the ZWT JavaScript API to have a better understanding of what you can really do.
You can also have a look at the ZWT Samples that cover a lot of use cases you may be interested in your own applications.
A ZWT project uses the ZWT Tools to generate the JavaScript, CSS and HTML code of the application from the ZUIDL files.
The generation of these files is done in the Maven build process during the process-resources
phase. So basically, you simply need to run the mvn compile
command to generate or regenerate the files. Don't forget to refresh your workspace to see the generated files in Eclipse.
The ZUIDL Compiler compiles the ZUIDL source files and generates the files of the application.
It generates different files depending on the type of the ZUIDL source file.
The JavaScript files are stored in the src/main/js
source folder.
You can modify the selected files which should basically contain the functional code of the application. You should never modify the other files as they are always regenerated by the compiler.
For an application ZUIDL source file, the compiler generates the following files:
main
method.
No Model is generated by the Compiler for an application because it doesn't have much meaning in that context.
The functionnal code of the application should go in the controller callback extension file that defines the methods bound to application events. This file is updated by the compiler if it already exists, all the other files are regenerated.
For a part ZUIDL source file, the compiler generates the following files:
In that context, the Model has a real role to play since the user can actually view the data displayed in the Part and modify them through the controller when interacting with the part.
As for the application, the functionnal code should go in the controller callback extension and the model, all the other files are systematically regenerated by the compiler.
The CSS files are stored in the src/main/css
source folder.
The compiler generates one CSS file per ZUIDL source file. It defines empty CSS selectors to modify the style of the different widgets.
These files are only updated by the compiler if they already exist, so you can safely modify them.
The HTML files are stored in the src/main/webapp
directory.
The compiler generates two HTML files per application ZUIDL source file:
The name of the HTML file is the qualified name of the application, it represents the entry point of the ZWT application.
These files are only generated if they don't already exist, you can also safely modify them.
The functional code defines the behavior of the application. It is executed when the user interacts with the application. It has to be defined in a controller in respect of the MVC pattern.
The controller callback extension files regroups all the methods bound to UI events, the functional code should naturaly go in these files. The controller handles events and can modify the model and/or the view. Therefore, an action method in a controller can interact with both the model and the view.
Open the org/zeleos/tuto/zwtTutorialAppController_callback.js
Controller extension. If you remember, we have previously declared the didResizeWindow
action on the windowResize event in the application ZUIDL file.
namespace('org.zeleos.tuto'); include('org.zeleos.tuto.zwtTutorialAppController'); org.zeleos.tuto.zwtTutorialAppController.prototype.didResizeWindow = function(zwt_ui_Window_window, zwt_event_WindowEvent_event) { };
The didResizeWindow
method is correctly defined in the zwtTutorialAppController
and should normally be executed when the browser window is resized.
Let's display the viewport dimension in the HelloLabel
when the window is resized.
namespace('org.zeleos.tuto'); include('org.zeleos.tuto.zwtTutorialAppController'); org.zeleos.tuto.zwtTutorialAppController.prototype.didResizeWindow = function(zwt_ui_Window_window,zwt_event_WindowEvent_event) { this.getzwtTutorialApp().getPart().getHelloLabel().setText('Height: ' + zwt_ui_Window_window.getInnerHeight() + 'px, Width: ' + zwt_ui_Window_window.getInnerWidth() + 'px'); };
As you can see the application controller provides an accessor to get the zwtTutorialApp
controller.
We have also defined an action in the zwtTutorialView
. The controller should normally stores the data being displayed in the part in the model. Since our tutorial application
is pretty basic, it doesn't make much sense to use the model for now.
Open the org/zeleos/tuto/zwtTutorialViewController_callback.js
Controller extension.
namespace('org.zeleos.tuto'); include('org.zeleos.tuto.zwtTutorialViewController'); org.zeleos.tuto.zwtTutorialViewController.prototype.hello = function(zwt_ui_Button_button, zwt_event_ClickEvent_event) { this.getPart().getHelloLabel().setText('Hello World!!!'); };
The hello
method is executed when the user clicks on the HelloButton
and simply displays 'Hello World!!!' in the HelloLabel
.
You can now run the application and see the result.
When resizing the window the new viewport dimension is displayed in the label. When clicking on the button, as expected, 'Hello World' is displayed in the label.
You may have noticed the namespace
and include
methods in the controller extension. They are used to indicate the namespace of the file and its dependencies to other classes.
Please have a look at the ZWT JavaScript API to have a detailed documentation on the controller (zwt.control.PartController
), the model (zwt.model.Model
) and the widgets.
Although event handling is specified in ZUIDL through the action
tag, it may be interesting to know how events are handled in a ZWT application.
First of all, all the events are not necessarily emitted by user interface components, they may also be emitted by a model when it is updated or any kind of objects. These various kind of events are handled in the same way using event handlers registered on an event manager associated to an Object that emits the events. This is the standard Observer pattern used in many UI frameworks.
A handler function is registered to the appropriate event manager of an object for a specific event type. An object emits events when its state changes in some ways programmatically or on a user action. The event is then handled by the appropriate event manager which delegates the event processing to the handlers registered on this specific type of the event.
In practice here is how we add a click event handler to the click event manager of the HelloLabel
:
namespace('org.zeleos.tuto'); include('org.zeleos.tuto.zwtTutorialViewController'); org.zeleos.tuto.zwtTutorialViewController.prototype.hello = function(zwt_ui_Button_button,zwt_event_ClickEvent_event) { this.getPart().getHelloLabel().setText('Hello World!!!'); var clickEventHandler = function(zwt_ui_Label_label, zwt_event_ClickEvent_event) { zwt_ui_Label_label.setText(''); zwt_ui_Label_label.getClickEventManager().removeClickHandler(clickEventHandler); }; this.getPart().getHelloLabel().getClickEventManager().addClickHandler(clickEventHandler); };
When the HelloButton
is clicked, a click event handler is registered to the click event manager of the HelloLabel
. And when the HelloLabel
is clicked, its text is cleared and the handler is unregistered.
You already had a small overview of the MVC Pattern used in ZWT, but we didn't go deep into it.
As stated in the previous section, a model can also emits events when its state changes and we can then handle them with an event manager. This is particularily powerful when parts need to communicate with each other. Basically, a part controller may monitor the changes on the model of another part by registering an event handler to its event manager. We'll complexify the tutorial application to play a bit with controllers and models.
Let's create a new ZUIDL file SamplePopup.xml
in the org.zeleos.tuto
package. If you have correctly set your Eclipse envrionment, you should be able to have code assist provided by the ZUIDL
XML schema.
Select org.zeleos.tuto
package in the src/main/zuidl
source folder and press Ctrl+N
to create a new ZUIDL file:
Choose to create the file from an XML schema file:
Then select the ZUIDL schema in the XML Catalog
We want to create a Popup Window so the root element of the file must be popupWindow
:
A new SamplePopup.xml
ZUIDL file has been created, we need to specify the id
and the namespace
that must match the file name and the directory structure.
Our Sample popup contains only a simple text field that will be used to enter a name.
<?xml version="1.0" encoding="UTF-8"?> <zwt:popupWindow id="SamplePopup" namespace="org.zeleos.tuto" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:zwt="http://www.zeleos.org/zwt/zwt-uidl" xsi:schemaLocation="http://www.zeleos.org/zwt/zwt-uidl http://www.zeleos.org/zwt/zwt-uidl "> <zwt:textField id="NameTextField"> <zwt:action name="onKeyUp" event="keyUp"/> </zwt:textField> <zwt:set name="Title" value="'Enter your name:'"/> <zwt:set name="Dimension" value="250,75"/> <zwt:set name="Maximize" value="false"/> <zwt:set name="Minimize" value="false"/> <zwt:set name="Resizable" value="false"/> </zwt:popupWindow>
You now need to recompile the zwtTutorial project in order to generate the JavaScript and CSS files for the new SamplePopup
.
Now that we have created the sample popup, we have to modify the hello
method in the zwtTutorialViewController
to open it the first time the user clicks on the HelloButton
.
namespace('org.zeleos.tuto'); include('org.zeleos.tuto.zwtTutorialViewController'); include('org.zeleos.tuto.SamplePopupController'); include('org.zeleos.tuto.SamplePopupController_callback'); org.zeleos.tuto.zwtTutorialViewController.prototype.hello = function(zwt_ui_Button_button,zwt_event_ClickEvent_event) { if(this._samplePopupController == null) { this._samplePopupController = new org.zeleos.tuto.SamplePopupController(); this._samplePopupController.getModel().getModelEventManager().addNotifyHandler(function(zwt_model_Model_model, zwt_model_ModelEvent_event) { this.getPart().getHelloLabel().setText('Hello ' + zwt_model_Model_model.name + '!!!'); }.bind(this)); zwt.ui.Window.getWindow().addPopup(this._samplePopupController.getPart()); this._samplePopupController.getPart().show(); } };
The hello
method now creates a SamplePopupController
, registers an event handler to the model event manager of the popup's model and finally shows the popup which needs first
to be attached to the window.
When the model of the sample popup is modified, an event should be emitted to notify its event manager that its state has
changed. The event manager then dispatches the event to the registered event handlers. In our tutorial application, the handler
sets the text of the HelloLabel
using the name
attribute of the sample popup model.
Basically when the SamplePopupController
modifies its model, it must send a event to notify the registered handlers that its state has changed, this is done in the
onKeyUp
method.
namespace('org.zeleos.tuto'); include('org.zeleos.tuto.SamplePopupController'); include('zwt.event.ModelEvent'); org.zeleos.tuto.SamplePopupController.prototype.onKeyUp = function(zwt_ui_TextField_textField, zwt_event_KeyboardEvent_event) { this.getModel().name = this.getPart().getNameTextField().getText(); this.getModel().onEvent(new zwt.model.ModelEvent(zwt.model.ModelEvent.NOTIFY)); };
The following steps describe the complete process:
You can now test the tutorial application and see that the behavior is as expected: when you click on the HelloButton
the SamplePopup
shows up and when you enter some text in the NameTextField
the HelloLabel
is automatically updated.
In order to completely use the MVC pattern, we should also register a model event handler on the sample model. We can do this
when the SampleController
is initialized:
<?xml version="1.0" encoding="UTF-8"?> <zwt:part id="Sample" namespace="org.zeleos.tuto" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:zwt="http://www.zeleos.org/zwt/zwt-uidl" xsi:schemaLocation="http://www.zeleos.org/zwt/zwt-uidl http://www.zeleos.org/zwt/zwt-uidl "> ... <zwt:action name="didInitController" event="controllerInit"/> </zwt:part>
In the didInitController
method, we simply register an event handler on the model event manager:
... org.zeleos.tuto.zwtTutorialViewController.prototype.didInitController = function(zwt_control_PartController_controller, zwt_control_PartControllerEvent_event) { this.getModel().getModelEventManager().addNotifyHandler(function(zwt_model_Model_model, zwt_model_ModelEvent_event) { this.getPart().getHelloLabel().setText(zwt_model_Model_model.message); }.bind(this)); }; ...
We can also modify the event handler we have registered on the sample popup model:
... org.zeleos.tuto.zwtTutorialViewController.prototype.hello = function(zwt_ui_Button_button, zwt_event_ClickEvent_event) { if(this._samplePopupController == null) { this._samplePopupController = new org.zeleos.tuto.SamplePopupController(); this._samplePopupController.getModel().getModelEventManager().addNotifyHandler(function(zwt_model_Model_model, zwt_model_ModelEvent_event) { this.getModel().message = 'Hello ' + zwt_model_Model_model.name + '!!!'; this.getModel().onEvent(new zwt.model.ModelEvent(zwt.model.ModelEvent.NOTIFY)); }.bind(this)); zwt.ui.Window.getWindow().addPopup(this._samplePopupController.getPart()); this._samplePopupController.getPart().show(); } }; ...
Now all the views in the tutorial application are synchronized with their model.
The ZUIDL compiler generates default CSS files for the applications and the parts. You can (and probably) should modify these default settings to customize your application.
By default, the dimension of a part is set to 800x600 which is definitely too big for the sample application.
The CSS files are stored in src/main/css
. To modify the dimension of the sample part, you can edit the org/zeleos/tuto/zwtTutorialApp.css
file:
@CHARSET "UTF-8"; @IMPORT url("../../../org/zeleos/tuto/zwtTutorialView.css"); #sampleSlot { width: 300px; height: 100px; margin: 50px auto auto auto; }
You can also modify the CSS style of the HelloLabel
in the org/zeleos/tuto/zwtTutorialView.css
file:
... #HelloLabel .zwt_label { color: red; font-size: 160%; font-weight: bold; text-align: center; border: 1px solid #A4A4A4; margin: 5px; padding-top: 6px; } ...
Now the Sample application should look much better:
The ZUIDL compiler generates empty CSS selectors for all the widgets in the application to facilitate the customization. You can also get information about widgets CSS rules in the ZWT JavaScript API documentation.
The Theme to use is specified in the HTML file of the application. You can safely modify this file:
... <link id="zwt_theme" rel="stylesheet" type="text/css" href="zwt/themes/HighContrast/zwt.css"/> ...
The ZWT distribution provides two themes: the Default
theme and the HightContrast
theme. If you run your application now, you can see the difference:
Note that you can also dynamically change the ZWT theme at runtime using the setTheme
method on the zwt.ui.Window
.
A ZWT theme basically defines all the CSS rules for all the widgets in the framework. As themes are defined in pure CSS, creating your own theme is not that tedious.
ZWT is an extensible framework that let's you create your own themes or create your own widgets. Indeed the API makes it very easy to override existing widgets or create custom ones.
If you want to participate in the development of the Zeleos Web Toolkit, please get the source code from the subversion repository and check the ZWT development page.
We also encourage you to consult the ZWT API documentation and the Zeleos UIDL reference documentation.
If you need support, please use the mailing lists.
We also strongly recommand to have a look at the demos and samples to see what you can do with Zeleos Web Toolkit.