0

Zeta Form - generated code used within another window

asked 2009-03-24 18:39:32 +0800

danielgoodwin gravatar image danielgoodwin
76 2

ZK 3.6.0
ZK Studio 0.9.3

I have been trying out the new Zeta forms part of ZK studio and am highly impressed!
I have a couple questions/observations.

My app uses a single index.zul with a common menu system into which I am 'injecting' other zul files at appropriate points. The injection is done in the code as follows ..

xcontentspanel.getPanelchildren().getChildren().clear();
Panelchildren xChildren = xcontentspanel.getPanelchildren();

Executions.createComponents(actionString + ".zul", xChildren, null);

Where xcontentspanel is a defined panel (autowired)

So lets say I have an entity xxx for which I have created xxx.zul
I can include it ok using above code but I have noticed two things

1. The initial load only shows 1 record
I have noted the comment in generated code as follows but have had to comment it out to get all data on first load of screen.

/initial to read one record so binder.loadAll() will not trigger unnecessary SQL
//The xxxWin.onClientInfo will load correct lines
if (isSupportPaging()) {
//xxxModel.setMaxResults(1);
}

2. The other point is that I get NullException when I click on edit
- I have 'worked' around this by checking for null binder and retrieving it as follows

private void switchMode() {
if (binder == null)
{
log.error("Binder is null");
binder = (AnnotateDataBinder)xxxWin.getVariable("xxxBinder",true);
}
binder.loadComponent(xxxDetail); //reload visible to force refresh
setFocus();
}

I would like to get to bottom of why the above happen and if its something to do with the window inclusion within another, at least then others may take note or we make wizard more 'aware' if possible?

Daniel

PS I am a newbie at ZK, so bear with me it the above does not make entire sense.

delete flag offensive retag edit

4 Replies

Sort by ยป oldest newest

answered 2009-03-25 04:59:09 +0800

kindalu gravatar image kindalu
255

updated 2009-03-25 07:28:54 +0800

Could you provide a minimal runnable code for this problem?
For reproducing the problem.

For second question, what if "binder is still null" after
this line
binder = (AnnotateDataBinder)xxxWin.getVariable("xxxBinder",true);?

link publish delete flag offensive edit

answered 2009-03-25 07:24:42 +0800

iantsai gravatar image iantsai
2755 1

About your two questions:


1. I'm not so sure whats the problem you bombed through your descriptions, but I guess maybe your newly created children are "out of sync".
if you try to load another Zul contents using Executions.createComponent() come from other .zul file, and you want the annotated data binding mechanism still work, you need to rebind the newly created children.

2. As what Kindaliu said, I think you should post your stack dump and provide the code where the problem occurs.

link publish delete flag offensive edit

answered 2009-03-25 09:15:37 +0800

danielgoodwin gravatar image danielgoodwin
76 2

Ok,
The first problem is actually caused by OnClientInfo not getting called as the generated window is NOT the root component of the page. see this thread for more details.

The code itself is the generated code from the new Zeta Form wizard for a simple two field table varchar(10), varchar(50) (taking all the defaults). For the NullpointerException thus all I was trying to do was find out why it was dumping - not necessarily fix it so that the wizard could perhaps be improved. It could be that the 'missing' call to OnClientInfo is also causing this, but as yet I'm unsure.

See this for Zeta form docs

The code generated is quite large so I'm including the relevant details I hope - This is the controller base class.
(apologies for size but the whole class is probably relevant to follow trace.

	
public abstract class AdjcodeControllerBase {
	

	
	/****** Field Edit Components *******/
	@Resource
	protected Textbox ref;
	@Resource
	protected Textbox descript;


	
	
	/****** Zul Specific Application Control *******/
	//main control window
	@Resource
	protected Window adjcodeWin; //main window
	@Resource
	protected Listbox adjcodeDataListView; //domain object summary list
	@Resource
	protected Paging adjcodePaging; //paging control for summary list
	@Resource
	protected Component adjcodeDetail; //domain object detail
	@Resource
	protected Component adjcodeEdit; //edit panel
	//buttons
	@Resource
	protected Button adjcodeCreate; //new button
	@Resource
	protected Button adjcodeUpdate; //edit button
	@Resource
	protected Button adjcodeDelete; //delete button
	@Resource
	protected Button adjcodeSave; //save button
	@Resource
	protected Button adjcodeCancel; //cancel button

	
	
	/****** Bean Field Edit Components *******/
	protected Adjcode _tmpSelected; //store original selected entity
	
	
	
	/****** Controller state Fields *******/
	//ZK databinder
	protected DataBinder binder;
	//Adjcode Model
	@Resource
	protected AdjcodeModelBase adjcodeModel = null;
	//operation transient state
	protected boolean _create; //when new a entity
	protected boolean _editMode; //switch to edit mode when doing editing(new/update)
	protected int _lastSelectedIndex = -1; //last selectedIndex before delete
	protected boolean _supportPaging = true; //switch to use Paging
	protected boolean _supportFilter = true; //TODO: switch to use Filter
	protected String _filter; //filters
	
	
	public AdjcodeControllerBase(){}
	
	@AfterCompose
	public void afterCompose() { 
		//initial to read one record so binder.loadAll() will not trigger unnecessary SQL 
		//The adjcodeWin.onClientInfo will load correct lines
		if (isSupportPaging()) {
			adjcodeModel.setMaxResults(1);
		}
		binder = new AnnotateDataBinder(adjcodeWin);
		adjcodeWin.setVariable("adjcodeBinder", binder, true);
		binder.loadAll();
		
		final List model = (List) adjcodeDataListView.getModel(); 
		if (!model.isEmpty()) {
			adjcodeModel.setSelected((Adjcode)model.get(0));
			binder.loadComponent(adjcodeDetail);
		}
		setFocus();
	}
	
	public boolean isSupportPaging() {
		return _supportPaging;
	}
	
	public boolean isSupportFilter() {
		return _supportFilter;
	}
	
	public boolean isSupportExtra() {
		return isSupportFilter() || isSupportPaging();
	}
	
	public void setFilter(String filter) {
		_filter = filter;
	}
	
	public String getFilter() {
		return _filter;
	}
	
	@Resource
	protected Button adjcodeQuery;
	
	@EventHandler("adjcodeQuery.onClick")
	public void doFilter(){
		if (Strings.isBlank(_filter)) {
			adjcodeModel.setWhere(null);
			adjcodeModel.setParameters(null);
		} else {
			//TODO:shall process filter string into JPQL where statement here
			prepareQueryConditions();
		}
		refreshModel();
	}
	
	protected void prepareQueryConditions(){
		adjcodeModel.setWhere(" ref LIKE :ref OR descript LIKE :descript");
		
		final Map params = new HashMap();
		params.put("ref", "%"+_filter+"%");
		params.put("descript", "%"+_filter+"%");
		adjcodeModel.setParameters(params);
	}
	
	public AdjcodeModelBase getModel() {
		return adjcodeModel;
	}

	public void setModel(AdjcodeModelBase adjcodeModel) {
		this.adjcodeModel = adjcodeModel;
	}
	
	public void refreshModel() {
		binder.loadAttribute(adjcodeDataListView, "model"); //reload model to force refresh
	}

	//-- view/edit mode --//
	public void setEditMode(boolean b) {
		_editMode = b;
		switchMode();
	}
	
	public boolean isViewMode() {
		return !_editMode;
	}
	
	public boolean isEditMode() {
		return _editMode; 
	}

	public boolean isCreate() {
		return _create;
	}
	public boolean isNotCreate() {
		return !_create;
	}
	
	public boolean isNotSelected() {
		return this.adjcodeModel.getSelected() == null;
	}

	private void switchMode() {
		binder.loadComponent(adjcodeDetail); //reload visible to force refresh
		setFocus();
	}
	
	private void setFocus() {
		//post event so doSetFocus after the listbox is loaded ready
		Events.postEvent(new Event("onSetFocus", adjcodeWin));
	}
	
	@EventHandler("adjcodeWin.onSetFocus")
	public void doSetFocus() {
		if (_editMode) {
			ref.focus();
		} else {
			if (((List)adjcodeDataListView.getModel()).isEmpty()) {
				//no result in list, focus on new button
				adjcodeCreate.focus();
			} else {
				if (_create) {
					adjcodeCreate.focus();
				} else {
					setListFocus();
}
			}
		}
	}
	
	private void setListFocus() {
		final Listitem li = adjcodeDataListView.getSelectedItem();
		if (li != null) {
			li.focus();
		} else {
			if (adjcodeModel.getSelected() != null) {
				adjcodeCreate.focus();
			} else {
				adjcodeCreate.focus();
			}
		}
	}
	
	@EventHandler("adjcodeWin.onOK")
	public void doOK(Event event) {
		if (isEditMode()) {
			doSave(event);
		} else {
			doUpdate(event);
		}
	}
	
	@EventHandler("adjcodeWin.onClientInfo")
	public void doClientInfo(Event event) {
		if (isSupportPaging()) {
			final ClientInfoEvent evt = (ClientInfoEvent) event;
			int height = evt.getDesktopHeight();
			int pageSize = Math.max((height - 130) / 14, 10); //estimated page size, at least 10
			int currentPageSize = adjcodeModel.getMaxResults(); 
			if (currentPageSize != pageSize) {
				adjcodeModel.setMaxResults(pageSize);
				final int inviewIndex = adjcodeDataListView.getSelectedIndex() < 0 ? 
					adjcodeModel.getOffset() : (adjcodeModel.getOffset() + adjcodeDataListView.getSelectedIndex()); 
				final int activePage = inviewIndex / pageSize; //new active page
				final int offset = activePage * pageSize;
				adjcodeModel.setOffset(offset);
				refreshModel();
				adjcodePaging.setPageSize(pageSize);
				adjcodePaging.setActivePage(activePage);
				setFocus();
			}
		}
	}
	
	@EventHandler("adjcodePaging.onPaging")
	public void doPaging(Event event) {
		if (isSupportPaging()) {
			final int activePage = adjcodePaging.getActivePage();
			final int offset = activePage * adjcodePaging.getPageSize();
			adjcodeModel.setOffset(offset);
			refreshModel();
			setFocus();
		}
	}
	
	//-- adjcodeDataListView control --//
	@EventHandler("adjcodeDataListView.onSelect")
	public void doSelect(Event event) {
		final int index = adjcodeDataListView.getSelectedIndex();
		if (index >= 0) {
			_lastSelectedIndex = index;
			_create = false;
		}
	}
	
	//-- view mode control --//
	@EventHandler("adjcodeWin.onCtrlKey")
	public void doCtrlKey(Event event) {
		final List items = adjcodeDataListView.getItems(); 
		if (!items.isEmpty() && (!_editMode || !_create)) {
			final int keycode = ((KeyEvent) event).getKeyCode();
			if (keycode == KeyEvent.DOWN || keycode == KeyEvent.UP){
				//handle no selected item case
				if (adjcodeDataListView.getSelectedIndex() < 0) { //no selected item
					//try our best to guess one
					if (_lastSelectedIndex >= 0) {
						final int index = Math.min(items.size() - 1, _lastSelectedIndex);
						adjcodeDataListView.setSelectedIndex(index);
						Events.sendEvent(new SelectEvent("onSelect", adjcodeDataListView, adjcodeDataListView.getSelectedItems()));
					}
				}
				setListFocus();
			}
		}
	}
	
	@EventHandler("adjcodeCreate.onClick")
	public void doCreate(Event event) {
		if (isViewMode()) {
			//prepare a new Adjcode
			_tmpSelected = adjcodeModel.getSelected();
			_create = true;
			adjcodeModel.setSelected(new Adjcode());
			
			//switch to edit mode
			setEditMode(true);
		}
	}
	
	@EventHandler("adjcodeUpdate.onClick")
	public void doUpdate(Event event) {
		if (isViewMode()) {
			if (adjcodeModel.getSelected() != null) {
				_create = false;

				//switch to edit mode
				setEditMode(true);
			}
		}
	}
	
	@EventHandler("adjcodeDelete.onClick")
	public void doDelete(Event event) {
		if (isViewMode()) {
			if (adjcodeModel.getSelected() != null) {
				_create = false;
				newConfirmDelete().show();
			}
		}
	}

	@EventHandler("adjcodeDelete.onDeleteYes")
	public void doDeleteYes(Event event) {
		if (isViewMode()) {
			beforeDelete();
			try {
				adjcodeModel.delete();
				adjcodeCreate.focus();		
			} catch (EntityNotFoundException e) { 
				//ignore, already deleted by others
			}
			adjcodeModel.setSelected(null);
			//refresh the todoList
			refreshModel();
			//update the adjcodeDetail
			switchMode();
		}
	}
	
	//-- sorting --//
	@EventHandler("refHeader.onSort")
	public void doSort(Event event) {
		final Listheader lh = (Listheader) event.getTarget();
		final String sortDirection = lh.getSortDirection(); //original direction
		if ("ascending".equals(sortDirection)) {
			final Comparator cmpr = lh.getSortDescending();
			if (cmpr instanceof FieldComparator) {
				final String orderBy = ((FieldComparator)cmpr).getOrderBy();
				adjcodeModel.setOrderBy(orderBy); //update query string
			}
		} else if ("descending".equals(sortDirection) || "natural".equals(sortDirection) || 
				Strings.isBlank(sortDirection)) {
			final Comparator cmpr = lh.getSortAscending();
			if (cmpr instanceof FieldComparator) {
				final String orderBy = ((FieldComparator)cmpr).getOrderBy();
				adjcodeModel.setOrderBy(orderBy); //update query string
			}
		}
		
		if (isSupportPaging()) {
			refreshModel();
		}
		setFocus();
	}
	
	//-- edit mode control --//
	@EventHandler("adjcodeSave.onClick")
	public void doSave(Event event) {
		if (isEditMode()) {
			//validate
			validate();

			//save into adjcode
			binder.saveComponent(adjcodeEdit); //reload model to force refresh
			
			//store into db
			if (_create) {
				beforeCreate();
				this.adjcodeModel.persist();
			} else {
				beforeUpdate();
				try {
					this.adjcodeModel.merge();
				} catch (EntityNotFoundException e1) {
					try {
						Messagebox.show(getUpdateDeletedMessage());
					} catch (InterruptedException e2) {
						//ignore
					}
				}
			}
			//refresh the todoList
			refreshModel();
			//switch to view mode
			setEditMode(false);
		}
	}

	@EventHandler("adjcodeCancel.onClick,adjcodeWin.onCancel")
	public void doCancel(Event event) {
		if (isEditMode()) {
			//restore to original selected Adjcode if cancel from new
			if (_create) {
				adjcodeModel.setSelected(_tmpSelected);
				_tmpSelected = null;
			}
			
			//switch to view mode
			setEditMode(false);
		}
	}
	
	//--To be override--// 
	/** Validate the input field */
	protected void validate() {
ref.getValue();

	}
	
	/** The info message when end user trying to update a "deleted" entity. */
	protected String getUpdateDeletedMessage() {
		return "Cannot find the selected item, might have been deleted by others.";
	}
	
	/** Get a instance of ConfirmDelete class */
	protected ConfirmDelete newConfirmDelete() {
		return new ConfirmDelete();
	}
	
	/** Delete Confirmation */
	protected class ConfirmDelete {
		/** Show the ConfirmDelete Messagebox */
		public void show() {
			try {
				Messagebox.show(getConfirmMessage(),
				        getConfirmTitle(),
				        Messagebox.YES+Messagebox.NO,
				        Messagebox.EXCLAMATION,
				        new org.zkoss.zk.ui.event.EventListener() {
							public void onEvent(Event event) {
								if ("onYes".equals(event.getName())) {
									doYes();
								}
							}
						}
					);
			} catch (InterruptedException ex) {
				//ignore
			}
		}
		
		/** Operation when end user click Yes button in confirm delete Messagebox*/
		public void doYes() {
			//have to send Event to change the current IdSpace to "adjcodeWin" 
			Events.sendEvent(new Event("onDeleteYes", adjcodeDelete));
		}
	}
	
	protected String getConfirmMessage(){
		return "Are you sure?";
	}
	
	protected String getConfirmTitle(){
		return "Are you sure you want to delete the selected item?";
	}
	
	protected void beforeCreate(){
	}
	
	protected void beforeUpdate(){
	}
	
	protected void beforeDelete(){
	}
}

	

The index.zul relevant part

<center flex="true">
				<panel border="normal" id="xcontentspanel">
					<panelchildren >
						<!--<include style="padding:3px;" id="xcontents" /> -->
					</panelchildren>
				</panel>
			</center>
</code]

Code which sets 'included' file details (use class of index.zul) based on chosen menubaritem option

xcontentspanel.getPanelchildren().getChildren().clear();
Panelchildren xChildren = xcontentspanel.getPanelchildren();

Executions.createComponents(actionString + ".zul", xChildren, null);


Stack ...

SEVERE: >>java.lang.NullPointerException
>> at com.xxx.crud.gen.base.AdjcodeControllerBase.switchMode(AdjcodeControllerBase.java:215)
>> at com.xxx.crud.gen.base.AdjcodeControllerBase.setEditMode(AdjcodeControllerBase.java:192)
>> at com.xxx.crud.gen.base.AdjcodeControllerBase.doCreate(AdjcodeControllerBase.java:337)
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>> at java.lang.reflect.Method.invoke(Method.java:597)
>> at org.zkoss.spring.bean.ZkMethodEventListener.onEvent(ZkMethodEventListener.java:88)
>> at org.zkoss.zk.ui.impl.EventProcessor.process0(EventProcessor.java:199)
>> at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:143)
>>...

link publish delete flag offensive edit

answered 2009-03-30 09:42:35 +0800

danielgoodwin gravatar image danielgoodwin
76 2

Apologies as I'm a bit of a newbie.
>>>
if you try to load another Zul contents using Executions.createComponent() come from other .zul file, and you want the annotated data binding mechanism still work, you need to rebind the newly created children.
<<<

How would I go about doing this?
I have code like this (where I include second zul file within my index.zul file)

    xcontentspanel.getPanelchildren().getChildren().clear();
    Component rootComponent = Executions.createComponents(includeFile + ".zul", xChildren, null);
    if (rootComponent instanceof Window) {
	Window winSub = (Window)rootComponent;
...

I have read the smalltalks/articles on databinding and am still a little confused
(probably why I liked the Zeta forms helper so much!) Do I have to iterate through the components and do something with each?

Any pointer appreciated

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: 2009-03-24 18:39:32 +0800

Seen: 616 times

Last updated: Mar 30 '09

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