PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/zkbind/src/org/zkoss/bind/impl/ChildrenBindingListDataListener.java

http://github.com/zkoss/zk
Java | 137 lines | 111 code | 8 blank | 18 comment | 38 complexity | 566183332a5a5c740b95d5a270a510f6 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /* ChildrenBindingListDataListener.java
  2. Purpose:
  3. Description:
  4. History:
  5. 2015/01/16 Created by James Chu
  6. Copyright (C) 2015 Potix Corporation. All Rights Reserved.
  7. */
  8. package org.zkoss.bind.impl;
  9. import java.util.List;
  10. import org.zkoss.bind.BindContext;
  11. import org.zkoss.bind.Converter;
  12. import org.zkoss.bind.sys.BinderCtrl;
  13. import org.zkoss.bind.xel.zel.BindELContext;
  14. import org.zkoss.zk.ui.Component;
  15. import org.zkoss.zk.ui.UiException;
  16. import org.zkoss.zul.ListModel;
  17. import org.zkoss.zul.event.ListDataEvent;
  18. import org.zkoss.zul.event.ListDataListener;
  19. /**
  20. * listen the model data onChange event (support list model in children binding)
  21. * @author James Chu
  22. * @since 8.0.0
  23. */
  24. public class ChildrenBindingListDataListener implements ListDataListener, java.io.Serializable {
  25. private static final long serialVersionUID = 20150116151900L;
  26. private final Component _owner;
  27. private final BindContext _ctx;
  28. private final Converter<?, ListModel<?>, Component> _conv;
  29. public ChildrenBindingListDataListener(Component comp, BindContext ctx,
  30. Converter<?, ListModel<?>, Component> conv) {
  31. this._owner = comp;
  32. this._ctx = ctx;
  33. this._conv = conv;
  34. }
  35. public void onChange(ListDataEvent event) {
  36. onListModelDataChange(new ChildrenBindingListModelDataEvent(event));
  37. }
  38. @SuppressWarnings("unchecked")
  39. private void onListModelDataChange(ListDataEvent event) {
  40. final ListModel<?> model = event.getModel();
  41. int type = event.getType();
  42. int index0 = event.getIndex0();
  43. int index1 = event.getIndex1();
  44. List<Component[]> cbrCompsList = (List<Component[]>) _owner
  45. .getAttribute(BinderCtrl.CHILDREN_BINDING_RENDERED_COMPONENTS);
  46. int oldsz = cbrCompsList == null ? 0 : cbrCompsList.size();
  47. int newsz = model.getSize();
  48. boolean refreshOwnerCBAttr = false;
  49. if (type == ListDataEvent.INTERVAL_ADDED) {
  50. int addedCount = index1 - index0 + 1;
  51. if ((newsz - oldsz) < 0)
  52. throw new UiException("Adding causes a smaller list?");
  53. else if ((oldsz + addedCount) != newsz) { //check live data changed
  54. index0 = oldsz;
  55. index1 = newsz - 1;
  56. }
  57. renderModelData(model, index0, index1);
  58. } else if (type == ListDataEvent.CONTENTS_CHANGED) {
  59. if (index0 >= 0 && index1 >= 0) {
  60. renderModelData(model, index0, index1);
  61. cbrCompsList = (List<Component[]>) _owner.getAttribute(BinderCtrl.CHILDREN_BINDING_RENDERED_COMPONENTS);
  62. int count = (index1 - index0) + 1;
  63. //remove old
  64. int oIndex = index1 + 1;
  65. for (int i = 0; i < count; i++) {
  66. Component[] oldComps = cbrCompsList.get(oIndex);
  67. for (Component oc : oldComps)
  68. oc.detach();
  69. cbrCompsList.remove(oIndex);
  70. }
  71. refreshOwnerCBAttr = true;
  72. } else //sync model
  73. syncModel(model);
  74. } else if (type == ListDataEvent.INTERVAL_REMOVED) {
  75. if (oldsz - newsz < 0)
  76. throw new UiException("Removal causes a larger list?");
  77. if (cbrCompsList != null) {
  78. for (int i = index0; i <= index1; i++) {
  79. Component[] oldComps = cbrCompsList.get(index0);
  80. if (oldComps != null) {
  81. for (Component oc : oldComps) {
  82. oc.detach();
  83. }
  84. }
  85. cbrCompsList.remove(index0);
  86. }
  87. }
  88. refreshOwnerCBAttr = true;
  89. }
  90. if (refreshOwnerCBAttr)
  91. _owner.setAttribute(BinderCtrl.CHILDREN_BINDING_RENDERED_COMPONENTS, cbrCompsList);
  92. }
  93. @SuppressWarnings("unchecked")
  94. private void syncModel(ListModel<?> model) {
  95. //clear all
  96. List<Component[]> cbrCompsList = (List<Component[]>) _owner
  97. .getAttribute(BinderCtrl.CHILDREN_BINDING_RENDERED_COMPONENTS);
  98. if (cbrCompsList != null) {
  99. _owner.removeAttribute(BinderCtrl.CHILDREN_BINDING_RENDERED_COMPONENTS);
  100. for (Component[] oldComps : cbrCompsList) {
  101. if (oldComps != null) {
  102. for (Component oc : oldComps) {
  103. oc.detach();
  104. }
  105. }
  106. }
  107. }
  108. renderModelData(model, 0, model.getSize() - 1);
  109. }
  110. @SuppressWarnings("unchecked")
  111. private void renderModelData(ListModel<?> model, int from, int to) {
  112. BindChildRenderer renderer = new BindChildRenderer();
  113. if (_conv != null) {
  114. List<Object> data = (List<Object>) _conv.coerceToUi(model, _owner, _ctx);
  115. BindELContext.addModel(_owner, data);
  116. if (data != null) {
  117. int size = data.size();
  118. if (to >= size)
  119. to = size - 1;
  120. for (int i = from; i <= to; i++)
  121. renderer.render(_owner, data.get(i), i, size, true);
  122. }
  123. }
  124. }
  125. }