Processing...
Description & Source Code

Echo event is a very useful feature handling long operations. This sample demonstrate how to deal with long running processes without block whole screen. Otherwise, ZK developers can simply invoke Clients.showBusy to block part of screen.

echo_event.zul
<zk>
	<hlayout spacing="25px" apply="demo.event.echo_event.FetchFileController" width="100%">
		<vlayout hflex="1">
			<button id="fetchBtn" label="Fetch Profile" height="35px" autodisable="self" />
			<listbox id="nameList" checkmark="true">
				<listhead>
					<listheader label="Name List"></listheader>
				</listhead>
			</listbox>
		</vlayout>

		<listbox id="downList" hflex="2">
			<auxhead>
				<auxheader colspan="2">Profile Download List</auxheader>
			</auxhead>
			<listhead>
				<listheader label="Name" />
				<listheader label="Profile Download" />
			</listhead>
		</listbox>

		<groupbox id="server" hflex="1" mold="3d" closable="false">
			<caption label="Server Status" />
			<image id="serverimg" src="/widgets/event/echo_event/img/webserver.png" onClick='alert("Server")' />
			<timer id="timer" delay="1500" repeats="true" onCreate="self.stop()"/>
		</groupbox>
	</hlayout>
</zk>
FetchFileController.java
package demo.event.echo_event;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Set;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.A;
import org.zkoss.zul.Button;
import org.zkoss.zul.Groupbox;
import org.zkoss.zul.Image;
import org.zkoss.zul.Label;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Timer;

import demo.data.RandomNameDatas;

public class FetchFileController extends SelectorComposer<Component> {
	private static final long serialVersionUID = 2761033708874533783L;

	private static final String PROCESSING_TEXT = "Processing...";

	@Wire
	private Listbox nameList, downList;
	@Wire
	private Button fetchBtn;
	@Wire
	private Groupbox server;
	@Wire
	private Image serverimg;
	@Wire
	private Timer timer;

	private Deque<String> namesToFetch = new LinkedList<String>();
	private ListModelList<String> nameListModel;
	private ListModelList<String> downListModel;

	@Override
	public void doAfterCompose(Component comp) throws Exception {
		super.doAfterCompose(comp);
		initNameList();
		initDownList();
	}

	@Listen("onClick = #fetchBtn")
	public void fetchFileFromServer(Event e) {
		Set<String> selectedNames = nameListModel.getSelection();
		if (selectedNames.isEmpty()) {
			alert("No Name Selected");
			return;
		}
		namesToFetch.addAll(selectedNames);
		nameListModel.removeAll(selectedNames);

		Events.echoEvent("onAddNameEvent", timer, null);

		Clients.showBusy(server, PROCESSING_TEXT + "(" + namesToFetch.size() + ")");
		serverimg.setSrc("/widgets/event/echo_event/img/webserver_busy.png");
	}

	@Listen("onAddNameEvent = #timer")
	public void processingFiles() {
		timer.start();
	}

	@Listen("onTimer = #timer")
	public void fetchingSimulatorTimer() {
		downListModel.add(namesToFetch.pop());

		Clients.showBusy(server, PROCESSING_TEXT + "(" + namesToFetch.size() + ")");
		if (namesToFetch.isEmpty()) {
			timer.stop();
			Clients.clearBusy(server);
			serverimg.setSrc("/widgets/event/echo_event/img/webserver.png");
		}
	}

	private void initDownList() {
		downListModel = new ListModelList<>();
		downList.setModel(downListModel);
		downList.setItemRenderer((Listitem item, String name, int index) -> {
			item.appendChild(new Listcell(name));
			Listcell cell2 = new Listcell();
			cell2.appendChild(new A("Download Profile"));
			item.appendChild(cell2);
		});
	}

	private void initNameList() {
		nameListModel = new ListModelList<>(RandomNameDatas.getNameList(15));
		nameListModel.setMultiple(true);
		nameListModel.addToSelection(nameListModel.get(0));
		nameListModel.addToSelection(nameListModel.get(1));
		nameList.setModel(nameListModel);
	}
}
RandomNameDatas.java
package demo.data;

import java.util.LinkedList;
import java.util.List;

public class RandomNameDatas {
	private static LinkedList<String> nameList = new LinkedList<String>();
	static {
		nameList.add("Patricia Thorpe");
		nameList.add("Kathi Derrickson");
		nameList.add("Carissa Daugherty");
		nameList.add("Johna Palmer");
		nameList.add("Inez Steffent");
		nameList.add("Divina Lum");
		nameList.add("Jeni Simpkin");
		nameList.add("Mu'tamid Philip");
		nameList.add("Goran Bohuslav");
		nameList.add("Lavern Bryant");
		nameList.add("Angelica Ott");
		nameList.add("Kassia Trengove");
		nameList.add("Gertie Wardrobe");
		nameList.add("Bryana Savage");
		nameList.add("Tahnee Street");
		nameList.add("April Irving");
		nameList.add("Karenza Ayers");
		nameList.add("Lalia Tracey");
		nameList.add("Lucille Reier");
		nameList.add("Lalia Bunker");
		nameList.add("Karla M. Rubino");
		nameList.add("Biddy Lyon");
		nameList.add("Petra Ericson");
		nameList.add("Red Wolf");
	}
	public static List<String> getNameList() {
		return new LinkedList<String>(nameList);
	}
	public static List<String> getNameList(int index) {
		return new LinkedList<String>(nameList.subList(0, index));
	}
}