0

Update Progressmeter form java controller

asked 2012-03-20 13:46:49 +0800

goggy gravatar image goggy
36

updated 2013-06-10 08:38:24 +0800

benbai gravatar image benbai
2228 6
http://www.zkoss.org

I'd like to implement a progress bar (progressmeter) that would display progress of the Listitems processed. For example: I have a multiple selection Listbox. A user selects a random number of listitems and clicks a button. Now the controller has to extract the value from each listitem and send it to a web service (as shown in a code below).

public void onClick$process() throws Exception {
    Set<Listitem> set = box.getSelectedItems();
    ListModel<Person> model = box.getModel();
    Person p = null;

        int cnt = 1;
    int allItems = set.size();
    for (Listitem it : set) {
        p = model.getElementAt(it.getIndex());
                /* Call a WebService */
                someWS.doSomething(p);

        Integer percent = cnt * 100 / allItems;
        progress.setValue(percent);

                cnt++;
    }
}

Problem in the code above is that the progressmeter on the client side is only updated (repainted) when the controller finishes. This means that for (example) 4 selected items the progressmeter doesn't go 0 -> 25 -> 50 -> 75 -> 100 instead it just goes 0 -> 100. In previous cases when refreshing was the problem i used Events.echoEvent() function, but I think it's not of much use here.

Any ideas how to fix this??

Regards Goran

delete flag offensive retag edit

17 Answers

Sort by ยป oldest newest most voted
0

answered 2012-12-13 06:54:43 +0800

benbai gravatar image benbai
2228 6
http://www.zkoss.org

Hi Neus,

You can put the for loop inside the thread:

Thread myThread = new Thread(){
	public void run(){
		try {
			for (int i = 0; i <= 100; i += 10) {
				   //Do something
				   percent = i;
				System.out.println("El otro thread " + i);
				que.publish(new Event("onActualizaProgreso",null,percent));
				Thread.sleep(1000);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
};
myThread.start();

Regards,
Ben

link publish delete flag offensive edit
0

answered 2012-12-03 16:25:14 +0800

Neus gravatar image Neus
1415 14

Any idea??

link publish delete flag offensive edit
0

answered 2012-11-20 08:13:27 +0800

Neus gravatar image Neus
1415 14

updated 2012-11-20 10:07:47 +0800

Following this http://stackoverflow.com/questions/9274847/illgalthreadstateexception I created the thread inside the loop. It doesn't throw the exception but the progressmeter is not updated for every iteration. I realize that the event called inside the thread (where the progressmeter is updated) is called at the end of the process.

link publish delete flag offensive edit
0

answered 2012-11-20 07:58:58 +0800

Neus gravatar image Neus
1415 14

It seems that it works. But the start() is inside a for loop (the progressmeter has to be updated in every iteration) and I think it is a problem. It's giving me this exception:

GRAVE: >>java.lang.IllegalThreadStateException
>>	at java.lang.Thread.start(Unknown Source)
>>	at org.sts.generales.PantallasZul.Componentes.GestionU2.VentanaAcciones.onClick$BTNProcesar(VentanaAcciones.java:604)
>>	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
>>	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
>>	at java.lang.reflect.Method.invoke(Unknown Source)
>>	at org.zkoss.zk.ui.event.GenericEventListener.onEvent(GenericEventListener.java:88)
>>	at org.zkoss.zk.ui.AbstractComponent.onEvent(AbstractComponent.java:2734)
>>	at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2705)
>>	at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2646)
>>	at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:136)
>>	at org.zkoss.zk.ui.impl.EventProcessingThreadImpl.process0(EventProcessingThreadImpl.java:534)
>>	at org.zkoss.zk.ui.impl.EventProcessingThreadImpl.sendEvent(EventProcessingThreadImpl.java:126)
>>	at org.zkoss.zk.ui.event.Events.sendEvent(Events.java:321)
>>	at org.zkoss.zk.ui.event.Events.sendEvent(Events.java:331)
>>	at org.zkoss.zk.ui.AbstractComponent$ForwardListener.onEvent(AbstractComponent.java:3172)
>>	at org.zkoss.zk.ui.AbstractComponent.onEvent(AbstractComponent.java:2734)
>>	at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2705)
>>	at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2646)
>>	at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:136)
>>	at org.zkoss.zk.ui.impl.EventProcessingThreadImpl.process0(EventProcessingThreadImpl.java:534)
>>	at org.zkoss.zk.ui.impl.EventProcessingThreadImpl.run(EventProcessingThreadImpl.java:461)

I've never worked with threads before so I don't know how to use their methods.

Thank you

link publish delete flag offensive edit
0

answered 2012-11-20 01:14:47 +0800

samchuang gravatar image samchuang
4084 4

hi, @Neus

the sample code you post, you should use myThread.start() ?
you use myThread.run(); will not create a new thread to execute task

link publish delete flag offensive edit
0

answered 2012-11-19 16:20:14 +0800

Neus gravatar image Neus
1415 14

Hi,
I have the same problem. I have a progressmeter that is painted when the controller finishes (it goes from 0->100). I tried with the EventQueues but I don't success, the behaviour is always the same.
I tried something like this:

final EventQueue que = EventQueues.lookup("actualizaProgreso", EventQueues.APPLICATION, true);
	    que.subscribe(new EventListener() {
		public void onEvent(Event evt) {
			   	progresoAcciones.setValue(Integer.valueOf(evt.getData().toString()));//Mostramos el pocentaje en el progressbox
		 }
	 }); 
 Thread myThread = new Thread(){
	public void run(){
		System.out.println("El otro thread");
		que.publish(new Event("onActualizaProgreso",null,percent));
	}
};
for (Iterator<Listitem> it = listItemsSeleccionados.iterator(); it.hasNext(); i++) {
       //Do something
       percent = i * 100/todos;
       myThread.run();
}

This code is executed in a onClick event of a button.
The System.out.println inside the run is executed after the "Do something" but the progressmeter is painted at the end of the controller and goes from 0 to 100.

Have anyone of you solved it? Apiening you say it was easy to solve, can you post your solution please?

Thank you!

link publish delete flag offensive edit
0

answered 2012-07-22 18:27:04 +0800

apiening gravatar image apiening
27

Hi gekkio thank you so much!

I haven't thought that this is could be that easy to solve. I passed a reference to the EventQueue via the constructor of my Runnable class to eliminate the lookup there. It works perfectly well now.

Thank you for your explanation!

link publish delete flag offensive edit
0

answered 2012-07-22 18:04:47 +0800

gekkio gravatar image gekkio flag of Finland
899 1
http://gekkio.fi/blog

If you take a closer look at the exception, there are two things that you should note:
- The message is "Not in an execution"
- The exception is thrown inside the lookup method

The problem is that you cannot lookup an EventQueue without being in an execution (= HTTP Request thread). It's very easy to fix: lookup the EventQueue before starting your thread.

This is the basic idea:

final EventQueue eq = EventQueues.lookup(...);
Thread myThead = new Thread() {
  public void run() {
    // ...
    eq.publish(...);
  }
}
myThread.start();

link publish delete flag offensive edit
0

answered 2012-07-22 17:37:40 +0800

apiening gravatar image apiening
27

Really no one with an idea on that?

I've experimented any further with a second .zul file (update.zul) with it's own GenericForwardComposer. In its overridden doAfterCompose method I can publish events with the same code from my previous example and it works without errors.
The update.zul page blocks while processing the working code and sending the update events to the progress bar, but the progress is displayed on my primary page like I want.
I understand that I have two independent requests now: One blocking while doing the calculation and sending updates via the EventQueue to the primary page and one which loads up and handles the events from the queue non blocking. This way I doesn't even need to create an extra thread manually. But how can I get this working with only one page? I tried to load the second zul file with Executions.createComponents but then the whole page blocks again without processing the updates.

This problem gets somehow annoying... anyone with a hint?

link publish delete flag offensive edit
0

answered 2012-07-21 16:22:12 +0800

apiening gravatar image apiening
27

updated 2012-07-21 16:22:47 +0800

I have found a documentation for EventQueues here: http://books.zkoss.org/wiki/Small_Talks/2009/August/ZK_5:_Chat_with_Event_Queue

I tried to register a basic listener like this:

//Create the event queue und bind the listener
        EventQueues.lookup("my super queue", EventQueues.SESSION, true).subscribe(
                new EventListener() {

                    public void onEvent(Event evt) {
                        System.out.println("Event handler called");
                    }
                });

And I created a Thread that is started in a button click event listener. In the run-method the thread sends an event like this:

EventQueues.lookup("my super queue", EventQueues.SESSION, true).publish(new Event("onSomethingHapping", null, new Integer(43)));

But after starting the thread I get an exception:

Exception in thread "Thread-45" java.lang.IllegalStateException: Not in an execution
	at org.zkoss.zk.ui.event.impl.EventQueueProviderImpl.lookup(EventQueueProviderImpl.java:43)
	at org.zkoss.zk.ui.event.EventQueues.lookup(EventQueues.java:127)
	at ProgressThread.run(ProgressThread.java:23)
	at java.lang.Thread.run(Thread.java:722)

What does this mean and how can I get around this?

Thank you!

link publish delete flag offensive edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2012-03-20 13:46:49 +0800

Seen: 590 times

Last updated: Jun 10 '13

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More