-
FEATURED COMPONENTS
First time here? Check out the FAQ!
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.
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);?
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.
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
Executions.createComponents(actionString + ".zul", xChildren, null);
Stack ...
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; ...
Any pointer appreciated
Asked: 2009-03-24 18:39:32 +0800
Seen: 616 times
Last updated: Mar 30 '09