Painting with Zero Kode: A real-time web page designer based on ZK, Part I"
m (moved Small Talks/Painting with Zero Kode: A real-time web page designer based on ZK, Part I to Small Talks/2006/August/Painting with Zero Kode: A real-time web page designer based on ZK, Part I)
Latest revision as of 09:40, 20 September 2010
Chris Spiliotopoulos, Software Architect, Athens, Greece
August 21, 2006
Sometimes it's just a tough world for application developers, software engineers, web page designers, core developers, front-end developers and the rest of the key roles in the software industry. Well, now that I think about it, it always have been a tough world but for different reasons.
As we look into the past, designing and writing good software was a job that was identified mainly by three major virtues: patience, love for what you do and being able to deliver on time. Unfortunately, nowadays after the 'big-bang' of the software industry, the one virtue that we are left with is just 'being able to deliver on time'. A lot of excuses can be heard around this topic but the most convincing one is that "there are thousands of tools to help you do your thing, so all you got to do is think something smart and just do it!". Well, who can argue with that, uh?
So, enough with the emotional stuff, I'm getting straight to the point. I come from a background of Visual C++, Visual Basic and Java development, where the task of designing the UI of an application had always been fun and easy to do, as all the IDEs I used to work with were shipped with a visual editing tool (designer). It wasn't since last year that I started messing around with web applications and it seems that this was the point of no return !V as far as desktop applications are concerned.
Well, isn't just amazing when at some point when you have to learn and deal with things that you really hate, to come across people that provide a solution for all of your problems (and possibly get their kicks out of these much hated things :))?
It wasn't more than a month ago that I came across the ZK framework and thought HALLELUJAH!!!! During that time I had just started designing a framework for my company that would help the rest of the developers to do their job easily and helping them focus on the business side of the applications rather than on the front-end.
Everyone who works in a team knows that it's pretty hard to bring all the developers on the same level of knowledge and experience with new technologies, especially when they are working under a very tight schedule. This is why every software company needs a concrete framework that can build applications upon. The difficult thing though is that most of the time frameworks come just as an API, with limited or no documentation at all. So, starting from myself, I always feel sorry for new developers that join a team and they have to learn new things and keep up with the others by the hard way.
I must admit that I was astonished by the quantity and quality of work the ZK team have put into their framework. The result is really great! I didn't expect up to that point that I would be able to design a front-end layer for a web app by using a familiar object-oriented style, such as:
Button btn = new Button(); btn.addEventListener(!K); window.appendChild(btn);
To be honest, things like 'Project of the month', or 'Highest number of downloads' do not mean as much to me, as to the development team for their effort. I want to see things working in a real-life application and judge from the performance. For this reason, I decided to learn and explore the framework in a bi-directional way. I thought to myself: "What do you need? A framework to help you with your job. How do you know that this framework is suitable? I don't. What do you do then? I start learning the framework by building a visual editor at the same time and wait for reactions!"
Why a visual designer?
Well, the idea of a designer is something that suits most of the developers. One good thing is that developers who are not very keen on designing UIs or do not have the time, find a helping hand with such a tool, as they can build a page in a few minutes. Another thing is that it abstracts most of the API's details and makes it easier for a team to keep people up to the same level of knowledge.
Being easy to use, doesn't necessarily mean that it cannot be flexible. The ZK team managed to provide a framework where the developer gets a number of choices of how to do things: ZUML, Java, JSP/XUL/HTML and all kinds of combinations. If this is not flexible, then what is? The designer wasn't written as a tool that would replace any of these approaches, but as a starting kit for someone new to the framework, or someone who doesn't want to spend time learning the bits and pieces.
The visual editor is just a web application !V packed in a '*.war' file' - that can be launched on an application server. It provides a visual interface with a toolkit that holds all the visual components that the ZK framework has implemented so far and is designed to use all kinds of custom components as well. This means that a developer can add to the toolkit components that he/she has designed, as far as they are compliant with the framework's protocol.
The developer drags-and-drops visual components on the active model, sets their properties (which are reflections of the corresponding Java class) and sets their events as well. Definitions of all the visual components found in the toolkit, are kept in an XML configuration file that can be edited by the developer in order to add, remove or re-order components. The developer can also load an existing '*.zul' file and modify it.
During the design process the developer can launch the active page in a new window and see how it looks and behaves. When a page is finished, the developer exports the page into a '*.zul' file that can be launched as standalone, or directly added to a web application.
In a nutshell, the designer speeds-up the process of writing '*.zul' files so that you don't have to do it all by hand. And when I say 'all', I mean that it covers 90% of the ZK's functionality at the current edition. Things like "beanshell scripts" for example are not supported by the designer and there is a good point behind that. First of all because I developed it in three weeks time and second because I agree with the ZK team that the best practice is to separate the UI layer from the business layer. This means that it is better to keep your code into separate JAR files so that it can be maintained correctly, rather than mixing it with the UI descriptive elements within a '*.zul' file. You can still do it, but by hand! :)
The following screenshot shows how the designer looks like when it is launched.
The toolbar is found on the top left corner of the designer and provides basic application functionality. You can load a page definition from a '*.zul' file onto the active canvas, you can save the current design into a '*.zul' file, you can preview the page onto a new window and you can clear the canvas and start a new design.
The toolkit is the designer's element found on the mid-left side of the screen, where you drag-and-drop visual components from onto the component model. The toolkit is loaded from the '/config/toolkit/toolkit.xml' file found within the application path. This is an XML file that describes all the components that will be displayed on a toolkit instance. Components are categorized into 'groups' and 'tabs'. You can easily re-organize and add new components to the toolkit by modifying this file.
You can add a new component to the page, by simply performing a drag-and-drop operation onto the model tree, which is just underneath the toolkit. After you drop a component onto the model !V and as long as it can be accepted as a child by the element you drop it onto !V the component gets displayed onto the canvas with its default initialization property values.
The model is just a tree view component that displays the current parent-child component representation that lies on the designer canvas. In a few words, what you have designed so far and is displayed onto the canvas, is actually a component 'tree' that starts from a single root which is the default Window element that is found on top of the tree hierarchy.
When you start the designer app, or clear the canvas there is always a Window component on top of the model tree. This cannot be deleted, as all visual components must have a parent and a common root. Every component that you add to the model is added as a child to the target element initially. Afterwards you can change its position by dragging-and-dropping it within the model tree, where a dialog is displayed concerning its new position.
By right-clicking on a tree element, a context menu is displayed. There you can copy an element and paste it into a new position, delete it, view and modify its properties or view and modify its events. Properties and events are displayed on a modal dialog as a grid of names and values. The properties are displayed after reflection on the component's implementation Java class. This means that all 'get'/'set' methods get displayed, but only those who take primitive or String values as arguments. Events for each component are defined in the 'toolkit.xml' file at this stage, as the API doesn't provide appropriate methods for application developers to retrieve the events supported by a component.
The designer canvas is nothing more than a real-time view of what has been designed so far. There is no direct drag-and-drop action with the canvas, but there is live interaction with the page. Being a living part of the designer app, you can directly interact with it, as you would do with the page itself. And that's the beauty of it.
With traditional designers, you had to finish the page, write the code that drives it, compile it and then drive the application to that point where you could test the page. But here is the real thing. You can modify component properties and see it happening. You can add events and see them get triggered and do their thing. It's all in front of you. And if you want to see the page in full action, you just click the preview button on the toolbar and it gets launched on a new window.
A step-by-step example:
Enough with the theory, so let's get down to business with a real-world example. Ok, let's say that we want to build the most elementary part of a web application, which is the login screen. The login screen is almost a part of any application and usually is the screen that most developers start off with for the design of the web app. The login screen usually performs database interaction behind the scenes for validation purposes, but we are just going to deal with the front-end design.
Typically, the login screen consists of a logo image (usually the application's or company logo), two text boxes !V one for the username and one for the password !V along with two labels that display the purpose of each text box, a couple of icons that beautify the appearance of the screen and finally a button that will trigger the validation code . Now, let's see how easy it is to design the page with the aid of the designer, on top of the ZK framework.
The first thing we have to think about is the layout of all the elements on the page. Normally, the logo image is found on top of the page and takes up the whole width of it. The rest of the components lie beneath it. Labels are positioned on the left of the text boxes and icons are positioned on the left of the labels !V or on the right of the text boxes. Finally the login button is found on the bottom of all the components.
For laying out the components on a page, the box model is used by the framework, so once you get the grasp of it, you will realize that it is a very easy and convenient way of laying out the page. So, first of all we need a vertical layout of the elements to start with. We select the 'Layout' tab of the standard components and drag-and-drop the VBox component onto the model tree, on top of the root Window element.
At this stage you won't see anything on the canvas, as this component doesn't have a visual part. But you can see it on the model tree, as a child of the window element. What you see on the model tree, is a new entry with the component's Id (starting with the # char), the component's type and a small-scaled icon of the component. The Id of component is auto-generated initially by the designer. You can change it to anything you like, as long as there is no naming conflict within the same Id space.
By right-clicking on the VBox element on the model, a context menu is displayed with all the actions you can take on the component itself. Select the 'Display Properties' menu item and a modal dialog will be displayed, showing all the component properties that can be modified by the user. These correspond to the read/write property methods of the Java object that represents the selected component, which take only primitive types and Strings as arguments. So, let's change the 'spacing' property and set it to '10px'. This means that all the children components of this VBox will have an in-between vertical spacing of 10px each.
Now, let's put the logo image on the screen. Drag the 'Image' component from the 'Basic' tab and drop it onto the VBox. This is automatically appended as a child to the VBox element. Display its properties and set the image source by using a relative application path, such as '/images/logo/mylogo.png'. If the image exists on the specified path it will immediately get displayed onto the canvas. If you want the logo to take up the whole screen's width, change the VBox's width first and then adjust the Image's width accordingly.
For laying out the Label !V Textbox !V Image combination, we need two separate HBox components - that will layout the components vertically !V which will be appended as children to the VBox element. So drag an HBox component from the toolkit and drop it onto the VBox. It will be displayed at the bottom of the tree, under the logo Image component. Now, drag an Image, a Label and a Textbox component and drop them onto the Hbox. You will see them on the canvas all side-by-side. If you like you can again adjust the spacing between them from the Hbox's properties. Now, select each element in turn on the tree and set its properties. Set the Image source and the Label's value. And the username set is ready!
For saving time, instead of repeating the procedure for the password set, select the Hbox on the tree, right-click and select the 'Copy Element' command. Then select the VBox, right-click and select the 'Paste Element' command. Nice uh? All you have to do now is change the Image and Label to the appropriate values and set the Textbox's 'style' property to 'password'. Now you can try out the component's so far on the canvas and check that the password text box displays '*' chars instead of the actual text.
Finally, drag a Button element from the toolkit and drop it onto the Vbox again - to place it on the bottom of the other elements - and set its 'label' property to display the required string (e.g. 'Sign In').
That's it! Well, how hard was that? It takes less than 2 minutes to design a page like this!
Note: Although not required, it is recommended that you give each newly created component on the canvas a meaningful Id, so that the model is well clarified. This is particularly important when dealing with events and binding the business logic to the page.
Now, after the design is finished, you normally want to see how the page looks like and behaves in real-time mode. Just click on the 'Preview Page' button on the toolbar and the page gets displayed on a new window, so that you can check the look-and-feel and have normal interaction with it.
And now some magic! Right click on the Button element and select the 'Display Events' command. A modal dialog will be displayed and you will get the list of all available events registered with the Button component. Enter a test event action on the 'onClick' event (e.g. 'alert("I was clicked!"), update it and see what happens when you click the button on the canvas. Well, this is what I call real-time behavior!
In order to save the design, click on the corresponding toolbar button and enter the name of the '*.zul' file you want to save the design into (you don't have to enter the '.zul' extension). The design is automatically saved under the '/saved_designs/' application path. Check out the ZUL file and see that the structure is exactly the same as the one you would have written by hand in a similar scenario. You can later reload the file onto the canvas and modify it, or you can include it in another design as well.
Now, if you want to check out how the page behaves with some custom code, create a test class !V let's say 'test.TestClass.java' !V and put it into the designer's runtime either as a compiled class, or even better under the /WEB-INF/lib path within a packed *.jar file. Write a static method !V let's say 'public static void onLogin()' !V which will contain the required login validation code !V or even a System.out.println() statement just to see that the method is called. As soon as the class is compiled and plugged into the runtime, set the action of the Button event to 'test.TestCase.onLogin()' and once again click the button.
Well, this is it. Design the page, write the code, pack it in a *.jar file and bind it with events. In this way, you can change the UI without messing with the business logic and vice-versa!
In Part II I'm going to show you how easy it is to write custom components built upon the ZK framework and plug them in directly to the designer's toolkit. Info:
The Zero Kode designer was developed on top of the latest version of the ZK Framework(Editor's note: it is upgraded to work with ZK 2.1.1 and later). The development tool was Eclipse 3.2 and the application server used was Apache Tomcat v5.x. Although the tool was written running a Java 5 runtime, it was designed to have backwards compatibility with Java 1.4.x.
Chris Spiliotopoulos is a software architect living in Athens, Greece. You can contact him at firstname.lastname@example.org
Copyright c Chris Spiliotopoulos. This article is licensed under GNU General Public License.
|Copyright © Chris Spiliotopoulos. This article is licensed under GNU Free Documentation License.|