package com.vci.client.uif.engine.client.tableArea.editable; import java.awt.Component; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JTextField; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import javax.swing.text.JTextComponent; import com.vci.client.bof.ClientBusinessObject; import com.vci.client.bof.ClientBusinessObjectOperation; import com.vci.client.bof.ClientLinkObject; import com.vci.client.bof.ClientLinkObjectOperation; import com.vci.client.common.FreeMarkerCommon; import com.vci.client.common.FreemarkerParamObject; import com.vci.client.omd.provider.EnumProvider; import com.vci.client.portal.utility.PRMItem; import com.vci.client.ui.date.PopupCalendarPanel; import com.vci.client.ui.swing.components.VCIJCalendarPanel; import com.vci.client.ui.swing.components.VCIJComboBox; import com.vci.client.ui.swing.components.VCIJOptionPane; import com.vci.client.ui.swing.components.VCIJTable; import com.vci.client.ui.swing.components.VCIJTextField; import com.vci.client.ui.swing.components.table.VCIJTableModel; import com.vci.client.uif.actions.client.PostActionEvent; import com.vci.client.uif.actions.client.PostActionListener; import com.vci.client.uif.actions.client.UIFUtils; import com.vci.client.uif.engine.client.controls.BaseCustomControl; import com.vci.client.uif.engine.client.controls.ControlFactory; import com.vci.client.uif.engine.client.controls.DateTimeControl; import com.vci.client.uif.engine.client.controls.VCIJComboBoxModelValueObject; import com.vci.client.uif.engine.client.tableArea.TablePanel; import com.vci.client.uif.engine.client.tableArea.editable.editor.BaseCellEditor; import com.vci.client.uif.engine.client.tableArea.editable.editor.CustomControlEditor; import com.vci.client.uif.engine.client.tableArea.editable.editor.TextFieldAndComboBoxEditor; import com.vci.client.uif.engine.common.IDataNode; import com.vci.corba.common.VCIError; import com.vci.corba.omd.data.AttributeValue; import com.vci.corba.omd.etm.EnumItem; import com.vci.mw.ClientContextVariable; /** * 支持编辑的TablePanel */ public class EditableTablePanel extends TablePanel { private static final long serialVersionUID = 8635218479503006813L; private final HashMap> cascadeControlsMap = new LinkedHashMap>(); private final HashMap> cascadeValueAndKey = new LinkedHashMap>(); private final HashMap ctrlComboBoxMap = new LinkedHashMap(); private HashMap ctrlComptMap = new LinkedHashMap(); private String sql = null; public HashMap getCtrlComptMap() { return ctrlComptMap; } public void setCtrlComptMap(HashMap ctrlComptMap) { this.ctrlComptMap = ctrlComptMap; } public boolean isSupportEditTableCell(){ return true; } @Override protected void initTableListDetailArea(){ super.initTableListDetailArea(); setTableCellEditor(); } private void setTableCellEditor(){ // 根据此Table中是否需要支持编辑,设置各列的编辑器 if(!getButtonAreaPanel().isEditable()) return; List editableColumnList = getDataProvider().getEditableColumnList(); TableColumnModel tcm = getDataTablePanel().getTable().getColumnModel(); for(int columnIndex : editableColumnList){ TableColumn tc = tcm.getColumn(columnIndex); setTableColumnCellEditor(tc); } } private void setTableColumnCellEditor(TableColumn tc){ int columnIndex = tc.getModelIndex(); String field = getDataProvider().getIndexToFieldMap().get(columnIndex); PRMItem item = getDataProvider().getTableFormPRMItemMap().get(field); // 列不支持编辑,不处理 boolean editable = ControlFactory.isEditable(item); if(!editable) return; Component compt = ControlFactory.createControl(item); ctrlComptMap.put(field, compt); cascadeControlsMapConfig(item); BaseCellEditor editor = null; if(compt instanceof JTextField){ JTextField textField = (JTextField)compt; textField.setEditable(true); textField.setEnabled(true); editor = new TextFieldAndComboBoxEditor(textField); } else if(compt instanceof JComboBox){ final JComboBox cbx = (JComboBox) compt; cbx.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { // TODO Auto-generated method stub if(e.getStateChange() == ItemEvent.SELECTED || e.getStateChange() == ItemEvent.SELECTED+1){ itemChanged(e); } } }); cbx.addFocusListener(new FocusListener() { @Override public void focusLost(FocusEvent e) { // TODO Auto-generated method stub } @Override public void focusGained(FocusEvent e) { focusGain(e); } }); loadComboBoxData(cbx, item, null); ctrlComboBoxMap.put(field, cbx); cbx.setEnabled(true); editor = new TextFieldAndComboBoxEditor(cbx); } else if(compt instanceof DateTimeControl){ final VCIJComboBox VCIcbx = new VCIJComboBox(); VCIcbx.addFocusListener(new FocusListener() { @Override public void focusGained(FocusEvent e) { new PopupCalendarPanel(VCIcbx, true, true, true,"").show();//add by caill 2016.2.24 PopupCalendarPanel.java中增加了参数个数,此处用""来填充 } @Override public void focusLost(FocusEvent e) { } }); editor = new TextFieldAndComboBoxEditor(VCIcbx); } else if(compt instanceof BaseCustomControl){ editor = new CustomControlEditor(new VCIJTextField("")); } if(editor == null){ editor = new TextFieldAndComboBoxEditor(new VCIJTextField("")); } editor.setTablePanel(this); editor.setPrmItem(item); tc.setCellEditor(editor); } //下拉框的选项改变之后,把关联的属性值显示设置为空 private void itemChanged(ItemEvent e){ VCIJTable tab = ((VCIJTable)((VCIJComboBox)e.getSource()).getParent()); int row = tab.getSelectedRow(); int col = tab.getSelectedColumn(); List refcols = new ArrayList(); String field = getDataProvider().getIndexToFieldMap().get(col); if(cascadeControlsMap.containsKey(field)){ List refFields = cascadeControlsMap.get(field); for( String refField : refFields){ //查找相关联的可以编辑的列 TableColumnModel tcm = getDataTablePanel().getTable().getColumnModel(); List editableColumnList = getDataProvider().getEditableColumnList(); for(int columnIndex : editableColumnList){ TableColumn tc = tcm.getColumn(columnIndex); columnIndex = tc.getModelIndex(); String fields = getDataProvider().getIndexToFieldMap().get(columnIndex); if(fields.equalsIgnoreCase(refField)){ refcols.add(columnIndex); } } //关联数据显示为空 VCIJTableModel model = getDataTablePanel().getTableModel(); for(int refcol:refcols){ model.setValueAt("", row, refcol); model.fireTableCellUpdated(row, refcol); getDataTablePanel().setTableModel(model); } } } } //获得鼠标焦点事件,刷新下拉框数据 private void focusGain(FocusEvent e){ // TODO Auto-generated method stub VCIJTable tab = ((VCIJTable)((VCIJComboBox)e.getSource()).getParent()); int row = tab.getSelectedRow(); int col = tab.getSelectedColumn(); String field = getDataProvider().getIndexToFieldMap().get(col); int refcols = -1; JComboBox com = ctrlComboBoxMap.get(field); PRMItem itemto = getDataProvider().getTableFormPRMItemMap().get(field); //获得与属性相关联的属性 if (cascadeValueAndKey.containsKey(field)){ List refFields = cascadeValueAndKey.get(field); if(refFields == null || refFields.size() == 0) { return; } for(String refField: refFields){ PRMItem item = getDataProvider().getTableFormPRMItemMap().get(refField); JComboBox comb = ctrlComboBoxMap.get(refField); TableColumnModel tcm = getDataTablePanel().getTable().getColumnModel(); List editableColumnList = getDataProvider().getEditableColumnList(); for(int columnIndex : editableColumnList) { TableColumn tc = tcm.getColumn(columnIndex); columnIndex = tc.getModelIndex(); String fields = getDataProvider().getIndexToFieldMap().get(columnIndex); if(!fields.equalsIgnoreCase(refField)) { continue; } refcols = columnIndex; String name = tab.getValueAt(row, refcols).toString(); int length = comb.getModel().getSize(); for(int i= 0; i cascadeControlsMapConfig(PRMItem item) { String field = item.getItemField(); List list = new ArrayList(); List refList = new ArrayList(); String itemQueryRefFields = item.getItemQueryRefFields(); if (itemQueryRefFields != null && !"".equals(itemQueryRefFields)) { // 一个属性能够关联 多个属性,被关联的属性名称之间用逗号,分隔 String[] itemQueryRefFieldsArray = itemQueryRefFields.split(","); for (String refField : itemQueryRefFieldsArray) { list.add(refField); if (cascadeValueAndKey.get(refField) == null) { refList = new ArrayList(); } else { refList = cascadeValueAndKey.get(refField); } if (!refList.contains(field)) { refList.add(field); } cascadeValueAndKey.put(refField, refList); } } cascadeControlsMap.put(field, list); return list; } private String getReplacedSql(String sql){ String res = sql; Map valueMap = new HashMap(); appendToValueMap(sql, valueMap); Iterator its = valueMap.keySet().iterator(); while(its.hasNext()){ String key = its.next(); sql = sql.replaceAll(key, key.replace(".", "_")); } Map rootMap = convertValueMapToFPOMap(valueMap); res = FreeMarkerCommon.getValueByTempRule(rootMap, sql); return res; } private Map appendToValueMap(String replaceField, Map valueMap){ String field = replaceField; int begin = field.indexOf("${"); int end = field.indexOf("}"); int len = field.length(); String key = ""; while(!"".equals(field) && begin >= 0 && end < len){ key = field.substring(begin + 2, end); if(!valueMap.containsKey(key)){ valueMap.put(key, key); } field = field.substring(end + 1); begin = field.indexOf("${"); end = field.indexOf("}"); len = field.length(); } return valueMap; } public Map convertValueMapToFPOMap( Map map) { Map rootMap = new LinkedHashMap(); Iterator it = map.keySet().iterator(); while(it.hasNext()){ String key = it.next(); String value = map.get(key); if(value.equals(key)){ value = getValueFromUIControl(key); } if(value == null){ value = ""; } String newKey = key.replace(".", "_"); FreemarkerParamObject fpo = new FreemarkerParamObject(newKey, value); rootMap.put(newKey, fpo); } return rootMap; } private String getValueFromUIControl(String field){ String res = ""; String key = field; Component compt = ctrlComptMap.get(key); if(compt instanceof VCIJComboBox){ VCIJComboBox cbx = (VCIJComboBox)compt; Object obj = cbx.getModel().getSelectedItem(); if(obj != null && obj instanceof VCIJComboBoxModelValueObject){ VCIJComboBoxModelValueObject val = (VCIJComboBoxModelValueObject)obj; if(val != null && !val.getValue().trim().equalsIgnoreCase("")){ res = val.getValue(); } } } else if(compt instanceof JTextComponent){ res = ((JTextComponent)compt).getText(); } else if(compt instanceof VCIJCalendarPanel){ res = ((VCIJCalendarPanel)compt).getDateString(); } return res; } private void loadComboBoxData(JComboBox cbx, PRMItem item, String itemName){ String itemAddFilter = item.getItemAddFilter().toString(); if(itemAddFilter != null && !"".equals(itemAddFilter)){ DefaultComboBoxModel model = new DefaultComboBoxModel(); sql = item.getItemAddFilter(); sql = getReplacedSql(sql); if (sql == null) return; model = convertSQLDataToDataModel(getMulColSQLData(sql, new AttributeValue[0]), itemName); model.insertElementAt(new VCIJComboBoxModelValueObject("",""), 0); cbx.setModel(model); } int length = cbx.getModel().getSize(); if(cbx.getItemCount() < 1){ for(int i = 0; i < length; i++ ){ Object items = cbx.getModel().getElementAt(i); if(items != " " && items != null){ cbx.addItem(items); } } } } private DefaultComboBoxModel convertSQLDataToDataModel(String[][] results, String itemName) { DefaultComboBoxModel model = new DefaultComboBoxModel(); for (String[] res : results) { VCIJComboBoxModelValueObject obj = new VCIJComboBoxModelValueObject(res[0], res[1]); if(obj.toString().equals(itemName)){ model.setSelectedItem(obj); } model.addElement(obj); } return model; } private String[][] getMulColSQLData(String sql, AttributeValue[] attrVals) { String[][] vals = new String[0][0]; ClientBusinessObjectOperation bofactory = new ClientBusinessObjectOperation(); try { vals = bofactory.getSqlQueryResult(sql, attrVals); } catch (VCIError e) { e.printStackTrace(); } return vals; } //add by guo end public void saveChange(Map params) throws Exception { if(!isChanged()) return; if (VCIJOptionPane.showConfirm(this, "您需要保存更改吗?") == VCIJOptionPane.OK_OPTION) { executeEvent("preevent", params); notifyServerEvent(params); if(getDataProvider().getLinkType() == null || getDataProvider().getLinkType().equals("")){ saveChangeToBO(); } else { saveChangeToLO(); } executeEvent("postevent", params); getDataTablePanel().refreshTableData(); } else { getDataTablePanel().refreshTableData(); } setChanged(false); setEditingRowIndex(-1); setEditingColumnIndex(-1); } /** * 把参数值放入全局变量中,以便服务端判断是否执行前后置事件 */ private void notifyServerEvent(Map params) { ClientContextVariable.cleanOtherGlobalVariable(); if(params != null && params.size() > 0) { for(Map.Entry entry : params.entrySet()) { ClientContextVariable.putGlobalVariable(entry.getKey(), entry.getValue()); } } } /** * 执行客户端前后置事件,为Tab编辑功能专用 * @param eventName 事件key * @throws Exception */ private void executeEvent(String eventName, Map params) throws Exception { if(params.containsKey(eventName)) { String className = params.get(eventName); if(className != null && className.length() > 0) { String[] classNames = className.split(";"); for(String name : classNames) { Object obj = Class.forName(name).getConstructor().newInstance(); if(obj instanceof PostActionListener){ PostActionListener pal = (PostActionListener)obj; PostActionEvent e = new PostActionEvent(); e.setSource(this); pal.actionPerformed(e); } } } } } /** * 保存数据变更 */ private void saveChangeToBO(){ List changedCBOs = new LinkedList(); Iterator its = changedRowColumnMap.keySet().iterator(); // 循环发生变量的行 while(its.hasNext()){ int rowIndex = its.next(); ClientBusinessObject cbo = null; IDataNode dataNode = getDataNode(rowIndex); Map valueMap = dataNode.getValueMap(); String oid = valueMap.get("oid"); Object masterObject = dataNode.getMaterObject(); if(masterObject != null && masterObject instanceof ClientBusinessObject){ cbo = (ClientBusinessObject)masterObject; } else { cbo = getCBOById(oid, getDataProvider().getShowType()); } List columnIndexList = changedRowColumnMap.get(rowIndex); // 循环发生变量的列 for(int columnIndex : columnIndexList){ String field = getDataProvider().getIndexToFieldMap().get(columnIndex); Object valObj = getDataTablePanel().getTableModel().getValueAt(rowIndex, columnIndex); String value = getCellValue(valObj); try { cbo.setAttributeValue(field, value); } catch (VCIError e) { UIFUtils.showErrorMessage(this, e); return; } } changedCBOs.add(cbo); } try { ClientBusinessObject[] cbos = changedCBOs.toArray(new ClientBusinessObject[]{}); cboOperation.batchUpdateBuinessObject(cbos); UIFUtils.showMessage(this, "uifmodel.plm.uif.actions.editsuccessmsg", ""); } catch (VCIError e) { UIFUtils.showErrorMessage(this, e); } } private String getCellValue(Object valObj){ String res = valObj.toString(); if(valObj instanceof VCIJComboBoxModelValueObject){ res = ((VCIJComboBoxModelValueObject)valObj).getValue(); } return res; } private ClientBusinessObjectOperation cboOperation = new ClientBusinessObjectOperation(); private ClientBusinessObject getCBOById(String oid, String boName){ ClientBusinessObject cbo = null; try { cbo = cboOperation.readBusinessObjectById(oid, boName); } catch (VCIError e) { e.printStackTrace(); } return cbo; } private ClientLinkObjectOperation cloOperation = new ClientLinkObjectOperation(); private ClientLinkObject getCLOById(String oid, String linkType){ ClientLinkObject clo = null; try { clo = cloOperation.readLinkObjectById(oid, linkType); } catch (VCIError e) { e.printStackTrace(); } return clo; } private IDataNode getDataNode(int rowIndex){ return getDataTablePanel().getSpecialObjectByRowIndex(rowIndex); } private void saveChangeToLO(){ //TODO 当 Table 显示的是Link 关联出来的数据时,暂时只支持保存LINK的TO端的属性 Iterator its = changedRowColumnMap.keySet().iterator(); List changedCBOs_F = new LinkedList(); List changedCBOs_T = new LinkedList(); LinkedList changedCLOs = new LinkedList(); try{ // 循环发生变量的行 while(its.hasNext()){ int rowIndex = its.next(); IDataNode dataNode = getDataNode(rowIndex); Map valueMap = dataNode.getValueMap(); String oid = valueMap.get("oid"); String f_oid = valueMap.get("f_oid"); String t_oid = valueMap.get("t_oid"); String btnName_f = valueMap.get("f_btwname"); String btmName_t = valueMap.get("t_btwname"); Object masterObject = dataNode.getMaterObject(); ClientLinkObject clo = null; if(masterObject != null && masterObject instanceof ClientLinkObject){ clo = (ClientLinkObject)masterObject; } else { clo = getCLOById(oid, getDataProvider().getLinkType()); } List columnIndexList = changedRowColumnMap.get(rowIndex); ClientBusinessObject cbo_f = getCBOById(f_oid, btnName_f); ClientBusinessObject cbo_t = getCBOById(t_oid, btmName_t); // 循环发生变量的列 for(int columnIndex : columnIndexList){ Object valObj = null; if (getDataTablePanel().isEnableSorter()) { valObj = getDataTablePanel().getTableSorter().getValueAt(rowIndex, columnIndex); } else { valObj = getDataTablePanel().getTableModel().getValueAt(rowIndex, columnIndex); } String field = getDataProvider().getIndexToFieldMap().get(columnIndex); String value = getCellValue(valObj); if(field.contains(".")){ String fieldName = field.split("\\.")[1]; EnumItem enumName = EnumProvider.getInstance().getEnumByName(fieldName); if(enumName != null){ String key = EnumProvider.getInstance().getEnumItemValue(fieldName, (String) valObj); if(key != null && key != ""){ value = key; } } } if(field.startsWith("f_oid.")){ field = field.replace("f_oid.", ""); //f_oid.name if(field.contains("\\.")){ //f_oid.usedbypart.name // from 参照属性处理 } else { cbo_f.setAttributeValue(field, value); } } else if(field.startsWith("t_oid.")){ field = field.replace("t_oid.", ""); if(field.contains("\\.")){ // to 端参照属性处理 } else { cbo_t.setAttributeValue(field, value); } } else { clo.setAttributeValue(field, value); } } if(cbo_f.getBusinessObject().newAttrValList.length > 0){ changedCBOs_F.add(cbo_f); } if(cbo_t.getBusinessObject().newAttrValList.length > 0){ changedCBOs_T.add(cbo_t); } if(clo.getLinkObject().newAttrValList.length > 0){ changedCLOs.add(clo); } } LinkedList cbos = new LinkedList(); if(changedCBOs_F.size() > 0){ cbos.addAll(changedCBOs_F); } if(changedCBOs_T.size() > 0){ cbos.addAll(changedCBOs_T); } ClientBusinessObject[] emptyCBOs = new ClientBusinessObject[0]; ClientLinkObject[] emptyCLOs = new ClientLinkObject[0]; cboOperation.batchCUDBOLO( emptyCBOs, emptyCLOs, cbos.toArray(new ClientBusinessObject[]{}), changedCLOs.toArray(new ClientLinkObject[]{}), emptyCBOs, emptyCLOs); UIFUtils.showMessage(this, "uifmodel.plm.uif.actions.editsuccessmsg", ""); }catch(VCIError e){ UIFUtils.showErrorMessage(this, e); } } /** * 数据是否发生了变更 */ private boolean changed = false; /** * 当前牌编辑单元格,编辑前的值 */ private Object oldValue = null; /** * 当前处于编辑中的行(索引) */ private int editingRowIndex = -1; /** * 当前处于编辑中的列(索引) */ private int editingColumnIndex = -1; /** * 变更后的数据行、列 */ private Map> changedRowColumnMap = new HashMap>(); public boolean isEditing(){ return editingRowIndex >= 0 && editingColumnIndex >= 0; } public boolean isChanged() { return changed; } public void setChanged(boolean changed) { this.changed = changed; } public Object getOldValue() { return oldValue; } public void setOldValue(Object oldValue) { this.oldValue = oldValue; } public int getEditingRowIndex() { return editingRowIndex; } public void setEditingRowIndex(int editingRowIndex) { this.editingRowIndex = editingRowIndex; } public int getEditingColumnIndex() { return editingColumnIndex; } public void setEditingColumnIndex(int editingColumnIndex) { this.editingColumnIndex = editingColumnIndex; } public Map> getChangedRowColumnMap() { return changedRowColumnMap; } public void setChangedRowColumnMap( Map> changedRowColumnMap) { this.changedRowColumnMap = changedRowColumnMap; } }