package com.vci.client.uif.engine.client; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import com.vci.client.uif.engine.common.IDataNode; public class UILayoutModel implements IUILayoutModel{ private Map> layoutAreaModel = new HashMap>(); private Map modelAreaMap = new HashMap(); private List layoutModes = new ArrayList(); /** * 变更区域影响的重载区域 */ private Map> reloadEffectAreaMap = new HashMap>(); public UILayoutModel() { } public void addLayoutModes(int area, IDataModel cDataModel) { List areaModels = null; if (layoutAreaModel.get(Integer.valueOf(area)) == null) { areaModels = new ArrayList(); layoutAreaModel.put(Integer.valueOf(area), areaModels); } else { areaModels = layoutAreaModel.get(Integer.valueOf(area)); } areaModels.add(cDataModel); this.layoutModes.add(cDataModel); this.modelAreaMap.put(cDataModel, area); } /** * 设置当期区域影响的重载区域 * @param fromArea, 当前区域 * @param effectArea,需要重载的区域 */ public void setReloadEffectArea(int fromArea, int effectArea) { List effectAreaList = null; if (reloadEffectAreaMap.get(fromArea) == null) { effectAreaList = new ArrayList(); } else { effectAreaList = reloadEffectAreaMap.get(fromArea); } effectAreaList.add(effectArea); this.reloadEffectAreaMap.put(fromArea, effectAreaList); } /** * 情况影响刷新区域的配置 */ public void cleanReloadEffectArea() { reloadEffectAreaMap.clear(); } public List getLayoutAreaModes(int area) { return layoutAreaModel.get(Integer.valueOf(area)); } public void removeAreaModels(int area) { List cAreaModel = layoutAreaModel.get(Integer.valueOf(area)); if (cAreaModel != null) { for (IDataModel dataModel : cAreaModel) { layoutModes.remove(dataModel); } } layoutAreaModel.remove(Integer.valueOf(area)); } public List getLayoutModes() { return this.layoutModes; } /** * 记录各个区域 最后一次的sourceData */ private Map areaSourceDataMap = new HashMap(); /** * 各区域之间刷新事件触发入口 * 建议平台能够灵活定义经典主界面中各区域之间的触发关联关系(即无需内置目前这种"左导航"触发"右上"与"右下";"右上"触发"右下"机制,而是可灵活定制各区域之间的事件影响触发关系,且一个复杂界面也需要目前这种上下文UI的嵌套) Add By ZhongGY 2015-02-12 */ @Override public void notify(IDataModel dataModel) { if(modelAreaMap.get(dataModel) == null) { return; } int cArea = modelAreaMap.get(dataModel).intValue(); if (cArea == 1) { //导航树的变化通知到右上区域与右下区域(建议后面有个事件传播定义机制,不要这样约定死了) notifyArea(dataModel, 2); //notifyArea(dataModel, 3); } else if (cArea == 2) { //右上区域的变化通知到右下区域(建议后面有个事件传播定义机制,不要这样约定死了) notifyArea(dataModel, 3); } else { // 右下操作区不向其它区域发送通知,但需要向同一个页签里的其它UI组件发送刷新通知 IDataNode sourceData = getDataModelClickObject(dataModel); notifyAreaInnerModel(dataModel, sourceData); } } /** * 返回IDataMode 点选的数据对象(作为其它区域组件的SourceData) * @param dataModel * @return */ protected IDataNode getDataModelClickObject(IDataModel dataModel){ IDataNode sourceData = null; Object clickObject = dataModel.getClickObject(); if(clickObject != null && clickObject instanceof IDataNode){ sourceData = (IDataNode)clickObject; } return sourceData; } /** * @Title :UI框架统一刷新处理 * @Description : * @param dataModel * @param area */ private void notifyArea(IDataModel dataModel, int area) { IDataNode sourceData = getDataModelClickObject(dataModel); // 存储各个区域真实的sourceData areaSourceDataMap.put(area, sourceData); //更新各区域的Source notifyAreaInnerModel(dataModel, sourceData); List areaList = layoutAreaModel.get(area); if (areaList == null) { return; } Iterator itor = areaList.iterator(); while (itor.hasNext()) { // 设置级联控制区域regionPanel的sourceData对象 IDataModel subDataModel = itor.next(); if(subDataModel.getRegionPanel() != null){ //subDataModel.getRegionPanel().setSourceData(sourceData); //Modify By ZhongGY 2015-07-02;为了优化UI加载与刷新机制,将数据尽量放到Model中(model中的getRegionPanel()可能为空) subDataModel.setSourceData(sourceData); } //subDataModel.refresh(dataModel); //优化刷新处理 by zhonggy 2015-07 subDataModel.refreshUI(dataModel); //优化刷新处理 by zhonggy 2015-07 } } private void notifyAreaInnerModel(IDataModel dataModel, IDataNode sourceData){ List slaveDataModels = areaInnerNotifyModelMap.get(dataModel); if(slaveDataModels != null){ for(IDataModel slaveDataModel : slaveDataModels){ if(slaveDataModel.getRegionPanel() != null){ //slaveDataModel.getRegionPanel().setSourceData(sourceData); slaveDataModel.setSourceData(sourceData); } //slaveDataModel.refresh(dataModel); //优化刷新处理 by zhonggy 2015-07 slaveDataModel.refreshUI(dataModel); //优化刷新处理 by zhonggy 2015-07 } } } public Map getAreaSourceDataMap() { return areaSourceDataMap; } public void setAreaSourceDataMap(Map areaSourceDataMap) { this.areaSourceDataMap = areaSourceDataMap; } private Map> areaInnerNotifyModelMap = new HashMap>(); public void addAreaInnerNotifyModel(IDataModel master, IDataModel slaveDataModel){ List models = areaInnerNotifyModelMap.get(master); if(models == null){ models = new LinkedList(); } models.add(slaveDataModel); areaInnerNotifyModelMap.put(master, models); } /** * 通知影响区域进行刷新 * @param dataModel */ public void notifyRefresh(IDataModel dataModel) { if(modelAreaMap.get(dataModel) == null) { return; } int cArea = modelAreaMap.get(dataModel).intValue(); List creloadArea = reloadEffectAreaMap.get(cArea); if (creloadArea == null || creloadArea.size() == 0) { return; } for (int area : creloadArea) { List areaList = layoutAreaModel.get(area); if (areaList == null) { continue; } Iterator itor = areaList.iterator(); while (itor.hasNext()) { IDataModel subDataModel = itor.next(); subDataModel.setNeedRefreshUI(true); subDataModel.refreshUI(); } } } }