ZK Version : 6.5.0
Concepts used in this example
- hbox is a layout component that arranges its child components horizontally.
- We have used List box to display three column listing.
- We also used the "emptyMessage" attribute is used to show a message when listbox contains no items.
- In ZK, the controller is responsible for controlling ZK components and listening to events triggered by user interaction.
We can create a such controller class by simply extending org.zkoss.zk.SelectorComposer. - We also used Annotation in the composer using ZK Select Composer.
- MVC Developer reference
- We are using Listbox Template concept to display the data.
Step 1:
If you are new ZK, then first we need to setup the development environment. This document will help you to do the same.
Step 2:
Let us create the Project in eclipse. Click File -> New -> ZK Project . Let us name the project as ZKMVCListing1. After creating the New ZK Project, the folder structure should look as follows
Step 3:
Now let us add the domain class car as follows. Note: We will create a package called "demo" and then we will create our class "car" in that.
1: package demo;
2:
3: public class Car {
4:
5: private Integer id;
6: private String model;
7: private String make;
8: private String preview;
9: private String description;
10: private Integer price;
11:
12: public Car(){
13: }
14:
15: public Car(Integer id, String model, String make, String description, String preview, Integer price){
16: this.id = id;
17: this.model = model;
18: this.make = make;
19: this.preview = preview;
20: this.description = description;
21: this.price = price;
22: }
23: public Integer getId() {
24: return id;
25: }
26: public void setId(Integer id) {
27: this.id = id;
28: }
29:
30: public String getPreview() {
31: return preview;
32: }
33: public void setPreview(String preview) {
34: this.preview = preview;
35: }
36: public String getDescription() {
37: return description;
38: }
39: public void setDescription(String description) {
40: this.description = description;
41: }
42: public Integer getPrice() {
43: return price;
44: }
45: public void setPrice(Integer price) {
46: this.price = price;
47: }
48:
49: public String getModel() {
50: return model;
51: }
52:
53: public void setModel(String model) {
54: this.model = model;
55: }
56:
57: public String getMake() {
58: return make;
59: }
60:
61: public void setMake(String make) {
62: this.make = make;
63: }
64:
65: }
Step 4:
We then define a service class to perform the business logic (search cars) shown below:
CarService.java
1: package demo;
2:
3: import java.util.List;
4:
5: public interface CarService {
6:
7: /**
8: * Retrieve all cars in the catalog.
9: * @return all cars
10: */
11: public List<Car> findAll();
12:
13: /**
14: * search cars according to keyword in model and make.
15: * @param keyword for search
16: * @return list of car that match the keyword
17: */
18: public List<Car> search(String keyword);
19: }
Step 5:
In this example, we have defined a class - CarServeImpl that implements the above interface. For simplicity, it uses a static list object as the data model.
CarServiceImpl.java
1: package demo;
2:
3: import java.util.LinkedList;
4: import java.util.List;
5:
6: public class CarServiceImpl implements CarService {
7:
8: // data model
9: private List<Car> carList = new LinkedList<Car>();
10: private static int id = 1;
11:
12: // initialize book data
13: public CarServiceImpl() {
14: carList.add(new Car(
15: id++,
16: "Primera",
17: "Nissan",
18: "The Nissan Primera was produced between 2002 and 2008. It was available as a 4-door sedan or a 5-door hatchback or estate."
19: + " The entry-level 1.6-liter petrol feels underpowered for a large car. The 1.8-liter petrol is keen, the refined 2.0-liter unit is the star performer. An improved 2.2-liter turbodiesel performs well, but is only relatively economical, as it's competitors in this class with similar characteristics offer even lower fuel consumption.",
20: "img/car1.png", 23320));
21: carList.add(new Car(
22: id++,
23: "Cefiro",
24: "Nissan",
25: "The Nissan Cefiro is an intermediate-size automobile range sold in Japan and other countries. It was available only as a 4 door sedan. A large proportion were equipped with automatic transmissions. Originally marketed towards the Japanese salaryman the top model used the same engine as found in the R32 Nissan Skyline, a 2 litre turbo charged 6 cylinder engine capable of just over 200 hp (150 kW). Other variants came with other versions of the Nissan RB engine. Brand new, the Cefiro was slightly more expensive than the equivalent Nissan Skyline.",
26: "img/car2.png", 38165));
27: carList.add(new Car(
28: id++,
29: "Camry",
30: "Toyota",
31: "The Toyota Camry is a midsize car manufactured by Toyota in Georgetown, Kentucky, USA; as well as Australia; and Japan. Since 2001 it has been the top selling car in the United States.The Holden equivalents were not successful even though they came from the same factory as the Camry. Since 2000 Daihatsu has sold a Camry twin named the Daihatsu Altis. The name comes from the English phonetic of the Japanese word \"kan-muri,\" which means \"crown.\"",
32: "img/car3.png", 24170));
33: carList.add(new Car(
34: id++,
35: "Century",
36: "Toyota",
37: "The Toyota Century is a large four-door limousine produced by Toyota mainly for the Japanese market. Production of the Century began in 1967 and the model received "
38: + "only minor changes until redesign in 1997. This second-generation Century is still sold in Japan. The Century is produced in limited numbers and is built "
39: + "in a \"nearly hand-made\" fashion. It is often used by royalty, government leaders, and executive businessmen. Although the Century is not exported outside Japan in large numbers, it is used frequently by officials stationed in overseas Japanese offices. In contrast to other luxurious cars (such as the Maybach or a Rolls Royce), the Century has not been positioned and marketed as a sign of wealth or excess. Instead, the Century projects an image of conservative achievement.",
40: "img/car4.png", 28730));
41: carList.add(new Car(
42: id++,
43: "Sigma",
44: "Mitsubishi",
45: "The third-generation of Japanese car Mitsubishi Galant, dating from 1976, was divided into two models: the Galant Sigma (for the sedan and wagon) and the Galant Lambda (the coupe). The former was sold in many markets as the Mitsubishi Galant (without the word 'Sigma') and in Australia as the Chrysler Sigma (until 1980, after which it became the Mitsubishi Sigma). Strangely, in New Zealand it was badged as 'Galant Sigma' but colloquially referred to as the 'Sigma', a name it formally adopted after 1980.",
46: "img/car5.png", 54120));
47: carList.add(new Car(
48: id++,
49: "Challenger",
50: "Mitsubishi",
51: "The Mitsubishi Challenger, called Mitsubishi Pajero Sport in most export markets, Mitsubishi Montero Sport in Spanish-speaking countries (including North America), Mitsubishi Shogun Sport in the UK and Mitsubishi Nativa in Central and South Americas (the Challenger name was also used in Australia), is a medium sized SUV built by the Mitsubishi Motors Corporation. It was released in 1997, and is still built as of 2006, although it's no longer available in its native Japan since the end of 2003.",
52: "img/car6.png", 58750));
53: carList.add(new Car(
54: id++,
55: "Civic",
56: "Honda",
57: "The eighth generation Honda Civic is produced since 2006. It is available as a coupe, hatchback and sedan. Models produced for the North American market have a different styling."
58: + " At the moment there are four petrol engines and one diesel developed for this car. The 1.4-liter petrol is more suitable for the settled driving around town. The 1.8-liter petrol, developing 140 hp is a willing performer. The 2.2-liter diesel is similar to the Accord's unit. It accelerates rapidly and is economical as well. The Honda Civic is also available with a hybrid engine. In this case engine is coupled with an automatic transmission only. The 2.0-liter model is available with the paddle shift gearbox.",
59: "img/car1.png", 17479));
60: carList.add(new Car(
61: id++,
62: "New Beetle",
63: "Volkswagen",
64: " The Volkswagen Beetle is produced since 1998. It is available as a coupe or convertible."
65: + " The VW Beetle is powered by a wide range of engines, including two 1.9-liter turbodiesels, and turbocharged 1.8-liter petrol. There is also a 3.2-liter RSI available for the range topper."
66: + " The new Beetle has nothing in common with the rear-engined original, except the 'retro' design. It is based on the VW Golf and has the same solid build quality.",
67: "img/car2.png", 67540));
68: carList.add(new Car(
69: id++,
70: "Golf V",
71: "Volkswagen",
72: "The Volkswagen Golf V is produced since 2003. There is a wide range of fine and reliable engines. The best choice would be 1.6-liter FSI direct injection petrol with 115 hp or 2.0-liter turbodiesel with 150 hp. The last mentioned features an outstanding fuel economy for it's capacity and acceleration speed, although is a bit noisy. The strongest performer is a 2.0-liter GTI, delivering 200 hp, which continues the Golf's hot hatch traditions."
73: + " Steering is sharp. The car is stable at speed and easily controlled as the power steering gets weightier with speed, unfortunately it does not give enough feedback to the driver. The ride is a bit firm in town, as the reliability of suspension was preferred to the comfort. It is a common feature of all VW Golf's.",
74: "img/car3.png", 78200));
75: carList.add(new Car(
76: id++,
77: "Neon",
78: "Chrysler",
79: " This car is sold as the Dodge Neon in the United States and as Chrysler Neon for export only. It is a second generation Neon produced since 2000."
80: + " There is a choice of three petrol engines. The basic 1.6-liter petrol is the same unit found on the MINI. The top of the range is a 2.0-liter engine, providing 133 hp, besides acceleration is a weak point of all Neons.",
81: "img/car4.png", 85400));
82: }
83:
84: public List<Car> findAll() {
85: return carList;
86: }
87:
88: public List<Car> search(String keyword) {
89: List<Car> result = new LinkedList<Car>();
90: if (keyword == null || "".equals(keyword)) {
91: result = carList;
92: } else {
93: for (Car c : carList) {
94: if (c.getModel().toLowerCase().contains(keyword.toLowerCase())
95: || c.getMake().toLowerCase()
96: .contains(keyword.toLowerCase())) {
97: result.add(c);
98: }
99: }
100: }
101: return result;
102: }
103: }
Step 6:
Now Let us Add the Search Zul file as follows.
Searchmvc.zul
1: <window title="Search" width="600px" border="normal"
2: apply="demo.SearchController">
3: <caption>
4: <label value="You are using ZK Version : ${desktop.webApp.version}"/>
5:
6: </caption>
7: <hbox align="center">
8: Keyword:
9: <textbox id="keywordBox" />
10: <button id="searchButton" label="Search" image="/img/search.png" />
11: </hbox>
12: <listbox id="carListbox" height="160px" emptyMessage="No car found in the result">
13: <listhead>
14: <listheader label="Model" />
15: <listheader label="Make" />
16: <listheader label="Price" width="20%"/>
17: </listhead>
18: <template name="model">
19: <listitem>
20: <listcell label="${each.model}"></listcell>
21: <listcell label="${each.make}"></listcell>
22: <listcell>$<label value="${each.price}" /></listcell>
23: </listitem>
24: </template>
25: </listbox>
26: <hbox style="margin-top:20px">
27: <image id="previewImage" width="250px" />
28: <vbox>
29: <label id="modelLabel" />
30: <label id="makeLabel" />
31: <label id="priceLabel" />
32: <label id="descriptionLabel" />
33: </vbox>
34: </hbox>
35: </window>
Some important points in the above ZUL file
1. hbox is a layout component that arranges its child components horizontally
2. We have used Listbox to display three column listing.
3. We also used the "emptyMessage" attribute is used to show a message when listbox contains no items.
4. In ZK, the controller is responsible for controlling ZK components and listening to events triggered by user interaction. We can create a such controller class by simply
extending org.zkoss.zk.SelectorComposer :
5. When we associate a controller with a component, every event triggered by this component (and its child components) is sent to the controller. If there is a method which we assigned to listen to the triggered event, it will be invoked
6. We have used template tag to display the listbox data.
Step 7:
Now let us add the controller as follows
SearchController.java
1: package demo;
2:
3:
4: import java.util.List;
5:
6: import org.zkoss.zk.ui.Component;
7: import org.zkoss.zk.ui.select.SelectorComposer;
8: import org.zkoss.zk.ui.select.annotation.*;
9: import org.zkoss.zul.*;
10:
11: public class SearchController extends SelectorComposer<Component> {
12:
13: private static final long serialVersionUID = 1L;
14:
15: @Wire
16: private Textbox keywordBox;
17: @Wire
18: private Listbox carListbox;
19: @Wire
20: private Label modelLabel;
21: @Wire
22: private Label makeLabel;
23: @Wire
24: private Label priceLabel;
25: @Wire
26: private Label descriptionLabel;
27: @Wire
28: private Image previewImage;
29:
30:
31: private CarService carService = new CarServiceImpl();
32:
33: @Listen("onClick = #searchButton")
34: public void search(){
35: String keyword = keywordBox.getValue();
36: List<Car> result = carService.search(keyword);
37: carListbox.setModel(new ListModelList<Car>(result));
38: }
39:
40: @Listen("onSelect = #carListbox")
41: public void showDetail(){
42: Car selected = carListbox.getSelectedItem().getValue();
43: previewImage.setSrc(selected.getPreview());
44: modelLabel.setValue(selected.getModel());
45: makeLabel.setValue(selected.getMake());
46: priceLabel.setValue(selected.getPrice().toString());
47: descriptionLabel.setValue(selected.getDescription());
48: }
49: }
Step 8:
Finally we will add some car image as shown here.
Now we run our searchmvc.zul file to see the output as follows
You can download the source here.
<script src="https://gist.github.com/4545051.js"></script>