ZK Framework Development
Skill para desenvolvimento de aplicações web Java utilizando ZK Framework (Community Edition), seguindo boas práticas de MVC/MVVM e integração com ecossistema Java.
When to Use
Use esta skill quando precisar:
- •Criar interfaces ZK com componentes ZUML (.zul)
- •Implementar padrão MVC com SelectorComposer e @Wire/@Listen
- •Implementar padrão MVVM com ViewModel e data binding
- •Integrar ZK com Spring Framework ou Spring Boot
- •Integrar ZK com JPA/Hibernate para persistência
- •Integrar ZK com Jersey/JAX-RS para APIs REST
- •Migrar entre versões do ZK (3.x até 10.x)
- •Escolher entre MVC e MVVM para seu caso de uso
Não use para: ZK Enterprise Edition (EE), ZK Charts, ZK Spreadsheet, mobile-specific.
Instructions
Step 1: Analisar Contexto ZK
Antes de gerar código, identifique:
- •
Versão do ZK Framework
- •Verifique
pom.xmloubuild.gradle - •ZK 3.x-5.x: MVC clássico (GenericForwardComposer)
- •ZK 6.x+: SelectorComposer, @Wire, @Listen
- •ZK 8.x+: MVVM maduro, Shadow Elements
- •ZK 9.x-10.x: Spring Boot integration, Java 17+ support
- •Verifique
- •
Padrão arquitetural
- •MVC: Uso de Composer (controller explícito)
- •MVVM: Uso de ViewModel (@Command, @NotifyChange, data binding)
- •
Stack de integração
- •Spring Framework/Boot: DI, transações
- •JPA/Hibernate: Persistência
- •Jersey/JAX-RS: APIs REST
Step 2: Escolher Padrão MVC vs MVVM
Use MVC quando:
- •Lógica de UI complexa e acoplada ao componente
- •Controle fino sobre eventos e lifecycle
- •Migração de código legado ZK 3.x-5.x
- •Prototipagem rápida
Use MVVM quando:
- •Separação clara entre UI e lógica de negócio
- •Reuso de ViewModels entre diferentes UIs
- •Testabilidade (ViewModels testáveis sem UI)
- •Projetos novos com ZK 8.x+
Step 3: Implementar Padrão MVC
ZUML (.zul):
<window title="User Management" border="normal"
apply="com.example.UserController">
<listbox id="userList" rows="10">
<listhead>
<listheader label="Name"/>
<listheader label="Email"/>
</listhead>
</listbox>
<button id="addBtn" label="Add User"/>
</window>
Controller (ZK 6.x+):
package com.example;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zul.*;
public class UserController extends SelectorComposer<Window> {
@Wire
private Listbox userList;
@Wire
private Button addBtn;
@Override
public void doAfterCompose(Window comp) throws Exception {
super.doAfterCompose(comp);
loadUsers();
}
@Listen("onClick = #addBtn")
public void onAddUser() {
Messagebox.show("Add user clicked");
}
private void loadUsers() {
ListModelList<String> model = new ListModelList<>();
model.add("John Doe");
model.add("Jane Smith");
userList.setModel(model);
}
}
Step 4: Implementar Padrão MVVM
ZUML (.zul):
<window title="User Management" border="normal"
viewModel="@id('vm') @init('com.example.UserViewModel')">
<listbox model="@load(vm.users)" rows="10">
<listhead>
<listheader label="Name"/>
<listheader label="Email"/>
</listhead>
<template name="model">
<listitem>
<listcell label="@load(each.name)"/>
<listcell label="@load(each.email)"/>
</listitem>
</template>
</listbox>
<button label="Add User" onClick="@command('addUser')"/>
</window>
ViewModel:
package com.example;
import org.zkoss.bind.annotation.*;
import org.zkoss.zk.ui.select.annotation.WireVariable;
import java.util.List;
public class UserViewModel {
@WireVariable
private UserService userService;
private List<User> users;
@Init
public void init() {
loadUsers();
}
@Command
@NotifyChange("users")
public void addUser() {
User newUser = new User("New User", "new@example.com");
userService.save(newUser);
loadUsers();
}
public List<User> getUsers() {
return users;
}
private void loadUsers() {
users = userService.findAll();
}
}
Step 5: Componentes ZK Essenciais
Layout Components:
<window>
<!-- Vertical layout -->
<vlayout spacing="10px">
<label value="Item 1"/>
<label value="Item 2"/>
</vlayout>
<!-- Horizontal layout -->
<hlayout spacing="10px">
<button label="Save"/>
<button label="Cancel"/>
</hlayout>
<!-- Grid layout -->
<grid>
<rows>
<row>
<label value="Name:"/>
<textbox value="@bind(vm.user.name)"/>
</row>
<row>
<label value="Email:"/>
<textbox value="@bind(vm.user.email)"/>
</row>
</rows>
</grid>
</window>
Input Components:
<textbox value="@bind(vm.name)" placeholder="Enter name"/>
<intbox value="@bind(vm.age)" constraint="min 0 max 120"/>
<decimalbox value="@bind(vm.price)" format="$###,##0.00"/>
<datebox value="@bind(vm.birthDate)" format="dd/MM/yyyy"/>
<timebox value="@bind(vm.meetingTime)" format="HH:mm"/>
<combobox model="@load(vm.countries)" selectedItem="@bind(vm.selectedCountry)"/>
<checkbox checked="@bind(vm.agreed)" label="I agree"/>
<radiogroup selectedItem="@bind(vm.gender)">
<radio label="Male" value="M"/>
<radio label="Female" value="F"/>
</radiogroup>
Data Components:
<listbox model="@load(vm.users)" selectedItem="@bind(vm.selectedUser)">
<listhead>
<listheader label="Name" sort="auto(name)"/>
<listheader label="Email" sort="auto(email)"/>
</listhead>
<template name="model">
<listitem>
<listcell label="@load(each.name)"/>
<listcell label="@load(each.email)"/>
</listitem>
</template>
</listbox>
<grid model="@load(vm.users)">
<columns>
<column label="Name"/>
<column label="Email"/>
</columns>
<template name="model">
<row>
<label value="@load(each.name)"/>
<label value="@load(each.email)"/>
</row>
</template>
</grid>
Step 6: Data Binding
One-way binding (load):
<label value="@load(vm.userName)"/> <!-- UI updates when VM changes -->
Two-way binding (bind):
<textbox value="@bind(vm.userName)"/> <!-- Bidirectional sync -->
Command binding:
<button label="Save" onClick="@command('save')"/>
<button label="Delete" onClick="@command('delete', user=vm.selectedUser)"/>
Converter:
<label value="@load(vm.price) @converter('formattedNumber', format='###,##0.00')"/>
<label value="@load(vm.date) @converter('formattedDate', format='dd/MM/yyyy')"/>
Validator:
<textbox value="@bind(vm.email) @validator(vm.emailValidator)"/>
Java Validator:
public Validator getEmailValidator() {
return (ValidationContext ctx) -> {
String email = (String) ctx.getProperty().getValue();
if (!email.matches("^[A-Za-z0-9+_.-]+@(.+)$")) {
ctx.setInvalid();
}
};
}
Step 7: Event Handling
MVC (Composer):
@Listen("onClick = #saveBtn")
public void onSave() {
// Handle save
}
@Listen("onSelect = #userList")
public void onUserSelect(SelectEvent<Listitem, String> event) {
String selected = event.getSelectedObjects().iterator().next();
}
@Listen("onChange = #searchBox")
public void onSearch(InputEvent event) {
String query = event.getValue();
filterUsers(query);
}
MVVM (ViewModel):
@Command
public void save() {
// Handle save
}
@Command
public void selectUser(@BindingParam("user") User user) {
this.selectedUser = user;
}
@NotifyChange("filteredUsers")
@Command
public void search(@BindingParam("query") String query) {
filteredUsers = userService.search(query);
}
Step 8: Navigation
Forward (same app):
Executions.sendRedirect("/users.zul");
With parameters:
// Send
Map<String, Object> params = new HashMap<>();
params.put("userId", 123);
Executions.createComponents("/userDetail.zul", null, params);
// Receive
Long userId = (Long) Executions.getCurrent().getArg().get("userId");
Session attributes:
// Set
Sessions.getCurrent().setAttribute("user", user);
// Get
User user = (User) Sessions.getCurrent().getAttribute("user");
Step 9: Validation & Error Handling
Client-side validation:
<textbox constraint="no empty: Please enter a value"/> <intbox constraint="min 0 max 100: Value must be between 0 and 100"/> <textbox constraint="/^[A-Za-z0-9+_.-]+@(.+)$/: Invalid email"/>
Server-side validation:
@Command
public void save() {
if (user.getName() == null || user.getName().isEmpty()) {
Clients.showNotification("Name is required", "error", null, "top_center", 3000);
return;
}
try {
userService.save(user);
Clients.showNotification("User saved successfully", "info", null, "top_center", 3000);
} catch (Exception e) {
Clients.showNotification("Error: " + e.getMessage(), "error", null, "top_center", 5000);
}
}
Best Practices
1. Progressive Disclosure
- •Use
references/para integrações específicas (Spring, JPA, REST) - •Consulte
references/design-patterns.mdpara padrões avançados - •Veja
references/customization.mdpara temas e componentes customizados
2. MVC vs MVVM
- •MVC: Prototipagem rápida, lógica UI-bound
- •MVVM: Projetos complexos, testabilidade, reuso
3. Performance
- •Use
ListModelListcomsetMultiple()para batch updates - •Evite re-renderização desnecessária com
@NotifyChange - •Lazy loading para datasets grandes
- •Detalhes em
references/performance-optimization.md
4. Security
- •Sempre validar input no servidor
- •Usar Spring Security para autenticação/autorização
- •Sanitizar outputs para prevenir XSS
5. Testing
- •ViewModels são POJOs: teste com JUnit diretamente
- •Composers: mock componentes ZK para testes unitários
- •Integração: use ZK Test Engine (ZTL)
Common Patterns
CRUD Pattern (MVVM):
public class CrudViewModel<T> {
private List<T> entities;
private T selected;
@Init
public void init() { load(); }
@Command @NotifyChange("entities")
public void load() { entities = service.findAll(); }
@Command @NotifyChange({"entities", "selected"})
public void save() { service.save(selected); load(); }
@Command @NotifyChange({"entities", "selected"})
public void delete() { service.delete(selected); load(); }
}
Master-Detail Pattern:
<hlayout>
<listbox model="@load(vm.users)" selectedItem="@bind(vm.selected)" width="300px"/>
<vlayout visible="@load(not empty vm.selected)">
<label value="@load(vm.selected.name)"/>
<label value="@load(vm.selected.email)"/>
</vlayout>
</hlayout>
References
Para integrações específicas e tópicos avançados, consulte:
- •Spring Integration - Spring Framework e Spring Boot
- •JPA/Hibernate Integration - Persistência e ORM
- •REST API Integration - Jersey/JAX-RS
- •Design Patterns - Padrões ZK-specific
- •Customization - Temas, macros, client-side
- •Advanced MVVM - Técnicas avançadas MVVM
- •Performance Optimization - Best practices
- •Migration Guide - Migração entre versões
Sources
- •ZK Framework Official Documentation - https://www.zkoss.org/documentation - Acessado 2026-02-05
- •ZK MVVM Reference - https://www.zkoss.org/wiki/ZK_Developer%27s_Reference/MVVM - Acessado 2026-02-05
- •ZK Spring Boot Starter - https://github.com/zkoss/zkspringboot - Acessado 2026-02-05
- •ZK Component Reference - https://www.zkoss.org/zkdemo/ - Acessado 2026-02-05
- •Baeldung ZK Framework Tutorial - https://www.baeldung.com/zk-framework - Acessado 2026-02-05