Chat with Global Command
Cossaer Filip
March 06, 2014
ZK 6 and above
Introduction: Chat in MVVM with Global Command
In the article ZK 5: Chat with Event Queue, Tom Yeh explains how to create a chat program with the event Queue. Now with MVVM we can do that way also, or say, we use a more MVVM compliant approach. In this small talk we will write a simple chat program just like Tom Yeh. We suggest you to read the previous article first for better understanding.
The global command
What is Global Comand
Global Command is also a ViewModel's command and can hook UI component's events to it. Local command can only be triggered by events of a ViewModel's Root View Component and its child components whereas the global command can be triggered by a component's event from any ZUL. The main difference of a global command from a local command is that the event doesn't have to belong to the ViewModel's root view component or its child component. By default we can bind an event to any ViewModel's global command within the same desktop. A method can be both a local command and a global command.
The scope of an global command
The default scope of a global command is the Desktop scope, this can be changed by the user.
Changing the scope
We can modify the scope of the Viewmodel. By changing the Viewmodel's scope the global-command can be called into that scope.
<window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('be.chillworld.YourVM')" binder="@init(queueScope='application')">
We can apply multiple binders to one scope by adding a queueName.
<window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('be.chillworld.YourVM')" binder="@init(queueName='chillworld',queueScope='application')">
More info about the differtent scopes : Scope of an Event Queue.
More info about the binder : DataBinding - Binder.
How to call a global command
We can call our global command in 2 ways. From the zul we do this :
<button label="Send" onClick="@global-command('send')" />
From java we do this :
BindUtils.postNotifyChange(java.lang.String queueName, java.lang.String queueScope, java.lang.Object bean, java.lang.String property)
More info about the BindUtil class : BindUtils.
An example: chat
The chat pojo. (I use this when I can enums for singelton because this is the best and easiest way to create them)
package be.chillworld;
/**
*
* @author chillworld
*/
public enum Chat {
INSTANCE;
private StringBuilder chat = new StringBuilder();
public String getChat () {
return chat.toString();
}
public void addText (String text) {
chat.append("\n");
chat.append(text);
}
}
the index.zul :
<?xml version="1.0" encoding="UTF-8"?>
<zk>
<window border="normal" title="chat with global command" apply="org.zkoss.bind.BindComposer"
viewModel="@id('vm') @init('be.chillworld.IndexVM')" binder="@init(queueScope='application')">
<vbox>
<label value="@load(vm.chat)" multiline="true" height="300px"/>
<textbox value="@bind(vm.text)"/>
<button label="Send text" onClick="@command('chat')"/>
</vbox>
</window>
</zk>
and the viewmodel :
package be.chillworld;
import org.zkoss.bind.annotation.GlobalCommand;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Sessions;
/**
*
* @author chillworld
*/
public class IndexVM{
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getChat() {
return Chat.INSTANCE.getChat();
}
@Command("chat")
public void chat() {
if (text != null) {
Chat.INSTANCE.addText(Sessions.getCurrent().toString() + " says : " + text);
text = null;
}
BindUtils.postGlobalCommand(null, EventQueues.APPLICATION, "update", null);
}
@GlobalCommand("update")
@NotifyChange({"chat", "text"})
public void update() {}
}
I created a maven project for this.
You can download this here.
Note : Remember that this needs two different sessions so best way to test is open 2 different browsers.
Special Thanks
bartvdc for asking this question.
ZK team allowing me to write a small talk.
Comments
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |