0

onCreate gets called twice when used with GenericForwardComposer

asked 2010-10-05 16:02:42 +0800

zknewbie1 gravatar image zknewbie1
370 4

I tried a quick test and get a very weird result: the onCreate for the Label component got called twice!! Could you run the test code below and check your Tomcat log output to see if you see the same symptom? I just put this question in a new forum's Thread since it's a new topic (the original question was related to a setFocus issue on a different forum's Thread). Any insight is greatly appreciated. Thanks..

ZUL file:
======

<?xml version="1.0" encoding="UTF-8"?>
<zk xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns='http://www.zkoss.org/2005/zul'
    xmlns:h='http://www.w3.org/1999/xhtml'
    xsi:schemaLocation='http://www.zkoss.org/2005/zul WEB-INF/xsd/zul.xsd'
    >

<window id='testWin' apply='GcmScLaunch.ControllerTestWin'
        border='normal' title='A Test Page'>
  <label value='Just a quick test on the order of method execution...'/><h:br/>
  <label id='currDateLabel' forward='onCreate=onCreate$currDateLabel'/>
  
</window>
</zk>

Controller file:
==========

package GcmScLaunch;

import java.sql.SQLException;
import javax.servlet.ServletContext;
import java.util.*;
import java.io.*;
import org.zkoss.zul.*;
import org.zkoss.zk.ui.*;
import org.zkoss.zk.ui.ext.*;
import org.zkoss.zk.ui.event.*;
import org.zkoss.zk.ui.util.*;

/** Controller class for test.zul page */

public class ControllerTestWin extends GenericForwardComposer {
  //private ZKCommonUtils zkCommonUtils = new ZKCommonUtils();
  //Auto-wire components
  private Window testWin;
  private Label currDateLabel;

  /** Controller constructor */
  public ControllerTestWin() {
    System.out.println("================= Checking Order of execution ==================");
    System.out.println("this is Constructor")  ;
  }//end contructor

  @Override
  public void doAfterCompose(Component win) throws Exception {
    super.doAfterCompose(win);
    System.out.println("This is doAfterCompose()");
  }//end method

  /** currDateLabel onCreate event-handler */
  public void onCreate$currDateLabel(Event event) throws Exception {
    System.out.println("this is Label onCreate");       
  }//end method
  
}//end class
 

delete flag offensive retag edit

12 Replies

Sort by ยป oldest newest

answered 2010-10-05 17:05:33 +0800

twiegand gravatar image twiegand
1807 3

Results for me in 5.0.4:

================= Checking Order of execution ==================
this is Constructor
This is doAfterCompose()
this is Label onCreate
this is Label onCreate

Todd

link publish delete flag offensive edit

answered 2010-10-05 19:51:53 +0800

samchuang gravatar image samchuang
4084 4

Hi

the second event is from zul file

forward='onCreate=onCreate$currDateLabel'

remove this line, only composer register onCreate event, then one event remain

link publish delete flag offensive edit

answered 2010-10-05 19:54:07 +0800

zknewbie1 gravatar image zknewbie1
370 4

Thanks Todd, yeap, that's it, that's the symptom!

link publish delete flag offensive edit

answered 2010-10-05 20:08:13 +0800

zknewbie1 gravatar image zknewbie1
370 4

Hi Samchuang, I removed as you suggested and the currDateLabel's onCreate does not get executed at all. Hi Todd, could you run again without the forward phrase and see if you see the same thing as I do?

link publish delete flag offensive edit

answered 2010-10-05 21:25:43 +0800

samchuang gravatar image samchuang
4084 4

Hi

the reason is, use forward will post onCreate, refer to http://books.zkoss.org/wiki/ZK_Developer%27s_Reference/Event_Handling/Event_Forwarding

in your java code, you register label's onCreate event, in zul, you forward to onCreate$currDateLabel method

that's why, it called twice, to avoid this, in java file, don't register onCreate event, so, change from onCreate$currDateLabel to onCreateDateLabel

	  public void onCreateDateLabel(CreateEvent event) throws Exception {
		    System.out.println("this is Label onCreate" + event.getTarget());       
		  }//end method

in zul code,

<label id='currDateLabel' forward='onCreate=testWin$comnposer.onCreateDateLabel'/>

link publish delete flag offensive edit

answered 2010-10-05 22:11:12 +0800

zknewbie1 gravatar image zknewbie1
370 4

Hi Samchuang, thanks for the link. From the link, it says we can register event either thru java code OR thru zul's forward attribute. In this case, how come only the Zul's forward approach work, but not the java code approach? When I don't use forward attribute, and only use onCreate$currDateLabel(Event event) in java code, why this event never get triggered??

link publish delete flag offensive edit

answered 2010-10-05 23:33:46 +0800

samchuang gravatar image samchuang
4084 4

updated 2010-10-05 23:49:14 +0800

Hi

The reason is relative to Life cycle.

onCreate event is different from other event, it will fire when ZK create the component

Composer will register event after create component. By this time, event has fired already.

please refer to http://books.zkoss.org/wiki/ZK_Developer's_Guide/Fundamental_ZK/Basic_Concepts/Architecture_Overview#The_Life_cycle_of_Loading_Pages

doAfterComposer is done after component created

link publish delete flag offensive edit

answered 2010-10-06 08:38:57 +0800

zknewbie1 gravatar image zknewbie1
370 4

Hi Samchuang, thanks for the link. Is there a way to show these Life cycle sequence in the Java code (which is what I was trying to do at the beginning of this thread)? My good friend Stephan showed some utility classes to see the number of components created. It'd be nice to also see the "sequence" of operation. Back to the onCreate event, another weird thing happens when I change the onCreate$currDateLabel(event) to onCreate$testWin(event), this time the onCreate event for the tesWindow is invoked!! Could you describe the exact load sequence for my particular example which has 4 components: the testWin, a Label, a <br/>, and the currDateLabel ?

================= Checking Order of execution ==================
this is Constructor
This is doAfterCompose()
this is main Win onCreate

link publish delete flag offensive edit

answered 2010-10-10 20:45:28 +0800

samchuang gravatar image samchuang
4084 4

Hi @zknewbie1

I think your question is very good,

from the javadoc, setApply()

it mentioned, the component is not created yet when the apply attribute is evaluated, so it seems the creation is different from composer's children

you can also refer to Component life cycle, Architecture Overview

link publish delete flag offensive edit

answered 2010-10-11 01:05:20 +0800

samchuang gravatar image samchuang
4084 4

Hi

after tested it, the sequence is

1. ) doBeforeCompose
2. ) new Component, here create children component
3. ) doAfterCompose
4. ) applyForward
5. ) post onCreate event if listen to

<?page title="new page title" contentType="text/html;charset=UTF-8"?>
<zk>
<zscript><![CDATA[
import org.zkoss.zk.ui.metainfo.*;

class WinComposer extends org.zkoss.zk.ui.util.GenericForwardComposer {
	Window win;
	Label label;
	
	public ComponentInfo doBeforeCompose(Page page, Component parent,
			ComponentInfo compInfo) {
		System.out.println("doBeforeCompose, parent: " + parent);
		return compInfo;
	}
	
	public void doAfterCompose(Component comp) throws Exception {
		System.out.println("WinComposer before super.doAfterCompose children size: " + comp.getChildren().size());
		
		//in super.doAfterCompose(), wire event, register event
		//we can think as we use addEventListener
		//for example
		//label.addEventListener(Events.ON_XXX, )
		super.doAfterCompose(comp);
		System.out.println("win doAfterCompose: " + comp);
	}
	
	//public void onCreate$label1() {
		//will not called here, since children will create first, 
		//Then, in doAfterCompose(), will add onCreate listener, but label already created
		//System.out.println("onCreate$label1");
	//}
	
	public void onCreateLabel1ByForward() {
		System.out.println("onCreateByForward, will fire after doAfterCompose");
	}
	
	public void onCreate$win() {
		System.out.println("onCreate$win");
	}
}
class Label2 extends Label {
	public Label2() {
		System.out.println("Label2 Constructor");
	}
	
	public void onCreate() {
		//use "use"
		System.out.println("Label2 onCreate");
	}
}


]]></zscript>
<window id="win" title="new page title" border="normal" apply="WinComposer" onCreate='System.out.println("win onCreate")'>
	<label id="label1" forward="onCreate=onCreateLabel1ByForward" value="Label1"></label>
	<label id="label2" use="Label2" value="Label2"></label>
</window>
</zk>

link publish delete flag offensive edit
Your reply
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: 2010-10-05 16:02:42 +0800

Seen: 1,058 times

Last updated: Oct 11 '10

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