package zk.support.cht; import org.zkoss.bind.BindUtils; import org.zkoss.bind.annotation.Command; import org.zkoss.bind.annotation.NotifyChange; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventQueue; import org.zkoss.zk.ui.event.EventQueues; import org.zkoss.zk.ui.util.Clients; public class LongOperationsViewModel { private String progress; @Command("startLongOperation") @NotifyChange("progress") public void onStartLongOperation() { progress = "started"; startLongOperationSequence(); } private void startLongOperationSequence() { final LongOperation processOperation = new BusyLongOperation("processQueue", "processing in backend") { @Override protected void execute() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } protected void onFinish() { super.onFinish(); progress += " ,processing done"; BindUtils.postNotifyChange(null, null, LongOperationsViewModel.this, "progress"); }; }; LongOperation loadOperation = new BusyLongOperation("loadQueue", "loading from DB") { @Override protected void execute() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } @Override protected void onFinish() { super.onFinish(); progress += " ,loading done"; BindUtils.postNotifyChange(null, null, LongOperationsViewModel.this, "progress"); processOperation.start(); } }; loadOperation.start(); } public String getProgress() { return progress; } public static abstract class BusyLongOperation extends LongOperation { private String busyMessage; public BusyLongOperation(String queueName, String busyMessage) { super(queueName); this.busyMessage = busyMessage; } @Override protected void onStart() { Clients.showBusy(busyMessage); } @Override protected void onFinish() { Clients.clearBusy(); } } public static abstract class LongOperation { private String queueName; public LongOperation(String queueName) { super(); this.queueName = queueName; } abstract protected void onStart(); abstract protected void execute(); abstract protected void onFinish(); public void start() { if (EventQueues.exists(queueName)) { Clients.showNotification("Queue with name '" + queueName + "' is already running. Try later."); return; } final EventQueue eventQueue = EventQueues.lookup(queueName, true); final EventListener executionListener = new EventListener() { @Override public void onEvent(Event event) throws Exception { execute(); } }; final EventListener callbackListener = new EventListener() { @Override public void onEvent(Event event) throws Exception { eventQueue.unsubscribe(executionListener); //problem here EventQueues.remove(queueName); //or problem here onFinish(); } }; onStart(); eventQueue.subscribe(executionListener, callbackListener); eventQueue.publish(new Event("launch dummy")); } } }