Creating a Simple Sightseeing Application

From Documentation

Before You Start

Translations are available in English and Français.

Other Introductions

Introdução

Esse tutorial é um guia rápido onde o foco é explicar as vantages do ZK, através de uma aplicação exemplo. Se preferir um tutorial passo a passo, por favor de uma olhada em Tutorial Passo a Passo.

Nesse tutorial, vamos introduzir duas maneiras de como criar uma aplicação ZK com Ajax, uma maneira padrão (sem data binding), e outra avançada (com data binding).

Um Exemplo Real Demo ao Vivo

Suponha que você quer criar uma aplicação web com o Google Maps integrado. A página é dividada em três partes, uma tabela ao lado esquerdo, o Google Maps ao lado direito e um painel na parte de baixo da página, como mostrado na figura abaixo.

Resort-s.jpg

  • Ajax em Ação: Quando o usuário selecionar um item na tebela à esquerda, a sua localização é mostrada no Google Maps, e a sua coordenada é mostrada no painel abaixo.

Modelo de Dados

De acordo com os requisitos mencionados acima, o modelo de dados requer quatro atributos: nome, descrição, latitude e longitude.

public class Resort {
    private String _name;
    private String _description;
    private double _latitude;
    private double _longitude;
    
    public Resort() {
    }

    public Resort(String name, String description, double latitude, double longitude) {
        _name = name;
        _description = description;
        _latitude = latitude;
        _longitude = longitude;
    }

    // getter and setter methods are omitted.

    public static List<Resort> getAll() {
       // Details are omitted.
    }
}

A Maneira Padrão (Sem Data Binding)

A maneira padrão de como criar uma aplicação web usando o ZK será introduzida. Neste exemplo você vai apreender como usar ZK e perceber as suas vantagens.

Design de Interface Para Usuário Através da Linguagem Markup do ZK

O primeiro arquivo a criar é resort.zul, que inclui uma listbox (tabela), um gmaps(Google Maps), and um groupbox(painel).

Nesse arquivo zul (resort.zul) não existe nenhum código java ou scriplets, e o layout da página é mantido limpo e claro. Esses códigos são definidos num outro arquivo Java — ResortController.java.

A interação entre o arquivo zul e a classe Java é ativida através das ações do usuário. Quando o usuário seleciona um ítem na listbox, o evento onSelect da listbox será disparado, e o método refreshUI() da classe ResortController.java será invocado mostrando o ítem selecionado no Google Maps, e suas coordenadas no painel na parte inferior da página.

<!-- resort.zul -->
<?script 
  content="zk.googleAPIkey='ABQIAAAACZ90QS5pNiEvbXhI0k2NLRTGXUEQDrMr1bP0DVG8X36ZVCheaRQMK05Rsdneh4skNF6KXaLI8maLlA'"?>

<window id="win" title="ZK Tutorial" border="normal"
 apply="org.zkforge.resort.ui.ResortController">
	<hbox>
		<listbox id="lb" hflex="1">
			<listhead sizable="true">
				<listheader label="Name" width="100px"/>
				<listheader label="Description"/>
			</listhead>
		</listbox>	
		<gmaps id="gmap" zoom="16" showTypeCtrl="true" mapType="satellite" 
                  showLargeCtrl="true" width="610px" height="400px">
			<ginfo id="ginfo"/>
		</gmaps>
	</hbox>
	<groupbox id="gb" mold="3d" width="100%">
		<caption label="Resort"/>
		Name:<textbox disabled="true" id="name"/>
		Description:<textbox disabled="true" id="desc"/>
		Longitude:<doublebox disabled="true" id="longtitude"/>
		Latitude:<doublebox disabled="true" id="latitude"/>
	</groupbox>
</window>

Manipule UI (User Interface) Através de Classes Java

No arquivo Java (ResortController.java), nós recuperamos os componentes definidos no arquivo zul através da sua ID, e colocamos os dados do componente selecionado na varíavel da classe Java. Então o ZK atualizará a página automaticamente através do Ajax.

// ResortController.java
public class ResortController extends GenericForwardComposer {

    private static final long serialVersionUID = -4023064279380075239L;
    private Listbox lb;
    private Gmaps gmap;
    private Ginfo ginfo;
    private Textbox name;
    private Textbox desc;
    private Doublebox latitude;
    private Doublebox longtitude;

    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp);
        
        lb.setItemRenderer(new ListitemRenderer() {
            public void render(Listitem item, Object data) throws Exception {
                Resort value = (Resort)data;
                item.appendChild(new Listcell(value.getName()));
                item.appendChild(new Listcell(value.getDescription()));
                item.setValue(value);
            }
        });
        
        lb.setModel(new ListModelList(Resort.getAll()));
    }
    
    public void onSelect$lb() {
        refreshUI();
    }

    private void refreshUI() {
        Resort resort = (Resort) lb.getSelectedItem().getValue();
        double latitudeValue = resort.getLatitude().doubleValue();
        double longtitudeValue = resort.getLongitude().doubleValue();
        
        name.setValue(resort.getName());
        desc.setValue(resort.getName());
        latitude.setValue(resort.getLatitude());
        longtitude.setValue(resort.getLongitude());
        ginfo.setLat(latitudeValue);
        ginfo.setLng(longtitudeValue);
        ginfo.setContent(resort.getDescription());
        gmap.panTo(latitudeValue, longtitudeValue);
        gmap.setZoom(16);
        gmap.openInfo(ginfo);
    }
}

Neste exemplo você pode perceber a simplicidade de criar uma aplicação web com o ZK com Ajax integrado. O view e o controller (do padrão MVC) estão claramente separados. Além disso nenhum código JavaScript é necessário! Acreditamos que a melhor maneira de utilizar o Ajax é não saber da sua existência.

A Maneira Avançada (Com Data Binding)

Para simplificar a manutenção e a consistência dos dados entre o data bean e a UI, o ZK provem um mecanismo de data-binding. A única ação necessãria é definir a relação entre o data bean com os componentes de UI, e o mecanismo de data-binding vai manter automaticamente a consistência entre variáveis Java (servidor) com as variáveis html/JavaScript no cliente. Ou seja, ao modificar um valor na classe Java, o valor na página será atualizado automaticamente e instantâneamente pelo ZK.

Defina Relações entre Data Bean e Componentes de UI.

Uma maneira simples consiste em definir as relações na definição da própria página. Uma das principais diferenças é que nós adicionamos outro data bean que representa o ítem selecionado, e então faz a ligação de todos os componentes do ZK.

<!-- resort_databind.zul -->
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<?script 
  content="zk.googleAPIkey='ABQIAAAACZ90QS5pNiEvbXhI0k2NLRTGXUEQDrMr1bP0DVG8X36ZVCheaRQMK05Rsdneh4skNF6KXaLI8maLlA'" ?>

<window id="win" 
  apply="org.zkforge.resort.ui.ResortController2" title="ZK Tutorial" width="1024px" border="normal">
	<hbox>
	<listbox id="lb" model="@{win$ResortController2.resorts}" selectedItem="@{win$ResortController2.selected}">
		<listhead sizable="true">
			<listheader label="Name" width="100px"/>
			<listheader label="Description"/>			
		</listhead>
		<listitem self="@{each=resort}">
			<listcell label="@{resort.name}" />
			<listcell label="@{resort.description}" />			
		</listitem>
	</listbox>	
	<gmaps id="gmap" zoom="16" showTypeCtrl="true" mapType="satellite" 
          showLargeCtrl="true" width="610px" height="400px">
		<ginfo id="ginfo" />
	</gmaps>
	</hbox>
	<groupbox id="gb" mold="3d" width="100%">
		<caption label="Resort"/>
		Name:<textbox id="name" value="@{win$ResortController2.selected.name}" disabled="true"/>
		Description:<textbox  id="desc" value="@{win$ResortController2.selected.description}" disabled="true"/>
		Longitude:<doublebox id="lng" value="@{win$ResortController2.selected.longitude}" disabled="true"/>
		Latitude:<doublebox id="lat" value="@{win$ResortController2.selected.latitude}" disabled="true"/>	
	</groupbox>
</window>

Revisão das Classes Java

Com a ajuda do data-binding, os códigos Java na classe ResortController.java são reduzidos. Uma vez que o usuário selecione um ítem diferente, o data bean mudará, e então todos os componentes relativos ao ZK serão atualizados automaticamente.

// ResortController2.java
public class ResortController2 extends GenericForwardComposer {

    private static final long serialVersionUID = -7504093487870918898L;
    private List<Resort> _resorts;
    private Resort _selected;
    private Gmaps gmap;
    private Ginfo ginfo;

    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp);
        setResorts(Resort.getAll());
        _selected = new Resort();
    }
    
    public void onSelect$lb() {
        refreshUI();
    }

    private void refreshUI() {
        double latitude = _selected.getLatitude().doubleValue();
        double longtitude = _selected.getLongitude().doubleValue();
        
        ginfo.setLat(latitude);
        ginfo.setLng(longtitude);
        ginfo.setContent(_selected.getDescription());
        gmap.panTo(latitude, longtitude);
        gmap.setZoom(16);
        gmap.openInfo(ginfo);
    }

    public Resort getSelected() {
        return _selected;
    }

    public void setSelected(Resort selected) {
        _selected = selected;
    }

    public void setResorts(List<Resort> _resorts) {
        this._resorts = _resorts;
    }

    public List<Resort> getResorts() {
        return _resorts;
    }
}

Instalando a aplicação Web

  1. Instalar o SDK do Java
    Se você ainda não possui o SDK do java, faça o download e instale Java SDK.
  2. Instale um Container Servlet
    Se você não tem um container servlet, faça o download e instale Apache Tomcat.
  3. Baixe a Aplicação Web
    Faça o download dos arquivos da aplicação mostrada aqui.
  4. Descompacte o Arquivo (Unzip)
    Descompacte resort.zip, e copiei o arquivo resort.war para $TOMCAT_HOME/webapps/.
  5. Inicie seu Servidor Web, e com o seu navegor visite a página http://localhost:8080/resort/resort.zul