ZK Component — Progress Meter and How To Implement Download Data Through Progress Meter

Reza Indrawan
4 min readJun 8, 2020

Progress Meter is one of ZK Component that can show you the percentage of a process. This percentage indicates how much of a task has been completed with range between 0 and 100. The task will representation of animation bar indicator of their movement.

Pic 1. Source : https://www.zkoss.org/zkdemo/miscellaneous/progress_meter

If you using ZK Framework, you’ve already know that update progress meter percentage must through a listener, you can find tutorial how to update indicator bar with a listeners on zkoss website. But, update percentage won’t work if inside Progress Meter’s method has a Loops like for, while, and do-while.

For particular reason we need use Loops inside a method, but its imposible to update progress meter inside that method. As an example of the case I create a feature that can download very large data from database into a file and show percentage of the download process.

If we using direct download of large data from database by query, imagine if we have get very large data from many table relation let say over millions rows, it will take a lot of memory .. but you can make it into small pieces then update through progress meter. In this article I will show you how to create progress meter downloader.

First, create ZUL file downloader

I created new zul file with progress meter component. I used to create a new window so you can have to cancel it if you want to abort. Here is my design

Pic 2. Zul File Downloader

And here is my code in xml

Second, create java class controller

I used to pass controller class over args or you can put spesific java class controller inside apply window element.

First thing first, I dont use long operation (see : https://www.zkoss.org/wiki/Small_Talks/2015/January/Simplify_Long_Operation_Handlings) and I dont use any of Thread, so you not to worries about handling a Thread.

I will use Timer and combine with EventQueue. This is important thing that I used one listener which is user click download button or something on previous page, then pages downloader.zul opened and triggers event to download data.

When pages download is opened, then I use Events.echoEvent to trigger an event on override method doAfterComposed. Here controller code

Before to the next step, an echoEvent need timer on parameter to tell progress meter component that percentage need to update. So, we create listen on onAddNameEvent.

Now, we create methods to start a queue

Next, we need to get data from database. Before that, see method doLongOperation, inside this method we do a process to get data from database and put into a files.

From code above, you can see variable isCountQTY, isFetchingData, isFinish it’s sign for label progress like “still counting data”, Downloading”, “Finished” and I’ll explain leter.

Now we have variable vStart and vEnd, this is important thing that I use both variable for paging data from database. Like I said, we will make get data into small pieces not to get all data from database. If dont familiar with paging database, it just like our data has pagination start from 1 until total count data. This sample query for pagination using oracle 11g

and you can replace 1 into vStart and 100 into vEnd depened on your setting.

After that, you should get total count / total quantity data like I do, this is important to know total count for define how many loop. To get count total just query select count(*). Variable devide use to determine how many data want to get in one loop on query. I decide to use 500 or 1000 depent on how many total data.

Now we need to determine how many loop in this script:

if ((totalQty / divide) % 2 == 0) {       
looping = (int) (totalQty / divide);
} else {
looping = (int) (totalQty / divide) + 1;
}

After that create file and begin main loop, you can see main loop in script above. Now, Its time to timer works.

you can see update progress meter through timer listener and progress meter will update percentage depend variable process and you can update progress label like I do on method updateLabel(). isCountQTY, isFetchingData, and isFinish variable I created to update through listener, you can set false or true to set value of label. On button Cancel listener, I use to stop all process like timer stop, removeQueue, and close window.

Here is final result :

Pic 3. File Downloader

After 100% file will be downloaded.

Pic 4. Downloaded File

--

--

Reza Indrawan
0 Followers

Java Developer & PL/SQL Developer @ Azec Indonesia Management Service