Suggested case list:
Using timer to refresh a grid
383guest172.69.33.12125nk0uiMay 7, 2020 7:23:47 AMlinkuser model to move item to another listbox
120guest162.158.193.148d0n3krApr 2, 2020 5:28:28 AMlinkDisabled list item row passed to VM-1981
296fatih123160.83.36.13025nk0uiFeb 13, 2018 4:25:44 PMlinkDisabled list item row passed to VM-1981
295fatih123160.83.36.13025nk0uiFeb 13, 2018 4:25:16 PMlinkDisabled list item row passed to VM-1981
294fatih123160.83.36.13225nk0uiFeb 13, 2018 3:30:44 PMlinkgrid sample with ListModel/RowRenderer
816guest80.82.2.1312vah9ajFeb 21, 2017 11:42:21 AMlinkgrid sample with ListModel/RowRenderer
809guest175.98.113.1622vah9ajJan 26, 2017 9:19:33 AMlinkgrid sample with ListModel/RowRenderer
196guest79.185.142.402vah9ajApr 26, 2014 10:53:57 PMlinkgrid sample with ListModel/RowRenderer
195guest79.185.142.402vah9ajApr 26, 2014 10:53:54 PMlinkgrid sample with ListModel/RowRenderer
194guest79.185.142.402vah9ajApr 26, 2014 10:53:51 PMlinkgrid sample with ListModel/RowRenderer
193guest79.185.142.402vah9ajApr 26, 2014 10:53:48 PMlinkgrid sample with ListModel/RowRenderer
192guest79.185.142.402vah9ajApr 26, 2014 10:53:44 PMlinkgrid sample with ListModel/RowRenderer
191guest79.185.142.402vah9ajApr 26, 2014 10:53:40 PMlinkHierarchy table without using ZK PE/EE
1aaknai151.28.135.2131s871daJul 29, 2013 11:02:46 PMlinkgrid sample with ListModel/RowRenderer
128aaknai151.28.135.2132vah9ajJul 29, 2013 7:20:00 PMlinkuser model to move item to another listbox
1TonyQ114.25.109.94d0n3krApr 21, 2012 10:43:27 AMlinkUsing timer to refresh a grid
1TonyQ220.133.44.3725nk0uiFeb 17, 2012 3:17:34 AMlinkFire a event from child iframe
1TonyQ220.133.44.372eupjotFeb 3, 2012 5:04:52 AMlinkTextbox input restriction sample
1TonyQ72.21.245.2431b3nlr0Dec 20, 2011 10:09:10 AMlinkTest web core taglib in ZUL
1TonyQ198.203.175.175ofqkemDec 17, 2011 3:36:08 AMlinkLatest 10 Fiddles :
constraint binding textbox
3guest172.68.151.16220peldaDec 5, 2025 5:08:19 PMlinkAnother new ZK fiddle
2guest172.68.151.16320peldaDec 5, 2025 5:07:51 PMlinkAnother new ZK fiddle
1guest172.68.151.16220peldaDec 5, 2025 5:07:32 PMlinkAnother new ZK fiddle
1peggypeng172.71.154.99364f4neDec 5, 2025 9:24:31 AMlinktooltip example
2guest104.22.23.13rc1ntoDec 4, 2025 2:23:45 PMlinkAnother new ZK fiddle
1guest172.69.134.2277t7602Dec 4, 2025 1:40:46 PMlinkAnother new ZK fiddle
1peggypeng104.22.17.1802df6e3oDec 4, 2025 8:41:29 AMlinkonClose
1peggypeng172.68.87.248j8kd8aDec 3, 2025 4:10:26 AMlinkAnother new ZK fiddle
1peggypeng172.69.134.2271rm7f4eNov 26, 2025 3:31:24 AMlinkZK-5912-Suggestion
2rebeccalai104.22.20.1442qrmiiuNov 26, 2025 2:07:15 AMlinkLongOperation MVVM and refresh listbox
1guest212.166.46.33qhs472Feb 13, 2020 3:17:33 PMlinkresources
index.zulzul<zk>
<window border="normal" title="hello" viewModel="@id('vmTest') @init('pkg$.TestVM')">
<combobox model="@bind(vmTest.searchedOrgs)"
selectedItem="@bind(vmTest.selectedSearchedOrg)"
onFocus="self.select()">
<template name="model">
<comboitem label="@load(each.lastname)" />
</template>
</combobox>
<button onClick="@command('startLongOperation')" label="start"/>
</window>
</zk>
TestVM.javajavaimport org.zkoss.zk.ui.*;
import org.zkoss.zk.ui.event.*;
import org.zkoss.zk.ui.util.*;
import org.zkoss.zk.ui.ext.*;
import org.zkoss.zk.au.*;
import org.zkoss.zk.au.out.*;
import org.zkoss.zul.*;
import java.util.*;
import org.zkoss.bind.*;
import org.zkoss.bind.annotation.*;
public class TestVM {
private ListModel<TestPOJO> searchedOrgs = new ListModelList<>();
private TestPOJO selectedSearchedOrg;
@Init
public void init() {
List<TestPOJO> pojos = new ArrayList<>();
TestPOJO pojo = new TestPOJO();
pojo.setLastname("Lastname");
pojo.setFirstname("Firstname");
pojos.add(pojo);
searchedOrgs = new ListModelList<>(pojos, true);
}
@Command
public void startLongOperation() {
LongOperation longOperation = new BusyLongOperation() {
@Override
protected void execute() throws InterruptedException {
// wait 5 seconds
Thread.sleep(5000);
}
@Override
protected void onFinish() {
searchedOrgs = new ListModelList<>();
BindUtils.postNotifyChange(null, null, TestVM.this, "*");
deactivate();
}
};
longOperation.start();
}
public ListModel<TestPOJO> getSearchedOrgs() {
return searchedOrgs;
}
public TestPOJO getSelectedSearchedOrg() {
return selectedSearchedOrg;
}
public void setSelectedSearchedOrg(TestPOJO pojo) {
this.selectedSearchedOrg = pojo;
}
}
TestPOJO.javajavaimport org.zkoss.zk.ui.*;
import org.zkoss.zk.ui.event.*;
import org.zkoss.zk.ui.util.*;
import org.zkoss.zk.ui.ext.*;
import org.zkoss.zk.au.*;
import org.zkoss.zk.au.out.*;
import org.zkoss.zul.*;
public class TestPOJO {
private String lastname;
private String firstname;
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
}
LongOperation.javajavaimport java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.WebApps;
import org.zkoss.zk.ui.sys.DesktopCache;
import org.zkoss.zk.ui.sys.DesktopCtrl;
import org.zkoss.zk.ui.sys.WebAppCtrl;
/**
* https://github.com/cor3000/zk-long-operations/blob/master/src/main/java/zk/example/longoperations/LongOperation.java
*/
public abstract class LongOperation implements Runnable {
private String desktopId;
private DesktopCache desktopCache;
private Thread thread;
private AtomicBoolean cancelled = new AtomicBoolean(false);
/**
* asynchronous callback for your long operation code
* @throws InterruptedException
*/
protected abstract void execute() throws InterruptedException;
/**
* optional callback method when the task has completed successfully
*/
protected void onFinish() {};
/**
* optional callback method when the task has been cancelled or was interrupted otherwise
*/
protected void onCancel() {};
/**
* optional callback method when the task has completed with an uncaught RuntimeException
* @param exception
*/
protected void onException(RuntimeException exception) {
exception.printStackTrace();
};
/**
* optional callback method when the task has completed (always called)
*/
protected void onCleanup() {};
/**
* set the cancelled flag and try to interrupt the thread
*/
public final void cancel() {
cancelled.set(true);
thread.interrupt();
}
/**
* check the cancelled flag
* @return
*/
public final boolean isCancelled() {
return cancelled.get();
}
/**
* activate the thread (and cached desktop) for UI updates
* call {@link #deactivate()} once done updating the UI
* @throws InterruptedException
*/
protected final void activate() throws InterruptedException {
Executions.activate(getDesktop());
}
/**
* deactivate the current active (see: {@link #activate()}) thread/desktop after updates are done
*/
protected final void deactivate() {
Executions.deactivate(getDesktop());
}
/**
* Checks if the task thread has been interrupted. Use this to check whether or not to exit a busy operation in case.
* @throws InterruptedException when the current task has been cancelled/interrupted
*/
protected final void checkCancelled() throws InterruptedException {
if(Thread.currentThread() != this.thread) {
throw new IllegalStateException("this method can only be called in the worker thread (i.e. during execute)");
}
boolean interrupted = Thread.interrupted();
if(interrupted || cancelled.get()) {
cancelled.set(true);
throw new InterruptedException();
}
}
/**
* launch the long operation
*/
public final void start() {
//not caching the desktop directly to enable garbage collection, in case the desktop destroyed during the long operation
this.desktopId = Executions.getCurrent().getDesktop().getId();
this.desktopCache = ((WebAppCtrl) WebApps.getCurrent()).getDesktopCache(Sessions.getCurrent());
enableServerPushForThisTask();
thread = new Thread(this);
thread.start();
}
@Override
public final void run() {
try {
try {
checkCancelled(); //avoid unnecessary execution
execute();
checkCancelled(); //final cancelled check before calling onFinish
activate();
onFinish();
} catch (InterruptedException e) {
try {
cancelled.set(true);
activate();
onCancel();
} catch (InterruptedException e1) {
throw new RuntimeException("interrupted onCancel handling", e1);
} finally {
deactivate();
}
} catch (RuntimeException rte) {
try {
activate();
onException(rte);
} catch (InterruptedException e1) {
throw new RuntimeException("interrupted onException handling", e1);
} finally {
deactivate();
}
throw rte;
} finally {
deactivate();
}
} finally {
try {
activate();
onCleanup();
} catch (InterruptedException e1) {
throw new RuntimeException("interrupted onCleanup handling", e1);
} finally {
deactivate();
disableServerPushForThisTask();
}
}
}
private UUID taskId = UUID.randomUUID();
private void enableServerPushForThisTask() {
((DesktopCtrl)getDesktop()).enableServerPush(true, taskId);
}
private void disableServerPushForThisTask() {
((DesktopCtrl)getDesktop()).enableServerPush(false, taskId);
}
private Desktop getDesktop() {
return desktopCache.getDesktop(desktopId);
}
}
BusyLongOperation.javajavaimport org.zkoss.zk.ui.util.Clients;
/**
* https://github.com/cor3000/zk-long-operations/blob/master/src/main/java/zk/example/longoperations/BusyLongOperation.java
*/
public abstract class BusyLongOperation extends LongOperation {
public BusyLongOperation() {
}
protected void showBusy(String busyMessage) throws InterruptedException {
activate();
Clients.showBusy(busyMessage);
deactivate();
}
@Override
protected void onCleanup() {
Clients.clearBusy();
}
@Override
protected void onFinish() {
Clients.alert("Coucou");
}
}