`
kelly.zhang
  • 浏览: 52922 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

ZK Rich Client Framework and Agile Development

阅读更多
ZK Rich Client Framework and Agile Development

Discuss this Article

Introduction

This article has two parts – a discussion followed by a tutorial.

In the discussion, I will explain why rich client frameworks in general, and ZK in particular, not only allow for more pleasing, powerful UIs, but aid in applying an “Agile” development methodology. The discussion is based on the real experience of my firm which has been programming business applications with both “32-bit” and traditional web GUIs for years, but over the last year has implemented a shift towards using a rich client approach, with extremely positive results.

In the tutorial, I take you through the basics of introducing ZK into your existing web application. The tutorial has a step-by-step approach but aims to highlight, from the start, the most useful structural features of ZK from the point of view of developing complex applications.

I have been programming “web stuff” for 12 years and Java for almost 10, so this article is focused on people with a solid background in both general Java programming and Java Web Application development. Nevertheless, I believe that the first, discussion part of the article will be of more general interest to anyone working with complex web applications on whatever platform.

Agile Development and Web Applications

Here I base my discussion on the Agile Methodology used in my own firm, Crystal Clear (Crystal Clear: A Human-Powered Methodology for Small Teams, Alistair Cockburn, 2004). I started working with the web, and programming, well before I had heard of "Agile" anything, but looking back, there were several fundamental issues that, in my opinion, reduced productivity (in terms of valid, working Use Cases), as compared to a "Windows 32" GUI or RAD/4GL project.

1) The heterogeneous bundle of technologies involved: instead of just Java, also HTML (later including CSS and JavaScript), HTTP, Struts or whatever framework, with several different XML file formats thrown in for good measure. Each of these technologies had its own learning curve, plus the "teaching curve" of explaining it (and the team’s particular way of using it) to new members. Every project I ever worked on spent a fair while choosing and tweaking its chosen "frameworks" and only then getting up to speed. On several projects, experienced programmers (with, admittedly, inexperienced project managers), became distracted by framework rewriting and "optimization" for months on end. These problems were not caused by the wide variety of technologies but I do believe they were exacerbated by them.

With the "bundle" approach, there are simply MORE lines of code (of whatever kind) to write, and MANY points at which one file depends on or refers to another, very often in a way that the compiler cannot check (ex. a URL which points to a Struts action path which refers to an Action class written in Java). Costly write, redeploy, run test cycles are therefore needed to detect even simple syntactical errors. There are many studies (see http://en.wikipedia.org/wiki/Lines_of_code for an introduction to the discussion) which show that, in general, the more LOC a programmer writes, the more errors they make.

2) Difficulty of prototyping. One of the principles of CC (and Agile methodologies in general), is to focus day to day work on final and not intermediate deliverables (for example, UI screens instead of Use Case documents) as a way to both reduce technical risk (because you are forced from very early on, to use your chosen technologies to produce real results) and requirements risk (because users get to see real, understandable screens and functionalities and discuss them verbally), without increasing the effort in terms of person-hours. Ideally, the team will work in fairly short cycles of 1-2 weeks, roughing out new Use Cases as evolutionary prototypes, having a customer viewing, then reworking them in time for the next or next but one viewing. Done properly, both developer and user representatives can keep the "state of the conversation" reasonably warm in their heads, allowing a rich flow of communication about requirements and changes, through the iterations. The longer each iteration takes for a particular use case, the worse the quality of this communication and the more it needs to be supplemented by costly formal mechanisms (detailed written use cases, review meetings, client review of issue tracker reports at a detailed level, etc.)

The reduced productivity I referred to above, simply makes many typical CRUD (Create-Read-Update-Delete) use cases take MORE THAN A WEEK to "knock up". So instead of the programmer coming out of a meeting, spending 3 working days making alterations based on the last user viewing, the 4th day performing the weekly build/release, and the 5th day at the next user viewing, the minimum cycle becomes 2 or even three weeks.

3). Limited UI. Most users in the industrialized world are now fairly computer literate, and expect a 21st-century "fancy" UI which makes full use of mouseovers, right-click, collapsible popup menus, keyboard shortcuts etc. And interestingly, in the less industrialized countries (where my firm is based), first-time users of IT systems can learn ANY kind of UI reasonably quickly provided they are given the right training and management support and guidance in the critical early period. What they DO have a problem with are "non-intuitive" UIs, which shift the whole appearance of the screen (and the thus the context information in the user's short term memory) when all they did was perform a single action, to see a single piece of information. And web UIs traditionally suffer from this. Yes, today we have broadband and a whole host of page composition technologies (such as Tiles, Regions, Portlets, SiteMesh etc) but "traditional" webapps are still fundamentally based on the click, post, process, reload entire screen paradigm. One large intranet project I worked on specifically designed the whole system (thousands of screens) to be based on almost "one field per screen", in part to fit within this model, principally because the value selected in one list informed another dropdown list how to populate itself. Unfortunately the system is heavily based around data entry from a variety of paper forms, and the early adoption of the system suffered greatly from the difficulty users had in taking a one-A4-page form, and filling it into 6 separate screens, each of which required the user to hunt around the paper form to find the corresponding piece of data.

Once again, the technology was not the only culprit here - the project had the budget to hire usability specialists and ignored various recommendations to do so - but it was an important contributing factor.

In the early days of the web's adoption by the mainstream (here I mean from about late 1995 onwards), some alternative UI technologies emerged, such as Java Applets and ActiveX controls. However they never really became serious contenders for a variety of reasons, principally related to security and browser compatibility (although I have seen some great individual examples of systems with fairly specific user communities, based on both of these technologies).

Now, I hear you cry - you are living in the past! Struts is outdated! There is AJAX! And Web 2.0!! Dude! Well, it is true that in recent years several extremely powerful frameworks for building serious webapps have become available - for instance:

  • Hibernate for the backend, reaching the goal that EJB never quite attained (full disclosure: my firm uses neither EJB nor Hibernate, but the OFBiz Entity Engine (REF), an ORM technology in many ways similar to Hibernate)
  • Spring for configuration and "everything else".

In terms of the frontend, there is no doubt that many new frameworks have emerged which offer productivity improvements relative to "granddaddy struts". As well as this, AJAX, JSTL, EL (JSP Expression Language) and HTML DOM have reached a sufficient level of adoption between major browsers (see current statistics at: http://marketshare.hitslink.com/report.aspx?qprid=0) that designing your application to use such technologies throughout, has become entirely feasible.

However the three problems I outlined above still, in my opinion, remain. You still end up writing a frontend UI layout which requires the developer to know, and agreed project-specific conventions for using:

  • HTML, both tags and DOM
  • CSS
  • JSP EL
  • JavaScript (often souped up with prototype, script.aculo.us, DOJO etc)
  • JSTL
  • HTTP (to understand processing flow)
  • XML in several formats (for data representation in AJAX calls, and for configuration files)

Problem (3) - Limited UI - can be to a large extend mitigated but only to the extend of increasing rather than reducing the cognitive and LOC load on the programmer (Problem 1), with concomitant effects on the release/user viewing cycle (Problem 2).

Enter "Rich Client Frameworks".

More recently still, really in the last two years or so, several potential solutions have emerged (and more continue to emerge), which aim to bring all the above technologies together to provide a better experience for both user AND developer. About a year ago, my firm decided to switch all of our web-based products (currently 3) to one of these frameworks. We were not worried about jumping on the Web 2.0 bandwagon, but we WERE focused on providing a boost to productivity by dealing with the three issues I outlined at the start.

For this reason, we first classified the frameworks we found out about into three levels. We then took those which fell into the last level - those which we really felt made a productivity "quantum leap" possible - and further analyzed them according to the following set of criteria:

  1. Genuine cross-browser compatibility (no need for plugins or special configuration tricks at the client side)
  2. Number of distinct coding/configuration languages involved (less is better)
  3. Speed of development, particular the ability to use a declarative language for UI layout (like GNOME/GTK).
  4. Financial cost, both initial and ongoing
  5. Maturity and long-term sustainability

Here are the rankings we came up with. First the "three levels", then the detailed analysis.

They are NOT meant to start a flame war!! We are a small company, we wanted a decision in a limited timescale, we wanted a decision in a limited timescale, and we took one. Furthermore, the marketplace is changing rapidly - the open-sourcing of Adobe Flex and the appearance of YUI are two examples of this.

We have not regretted the decision we made - but that is not to say that other firms might wish to use a different analytical framework - or use our framework and come up with different results. However I do believe that our analysis is general enough to be of interest to a large proportion of the Java Web Development community.

Table 1 - "the three levels"

    Level Description Technologies Considered
    1 JavaScript libraries which help you add Web 2.0 features into a traditional DHTML page. rico script.aculo.us prototype
    2 As level 1, but include some kind of server-side component which helps you communicate from your page running in the browser, to a program object running on the server. DWR Dojo
    3 "Fully fledged UI replacements". Allow you to write all your code on the server, and automatically take care of getting the UI to the client, and the interaction between client and server. Echo2 ZK OpenLaszlo Flex GWT

Table 2 - Detailed comparison of the Level 3 contenders

+ means good, yes it has this feature (score 1.0)

- means bad, it lacks this feature (score 0)

~ means "to a certain extent" (score 0.5)

Feature Echo2 ZK OpenLaszlo Flex GWT
a ~ + ~ - +
b + + ~ ~ +
c ~ + + + -
d + ~ + ~ +
e - + ~ + +
SCORE 3.0 4.5 3.5 3.0 4.0

Here are some brief notes about why I gave each technology the score I did:

  • Echo2 (http://www.nextapp.com/platform/echo2/echo/): is free and Open Source (Mozilla Public License). However it is extremely buggy and immature still, and appears maintained by a very small part-time team, which means that some fairly basic bugs stay around on the forums for ages. It does have the advantage of an Eclipse-plugin IDE. It is similar to GWT in that building up a page requires a developer to build up (in Java) a tree of UI component objects.
  • ZK (http://zkoss.org/): has a dual GPL/Commercial licensing model. This means that GPL or compatibly-licensed products can use it for free, while other products need to pay on a per-CPU or per-developer basis. Perpetual licenses are available. It is pretty mature, although occasionally small bugs are found. They tend to be fixed within the next minor release by the team. It allows declarative definition of pages in XML, and scripting in Java Beanshell (http://beanshell.org). It has a visual editor (Zero Kode) which is itself a JEE webapp – although personally I have not used this and would prefer an Eclipse-based plugin.
  • OpenLaszlo: (http://www.openlaszlo.org/): very similar to ZK in terms of philosophy and architecture except that:
    • It uses JavaScript (ECMAScript) for scripting, rather than Java Beanshell
    • It has a more flexible license Open Source (Common Public License)
    • It required the Flash plugin in client browsers until very recently. Full DHTML deployment was released last month – I originally tried out OL over a year ago and gave up waiting for DHTML support
    • It does not have an IDE (an Eclipse plugin was in development but has been discontinued)
  • Flex (http://www.flex.org/): is perhaps the grandaddy here, it is a mature platform for rich client development. It requires browsers to have the Flash plugin. It has an XML language for declarative page definition, and uses ActionScript (syntactically similar to JavaScript) fro scripting. Until quite recently it was very pricey for production use although the price has come down. A powerful commercial IDE is available. Adobe has announced that it plans to release Flex under the Mozilla Public License although this is still just a plan.
  • Google Web Toolkit (http://code.google.com/webtoolkit/): is Open Sourced under the Apache 2.0 license. It is very similar to Echo2 in that you build up the UI via a tree of Java UI objects. Obviously, it has slightly more heavyweight backing than Echo2! Third-party IDEs/plugins are available for Eclipse, IntelliJ IDEA and standalone.

Based on this, ZK pipped GWT to the post - although the pip was quite a big one. Basically, ZK offers the ZUML language for declarative page layout and GWT has nothing comparable to this - in GWT you must define your layouts by building them as object trees in a step by step way. In ZK you can do this, whenever you want to, but perhaps 80% of the time you can declare the same tree in a more concise and intuitive way using the ZUML, a simple XML-based UI markup language.

A secondary factor which helped in the final decision was ZK’s extensibility. It comes with built-in integration and extension points for several popular technologies such as Spring, Google Maps, the FCKEditor online rich text editor, and DOJO. As we do not use all these technologies at the moment, we certainly plan to use some of them in the medium term and it was helpful to know that we were not shutting ourselves off from them by choosing ZK.

Results

We went with ZK at the end of last year, and within a month had fully integrated it into our existing spring-based web framework (including authentication, authorization, i18n and transaction management) and applications (that is, we were able to phase it in gradually to existing webapps, some of which now even have "hybrid" screens with some parts ZK and others DHTML/JSP. We did not have to rewrite any existing screens).

Since then we have noticed the following progress on the three problems outlined at the start of this article.

1) Technology Splurge. We reduced our technology base to two: Java (often written in Beanshell, which allows us to omit type declarations and take a few other shortcuts, IF WE WANT) and the aforementioned ZUML markup language. All ZUML elements and attributes correspond to Java classes and methods in an obvious and consistent way, so whatever we can write in ZUML, we can do programmatically should we wish to. Browser-Server communication is transparent (although there are many points at which you can interact with it should you wish to, either for performance reasons or to interact with custom scripts).

All of our developers who have changed to ZK have enjoyed it and none want to go back. Warm-up time for new team members has been reduced to about an hour for the frontend part of our applications! Previously, it was at least a day, even if they were already familiar with the technologies we used.

2) Development cycles. A developer is now capable of thinking up his UI on the way back from a user viewing, knocking it up in the 30 minutes immediately following the viewing, while discussing it with other team members over his shoulder, and having all of the new functionality (including middle and backends) dealt with, plus unit tests, within a week (normally) or two weeks (maximum, for changes which significantly alter the data model). We spend more time talking about the system and less time talking about syntax, config file locations and technology gotchas.

3) UI Richness. We can do pretty much anything we could in a Native GUI - the relevant tags and UI elements are intuitively named and well documented. Performance CAN be an issue - for instance comboboxes with hundreds of items take a long time for the browser to render - but overall application richness, cohesiveness of information, and ease of use is up. Tree controls, search-as-you type, floating popups etc. And we do all this in one ZUML file - occasionally making use of a reusable beanshell script for reuse between pages. Our beanshell code effectively calls our Spring beans directly, meaning that our middle layer did not have to change AT ALL - it just got easier to access from the frontend!

Well, that was the hot air! Now let's try it out in practice. The following tutorial should take no more than 1 hour to complete for someone familiar with standard J2EE webapps and their application server of choice (we use Tomcat 5.5).

Introductory Tutorial

This tutorial explains how to use a "rich client" web UI, inside the Apache Tomcat 5.5 Web Application Server, via the ZK Rich Client framework.

Prerequisites

  1. JDK 1.5 or 1.6, with the JAVA_HOME environment variable set correctly.
  2. Tomcat 5.5 or 6.0 installed and working correctly, in a directory which we will refer to as TOMCAT_HOME from now on.
  3. A webapp (either your own or one of the Tomcat sample webapps) already working, that you are happy to mess around with as a sandbox. You should be comfortable with configuring a J2EE webapp via web.xml.

Preparation

  1. Download the latest stable binary (2.4.1 at the time of this writing) of ZK from here: http://potix.com/download/Your browser may not support display of this image.
  2. Unzip this binary to a temporary directory, which we will call ZK_DIR
  3. Make a shortcut to the PDFs in ZK_DIR/doc as you will consult them frequently - zk-devguide.pdf is the most useful

Installing ZK framework in your OFBiz webapp

  1. Copy the 6 “z*” jars from ZK_DIR/dist/lib onto the classpath of your webapp.The standard way to do this is to put them in webapp/WEB-INF/lib.
  2. You may also need to copy the following jars from ZK_DIR/dist/lib/ext, if your webapp does not have them already:
    • bsh.jar
    • commons-el.jar

    The remaing jars in the ext and zkforge subdirs are not need for this tutorial.

  1. Now we must register the various bits of the ZK engine in our webapp. Edit your web.xml, and without removing anything you already have registered here, insert the following snippets. Note that the comments are mine, they should help you understand what each bit does, although it is unlikely you will have to tweak these settings any further, they work “Out of the box”.
<!--- ZK: 1.1: servlet for ZK pages -->

      <servlet>

        <description>ZK loader for evaluating ZK pages</description>

        <servlet-name>zkLoader</servlet-name>

      <servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>

        <init-param>

         <param-name>update-uri</param-name>

         <param-value>/zkau</param-value>

        </init-param>

        <load-on-startup>1</load-on-startup>

      </servlet>

<!--- ZK: 1.2: map.zul and .zhtml requests to this servlet -->

      <servlet-mapping>

        <servlet-name>zkLoader</servlet-name>

        <url-pattern>*.zul</url-pattern>

      </servlet-mapping>

      <servlet-mapping>

        <servlet-name>zkLoader</servlet-name>

        <url-pattern>*.zhtml</url-pattern>

      </servlet-mapping>

<!--- ZK: 2.1: servlet which handles client-server comms -->

      <servlet>

        <description>The asynchronous update engine for ZK</description>

        <servlet-name>auEngine</servlet-name>

        <servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class>

      </servlet>

      <servlet-mapping>

        <servlet-name>auEngine</servlet-name>

        <url-pattern>/zkau/*</url-pattern>

      </servlet-mapping>


<!--- ZK: 3: make sure the browser will treat relevant file types correctly -->

      <mime-mapping>

        <extension>js</extension>

        <mime-type>application/x-javascript</mime-type>

      </mime-mapping>

      <mime-mapping>

        <extension>zhtml</extension>

        <mime-type>text/html</mime-type>

      </mime-mapping>

      <mime-mapping>

        <extension>zul</extension>

        <mime-type>text/html</mime-type>

      </mime-mapping>

    4. Start (or restart) Tomcat and check that nothing nasty comes out in the logs!

Part 1 - your first ZUML page

Now we're going to make a very simple page using ZUML (the ZK User Interface Markup Language). In my firm we call these "ZULs", after the file extension, since it is much easier to say than ZUML.

1. Create a file hello1.zul in the root of your webapps and paste the following code into it:

<?page title="Title for the Browser"?> <!-- sets browser window title -->

<window title="Title for Window"> <!-- creates a window within HTML body -->

Click here: <button label="Yes here!"/>

</window>

2. Now visualize it in your browser via the obvious URL (just as if it were a JSP). For instanceif your webapp was deployed on a server listening on port 8081 and running at the context path /zk, you would use the URL:

It should look something like this:

4. So far, clicking the button does nothing so let's put in a bit of interactivity. Alter your ZUL to look like the following...

<?page title="Title for the Browser"?> <!-- sets browser window title -->

<window title="Title for Window"> <!-- creates a window within body -->

<zscript> <!-- ONE -->

  clickCount = 0;   //TWO

  clickIt()

  {

       clickCount++;  //register the click

       countLabel.value = "Clicks: " + clickCount; // THREE: update screen

  }

</zscript>

Click here: <button label="Yes here!" onClick="clickIt()"/>

<label id="countLabel" value="Clicks: ${clickCount}"/> <!--  FOUR -->

</window>
  1. Refresh the page in your browser, to force the ZUL to be reinterpreted, then try clicking the button and see what happens. You should end up with something like this:
  1. Now look at the lines with ONE, TWO comments and note the following interesting points....
  • ONE: by default, a zscript element just contains Java beanshell code. By declaring our zscript block inside the window, we have access to all the window's child components simply by referring to the value of their id attributes.
  • TWO: this variable clickCount exists within the scope of this window, until a page refresh occurs. Prove this to yourself by clicking it several times, then refreshing the page via your browser – the value should go back to 0.
  • THREE: here we refer directly to the label element below. We also use a syntactic sugar countLabel.value =, which is the same as saying countLabel.setValue()
  • FOUR: the original displayed value of countLabel uses standard JSP Expression Language, to get at the value of the clickCount page-scoped variable. This only works at page interpretation time (refresh). After that, we have to use an event-handler (our clickIt() method), to dynamically access the label object and update its internal state.

6. At this stage you are ready to play with all the different UI widgets ZK has to offer. If you would like to do this, work your way through the zk-quickstart.pdf tutorial. However in the current tutorial I will jump onwards to showing how a ZK user interface can manipulate your data.

Part 2: Integration with the rest of your application

In this part, we will do something really useful for the first time - get an data entity from a list, alter it, and persist the changes. In this tutorial I will use a POJO retrieved by a “Manager” object which has fetch, and updates. How the manager actually get the object to and from the database is outside the scope of this tutorial but typically it would have come from Hibernate, Spring JDBC, an EJB or some such persistence mechanism)

In this example, let's assume that our objective is to show a dropdown list of all the Person entities stored in our system, and allow the user to alter their first name. I will assume that we already have defined, the Person class representing our data, and a PersonManager which knows how to get it to and from the database as described above.

You can download the source code here.

1. Lets start off by getting a PersonManager and using it to list all the Person instances - we will store the result in a variable. The code should be pretty self evident, it is simply beanshell, using the API of the classes we mentioned above.If you haven't used beanshell before, the only strange bit might be that it allows us to skip type declarations, as the code is interpreted rather than compiled.

The interesting bit is in the screen, where we use the special forEach attribute to iterate all the Persons and make a dropdown list from them. We can access fields on the each iterator variable (in ZK it is always called each) with the Expression Language DOT notation. And finally, see how we use the value attribute of each listitem, to hold a reference to the Person - not its PK but the actual POJO itself. This will come in handy in the next step.

<?page title="Tutorial 3"?>

<window title="Tutorial 3 Window">

<zscript>

  //standard Java import of the POJO and its manager

  import tutorial.Person;

  import tutorial.PersonManager;



  //create manager and add some test POJOs (in real system they'd come from the backend)

  manager = new PersonManager();

  manager.addPerson(new Person("Cameron", "Smith"));

  manager.addPerson(new Person("Django", "Reinhardt"));



  //now create a variable within the window scope holding all our POJOs

  persons = manager.listPersons();

</zscript>

  <!-- the listbox below will be built from the list of POJOs -->

  <listbox mold="select">  <!-- mold: select means a dropdown list -->

   <listitem forEach="${persons}" label="${each.firstName} ${each.lastName}" value="${each}"/>

  </listbox>

</window>

Here is a shot of the list being used:

2. Now that we can list our people, we need to have a screen for editing them. The next code sample expands upon the first by creating a little edit form but keeping it hidden until the user actually selects a person for editing. Pay special attention to the parts in bold, where we take advantage of the selected listitem's value payload - a Person entity. Also note how we use the grid component to layout the other components nicely.

At this point we should also learn another handy feature of ZUML – all tags representing GUI components are implemented by Java classes in the package org.zkoss.zul. To work out the name of the implementing class, simply capitalize the first letter of the tag name, for instance:

    <textbox> --> org.zkoss.zul.Textbox

    <listbox> --> org.zkoss.zul.Listbox

Except for certain special attributes, all attributes correspond to standard Java bean getter/setter methods on these classes. This means that, as well as using the zk-devref.pdf to check what attributes you can use, you can simply look at the relevant implementing class in the Javadoc at: http://www.zkoss.org/javadoc/2.4.1/zul/

Be careful, however, of relying too much on beanshell's syntactic sugar: firstName.value = person.firstName; only works because the method Textbox.setValue() in fact takes a String parameter (as you can see here: http://www.zkoss.org/javadoc/2.4.1/zul/org/zkoss/zul/Textbox.html#setValue(java.lang.String) ), and Person.getFirstName() also returns a String. That is, you can omit type declarations but beanshell will not perform automatic conversions – you must still obey standard Java rules for the type of expressions.

<?page title="Tutorial 4"?>

<window title="Tutorial 4 Window">

<zscript>

  import tutorial.Person;

  import tutorial.PersonManager;



  manager = new PersonManager();

  manager.addPerson(new Person("Cameron", "Smith"));

  manager.addPerson(new Person("Django", "Reinhardt"));



  persons = manager.listPersons();



  //define a method for event handler to call - in beanshell no need for types

  selectPerson(person)

  {

      //populate the edit form

      firstName.value = person.firstName;

      lastName.value = person.lastName;



      //and make it visible

      editRow.visible = true;

  }

</zscript>

<grid>

  <rows>

   <row>

      Select the person you wish to edit

    <listbox mold="select" onSelect="selectPerson(self.selectedItem.value)">

       <listitem value="--- SELECT BELOW ---"/>

     <listitem forEach="${persons}" label="${each.firstName} ${each.lastName}" value="${each}"/>

    </listbox>

   </row>

   <row id="editRow" visible="false">

      <textbox id="firstName"/><label id="lastName"/>

   </row>

  </rows>

</grid>

</window>

And a screenshot showing what happens after we select one of the list items:

3. Finally, let's add a Save button and make it do something. Note how we dynamically update the person's name on the list, too. Given that all ZK GUI components are standard Java objects as we saw above, then it stands to reason that they can be dynamically manipulated via beanshell or Java in this way.

<?page title="Tutorial 5"?>

<window title="Tutorial 5 Window" width="500px">

<zscript>

  //standard Java import of the POJO and its manager

  import tutorial.Person;

  import tutorial.PersonManager;



  manager = new PersonManager();

  manager.addPerson(new Person("Cameron", "Smith"));

  manager.addPerson(new Person("Django", "Reinhardt"));



  persons = manager.listPersons();



  selectPerson(person)

  {

      //populate the edit form

      firstName.value = person.firstName;

      lastName.value = person.lastName;



      //and make it visible

      editRow.visible = true;

  }



  savePerson()

  {

      person = personList.selectedItem.value; //get person object from the list

      person.firstName = firstName.value;     //update it based on the textbox

      manager.updatePerson(person);           //ask manager to register update

      personList.selectedItem.label = person.firstName + " " + person.lastName;

  }

</zscript>

<grid>

  <rows>

   <row spans="1,2"> <!-- spans distributes the colspans of the first grid row, since it only has 2 things -->

      Select the person you wish to edit

    <listbox id="personList" mold="select" onSelect="selectPerson(self.selectedItem.value)">

       <listitem value="--- SELECT BELOW ---"/>

     <listitem forEach="${persons}" label="${each.firstName} ${each.lastName}" value="${each}"/>

    </listbox>

   </row>

   <row id="editRow" visible="false">

      <textbox id="firstName"/><label id="lastName"/><button label="Save" onClick="savePerson()"/>

   </row>

  </rows>

</grid>

</window>

Here are a couple of screenshots, immediately before and after the button click. Notice how the updated Person's name appears in the list, because of the line in bold.

Next Steps

I plan to follow up this tutorial with two more, on the topics listed below, which to me are the most important from a team productivity point of view. However I welcome suggestions for other topics – as well as criticisms and comments on this one!

References

For your convenience, here are the URLs of all the technologies and tools used in this tutorial:

    • QuickStart: a fast introduction to the basic elements of ZK
    • DevGuide: an in-depth, narrative explanation of the whole framework, including its architectural underpinnings
    • DevRef: a comprehensive reference for all the tags, implicit objects and other structural aspects of the framework
  • ZK “Small Talks”: a regularly-updated set of mini-tutorials looking at particular aspects of ZK and especially “howtos” for integrating it with other languages. http://www.zkoss.org/smalltalks/

About the Author

Cameron Smith comes from Glasgow, Scotland and started “messing with computers” while studying for his first degree, in Politics. Several years and various jobs later he graduated from an Msc in Information Technology at Glasgow University. Since then he has worked as a programmer and team leader in various companies, generally in systems integration and web application projects for the Financial Services and Government sectors. He is currently Director of Projects at Database, Lda, a privately-held IT Software & Services firm based in Maputo, Mozambique.

You can contact him at: cameron DOT ord AT database DOT co DOT mz

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics