package com.vci.client.uif.engine.client.TreeTable; import java.awt.BorderLayout; import java.awt.Component; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Vector; import javax.swing.JOptionPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.table.TableColumnModel; import javax.swing.tree.TreePath; import com.vci.client.bof.ClientBusinessObject; import com.vci.client.bof.ClientLinkObject; import com.vci.client.portal.utility.DataModelFactory; import com.vci.client.portal.utility.PLDefination; import com.vci.client.ui.swing.VCISwingUtil; import com.vci.client.ui.swing.components.VCIJButton; import com.vci.client.ui.swing.components.VCIJLabel; import com.vci.client.ui.swing.components.VCIJOptionPane; import com.vci.client.ui.swing.components.VCIJPanel; import com.vci.client.ui.swing.components.VCIJScrollPane; import com.vci.client.ui.swing.components.VCIJTextField; import com.vci.client.ui.treeTable.InterfaceTreeTableModel; import com.vci.client.ui.treeTable.JTreeTable; import com.vci.client.ui.treeTable.TreeTableModel; import com.vci.client.ui.treeTable.TreeTableModel.TreeTableNode; import com.vci.client.uif.actions.client.UIFUtils; import com.vci.client.uif.engine.client.AbstractRegionPanel; import com.vci.client.uif.engine.client.BasePanel; import com.vci.client.uif.engine.client.IRegionPanel; import com.vci.client.uif.engine.client.UIHelper; import com.vci.client.uif.engine.client.tree.SearchTipDialog; import com.vci.client.uif.engine.common.DefaultTableNode; import com.vci.client.uif.engine.common.IDataNode; import com.vci.client.uif.engine.common.api.TreeTableRootDataProvider; import com.vci.corba.omd.data.BusinessObject; import com.vci.mw.ClientContextVariable; public class TreeTablePanel extends AbstractRegionPanel { /** * */ private static final long serialVersionUID = 5623994358027905220L; private VCIJLabel lblFound = new VCIJLabel("查找:"); private VCIJTextField txtFound = new VCIJTextField("", 25); private VCIJButton btnFound = VCISwingUtil.createVCIJButton("found", "", "按输入内容进行模糊匹配查找", "search.gif"); private VCIJButton btnRefresh = VCISwingUtil.createVCIJButton("refresh", "刷新", "刷新当前选择节点的数据", "pagination_refresh.png"); private JTreeTable treeTable = null; private TreeTableDataModel treeTableModel = null; private TreeTableModel.TreeTableNode rootNode = null; private Object rootObj = null; private TreeTablePanel instance = null; private String cStr = null; private Map cSearMap = new HashMap(); public TreeTablePanel(Object sourceData,String type,String context,PLDefination defination){ setComponentPanel(this); //start 加入空值判断,如果为空给一个默认值, by liucq if(sourceData == null){ sourceData = new DefaultTableNode(); } //end rootObj = sourceData; dataProvider = new TreePanelDataProvider(this, factory, type, context, defination); headerColumns = dataProvider.getColumns(); columnClasses = getTreeTablerHeaderClass(headerColumns); treeTableModel = new TreeTableDataModel(rootObj, headerColumns, columnClasses, this); //start 在加载数据之前设定sourceData by liucq rootNode = treeTableModel.getRootNode(); rootNode.setLeaf(false); rootNode.setExpand(true); rootNode.setObj(rootObj); treeTableModel.setSourceData((IDataNode)sourceData); //end this.setDataModel(treeTableModel); } @Override public void preInit(String type, String context) { super.preInit(type, context); } private String firstOid = ""; @Override public Component init() { // 记录进入本模块时的主对象OID if(firstOid != null && "".equals(firstOid)){ firstOid = this.getBusinessObjectOid(this.getSourceData()); } setLayout(new BorderLayout(3, 3)); add(initSearchArea(), BorderLayout.NORTH); add(initTreeTableArea(), BorderLayout.CENTER); setBuilt(true); instance = this; setComponentPanel(this); setBuilt(true); return this; } private VCIJPanel initSearchArea(){ VCIJPanel pal = new VCIJPanel(new FlowLayout(FlowLayout.LEADING)); pal.add(lblFound); pal.add(txtFound); pal.add(btnFound); pal.add(btnRefresh); addButtonToPanel(pal); btnFound.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { found(); } }); btnRefresh.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { refresh(); } }); txtFound.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if(!txtFound.getText().trim().equals("") && e.getKeyCode() == KeyEvent.VK_ENTER){ found(); } } }); VCIJPanel palNorth = new VCIJPanel(new BorderLayout()); String tableTitle = "数据列表"; if(this.getTabPage() != null){ // TODO 等待 defination 对象增加 name 属性 tableTitle = getDefination().getName(); } palNorth.add(UIHelper.getTitleBar(tableTitle, "base.png"), BorderLayout.NORTH); palNorth.add(pal, BorderLayout.CENTER); return palNorth; } private void addButtonToPanel(VCIJPanel pal){ BasePanel btnPanel = new BasePanel(factory, getType(), getContext(), getDefination()); VCIJButton[] btns = btnPanel.getButtonsByTabPageId(getTabId(), this); for (VCIJButton btn : btns) { pal.add(btn); } } private void found(){ String searchVal = txtFound.getText(); if (searchVal.equals("")) { JOptionPane.showMessageDialog(ClientContextVariable.getFrame(), "请填写需要查询的条件进行查找!"); return; } if (this.rootNode.toString().indexOf(searchVal) >= 0 && !isSearched(rootNode, searchVal)) { treeTable.getTree().setSelectionPath(new TreePath(rootNode.getPath())); } else { if (rootNode.getChildren().length == 0) { JOptionPane.showMessageDialog(ClientContextVariable.getFrame(), "导航树查找完毕!"); return; } this.setFinish(false); this.setCancel(false); startSearch(searchVal); } } private void startSearch(final String searchVal) { Thread t = new Thread(){ public void run() { iteratorTree(rootNode, searchVal); if (TreeTablePanel.this.isFinish()) { return; } else { TreeTablePanel.this.setFinish(true); JOptionPane.showMessageDialog(ClientContextVariable.getFrame(), "导航树查找完毕!"); } } }; SearchTipDialog tipDialog = new SearchTipDialog(ClientContextVariable.getFrame(), t, instance); tipDialog.setVisible(true); } private void iteratorTree(TreeTableModel.TreeTableNode parentNode, String searchVal) { int count = 0; if (parentNode.getChildren() == null) { count = 0; } else { count = parentNode.getChildren().length; } if (count == 0) { return; } for (int i = 0; i < count; i++) { if (isCancel()) { return; } TreeTableModel.TreeTableNode cNode = (TreeTableModel.TreeTableNode)parentNode.getChildAt(i); if (cNode.toString().indexOf(searchVal) >= 0 && !isSearched(cNode, searchVal)) { this.setFinish(true); treeTable.getTree().setSelectionPath(new TreePath(cNode.getPath())); return; } iteratorTree(cNode, searchVal); } } /** * 判断当前节点是否被查询过 * @param cNode * @param searchVal * @return */ private boolean isSearched(TreeTableModel.TreeTableNode cNode, String searchVal) { if (cStr == null) { cStr = searchVal; cSearMap.clear(); } else if (!cStr.equals(searchVal)) { cStr = searchVal; cSearMap.clear(); } Object nodeObj = cNode.getObj(); if (nodeObj instanceof InnerClientBuinessObject) { String key = ((InnerClientBuinessObject)nodeObj).getOid(); if (cSearMap.containsKey(key)) { return true; } else { cSearMap.put(key, nodeObj); } } else { IDataNode dataNode = (IDataNode)nodeObj; String key = ""; if (dataNode.getMaterObject() instanceof ClientBusinessObject) { key = ((ClientBusinessObject)dataNode.getMaterObject()).getOid(); } else if (dataNode.getMaterObject() instanceof ClientLinkObject){ key = ((ClientLinkObject)dataNode.getMaterObject()).getOid(); } if (cSearMap.containsKey(key)) { return true; } else { cSearMap.put(key, nodeObj); } } return false; } /* @Override public void setSourceData(IDataNode sourceData){ // 如果设置的sourceData为null,则创建一个默认的空实例对象 if(sourceData == null){ sourceData = new DefaultTableNode(); } super.setSourceData(sourceData); rootObj = sourceData; if(rootNode != null){ rootNode.setObj(rootObj); } }*/ private DataModelFactory factory = new DataModelFactory(); private TreePanelDataProvider dataProvider = null; private String[] headerColumns = new String[0]; private Class[] columnClasses = new Class[0]; private VCIJPanel initTreeTableArea(){ VCIJPanel pal = new VCIJPanel(new BorderLayout()); treeTable = new JTreeTable(treeTableModel); treeTable.setRowHeight(25); treeTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); treeTable.getTableHeader().setReorderingAllowed(false); treeTable.getTableHeader().setResizingAllowed(true); treeTable.setColumnSelectionAllowed(false); treeTable.setShowGrid(true); treeTable.getColumnModel().getColumn(0).setMinWidth(200); treeTable.getTree().setCellRenderer(new TreeTableCellRenderer()); treeTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); treeTable.setRowHeight(VCISwingUtil.JTABLE_ROW_HEIGHT); treeTable.setFont(VCISwingUtil.FONT_DEFAULT); treeTable.getTableHeader().setFont(VCISwingUtil.FONT_DEFAULT); treeTable.getColumnModel().getColumn(0).setMinWidth(200); treeTable.getColumnModel().getColumn(0).setPreferredWidth(200); treeTable.getColumnModel().getColumn(0).setWidth(200); setTreeTableColumnWidth(treeTable.getColumnModel()); treeTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); treeTable.getTree().setFont(VCISwingUtil.FONT_DEFAULT); //setDataModel(treeTableModel); pal.add(new VCIJScrollPane(treeTable), BorderLayout.CENTER); currentTreeNode = rootNode; treeTable.setColumnSelectionAllowed(true);// 列选择模式 treeTable.getColumnModel().getColumn(0).setPreferredWidth(350); treeTable.getTree().setSelectionPath(new TreePath(rootNode)); treeTable.updateUI(); treeTable.getTree().updateUI(); initTreeTableActionListenerEvent(treeTable); setUserClick(false); // 加载根节点数据 reloadCurrenTreeNodeData(); return pal; } private TreeTableRootDataProvider rootDataProvider = null; private TreeTableRootDataProvider getRootDataProvider(){ if(rootDataProvider == null){ synchronized (TreeTablePanel.class) { if(rootDataProvider == null){ String className = getDefination().getDescription();//"plm617.client.dataProvider.WIToDistGRPRootDataProvider"; rootDataProvider = getRootDataProvider(className); } } } return rootDataProvider; } /** * 根据完整限定名的 className 创建TreeTableRootDataProvider的实例 * @param className className 完整限定名,必须要实现 plm.uif.engine.common.api.TreeTableRootDataProvider 接口 * @return */ private TreeTableRootDataProvider getRootDataProvider(String className){ TreeTableRootDataProvider res = null; if(className == null || "".equals(className)) return res; try{ Object obj = Class.forName(className).getConstructor(null).newInstance(null); if(obj != null && obj instanceof TreeTableRootDataProvider){ res = (TreeTableRootDataProvider) obj; } }catch (Exception e) { e.printStackTrace(); } return res; } private void initTreeTableActionListenerEvent(final JTreeTable treeTable){ treeTable.getTree().addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { treePanel_tree_valueChanged(e); } }); treeTable.getTree().addTreeExpansionListener(new TreeExpansionListener(){ @Override public void treeExpanded(TreeExpansionEvent e) { treeTable_tree_treeExpanded(e); } @Override public void treeCollapsed(TreeExpansionEvent e) { treeTable_tree_treeCollapsed(e); } }); treeTable.getSelectionModel().addListSelectionListener(new ListSelectionListener(){ @Override public void valueChanged(ListSelectionEvent e) { if(!isUserClick()) { setUserClick(true); return; } int row = treeTable.getSelectedRow(); if (row != -1) { Object obj = treeTable.getTree().getLastSelectedPathComponent(); if(obj == null) return; TreeTableModel.TreeTableNode treeTableNode = null; if(obj instanceof TreeTableModel.TreeTableNode){ treeTableNode = (TreeTableModel.TreeTableNode)obj; } if(treeTableNode == null) return; if(TreeTablePanel.this.getDataModel() == null) return; TreeTablePanel.this.getDataModel().setClickObject(treeTableNode.getObj()); if(TreeTablePanel.this.getDataModel().getUILayoutModel() == null) return; TreeTablePanel.this.getDataModel().getUILayoutModel().notify(TreeTablePanel.this.getDataModel()); } } }); } private boolean userClick = true; public boolean isUserClick() { return userClick; } public void setUserClick(boolean userClick) { this.userClick = userClick; } private TreeTableModel.TreeTableNode currentTreeNode = null; private void treePanel_tree_valueChanged(TreeSelectionEvent e){ TreePath treePath = e.getPath(); if(!isMatchedNode(treePath)) return; TreeTableModel.TreeTableNode treeNode = (TreeTableModel.TreeTableNode)treePath.getLastPathComponent(); currentTreeNode = treeNode; setUserClick(false); } private void treeTable_tree_treeExpanded(TreeExpansionEvent e){ TreePath treePath = e.getPath(); if(!isMatchedNode(treePath)) return; TreeTableModel.TreeTableNode treeNode = (TreeTableModel.TreeTableNode)treePath.getLastPathComponent(); if(treeNode.isExpand()) return; treeExpanded_Handler(treeNode); treeNode.setExpand(false); } private void refresh(){ TreePath treePath = treeTable.getTree().getSelectionPath(); int selectedRow = treeTable.getSelectedRow(); if(treePath == null || selectedRow == -1){ VCIJOptionPane.showMessage(ClientContextVariable.getFrame(), "请先选择数据再进行此操作!"); return; } if(!isMatchedNode(treePath)) return; //判断选中的是否是根节点 if(selectedRow == 0) { reloadCurrenTreeNodeData(); } else { TreeTableModel.TreeTableNode treeNode = (TreeTableModel.TreeTableNode)treePath.getLastPathComponent(); treeExpanded_Handler(treeNode); if(treeNode.getParent() != null){ TreeTableModel.TreeTableNode parentTreeNode = (TreeTableNode) treeNode.getParent(); if(parentTreeNode.getParent() == null){ reloadCurrenTreeNodeData(); } else { treeExpanded_Handler(parentTreeNode); } } treeTable.updateUI(); } } private void treeExpanded_Handler(TreeTableModel.TreeTableNode treeNode){ currentTreeNode = treeNode; treeTable.getTree().setSelectionPath(new TreePath(currentTreeNode)); Object obj = treeNode.getObj(); if(obj instanceof IDataNode ){ IDataNode dataNode = (IDataNode) obj; loadTreeTableData(treeNode, dataNode, getDefination().getExpandMode(), false); } } private void treeTable_tree_treeCollapsed(TreeExpansionEvent e){ } private boolean isMatchedNode(TreePath treePath){ boolean res = false; if(treePath.getLastPathComponent() instanceof TreeTableModel.TreeTableNode){ res = true; } return res; } private ClientBusinessObject rootBusinessObject = null; public ClientBusinessObject getRootBusinessObject(){ return rootBusinessObject; } private Object getRootObject(){ return this.getSourceData(); } private Class[] getTreeTablerHeaderClass(String[] columns){ Class[] classes = new Class[columns.length]; classes[0] = InterfaceTreeTableModel.class; for (int i = 1; i < columns.length; i++) { classes[i] = String.class; } return classes; } private void loadTreeTableData(TreeTableModel.TreeTableNode parenTreetNode, IDataNode parentDataNode, String expandMode, boolean fromRoot){ parenTreetNode.removeAll(); IDataNode[] dataNodes = new IDataNode[0]; LinkedList btmNameList = new LinkedList(); if(fromRoot && getRootDataProvider() != null){ if(getSourceData().getValueMap().containsKey("btmname")){ btmNameList.add(getSourceData().getValueMap().get("btmname")); } dataNodes = getRootDataProvider().getRootDatas(getSourceData()).toArray(dataNodes); if(dataNodes.length > 0 && dataNodes[0] != null){ Object masterObject = dataNodes[0].getMaterObject(); if(masterObject instanceof ClientLinkObject){ String btmName = ((ClientLinkObject)masterObject).getLinkObject().toBTName; if(!btmNameList.contains(btmName)){ btmNameList.add(btmName); } }else if(masterObject instanceof ClientBusinessObject){ String btmName = ((ClientBusinessObject)masterObject).getBusinessObject().btName; if(!btmNameList.contains(btmName)){ btmNameList.add(btmName); } } } if(btmNameList.size() > 0){ dataProvider.calcAttrEnumMapForBtmType(btmNameList.toArray(new String[]{})); } } else { dataNodes = dataProvider.getDatasByParentDataNode(1, 1000, parentDataNode); } long start = System.currentTimeMillis(); int index = 0; Vector children = new Vector(); for(IDataNode dataNode : dataNodes){ index++; InnerDataNode dataNodeNew = convertToInnerDataNode(dataNode); dataNode.setForward(dataProvider.getQueryTemplateDirectory()); TreeTableModel.TreeTableNode newNode = treeTableModel.new TreeTableNode(parenTreetNode, dataNodeNew); newNode.setLeaf(false); newNode.setExpand(false); children.add(newNode); setTreeTableNodePropertyValue(newNode, dataNode); if (expandMode != null && expandMode.equals("0")) { newNode.setLeaf(false); newNode.setExpand(true); treeTable.getTree().expandPath(new TreePath(newNode)); loadTreeTableData(newNode, dataNode, expandMode, false); } } parenTreetNode.setChildren(children); TreeTableNode[] path = parenTreetNode.getPath(); treeTableModel.fireTreeStructureChanged(treeTableModel, path, null, null); long end = System.currentTimeMillis(); UIFUtils.writeClientLog("将数据添加到TreeTable:", start, end); parenTreetNode.setLeaf(false); parenTreetNode.setExpand(true); } private InnerDataNode convertToInnerDataNode(IDataNode dataNode){ DefaultTableNode res = new InnerDataNode(); res.setMasterObject(dataNode.getMaterObject()); res.setValueMap(dataNode.getValueMap()); res.setForward(dataNode.isForward()); return (InnerDataNode)res; } private void setTreeTableNodePropertyValue(TreeTableModel.TreeTableNode treeNode, IDataNode obj){ for (int i = 1; i < headerColumns.length; i++) { String header = headerColumns[i]; treeNode.setPropertyValueByName(header, dataProvider.getPropertyValue(obj, header)); } } private void setTreeTableColumnWidth(TableColumnModel columnModel){ int preWidth = 250; int minWidth = 1; int maxWidth = 1500; int width = preWidth; for (int i = 1; i < columnModel.getColumnCount(); i++) { columnModel.getColumn(i).setPreferredWidth(preWidth); columnModel.getColumn(i).setMinWidth(minWidth); columnModel.getColumn(i).setMaxWidth(maxWidth); columnModel.getColumn(i).setWidth(width); } } class InnerClientBuinessObject extends ClientBusinessObject{ @Override public String toString(){ BusinessObject bo = super.getBusinessObject(); return bo.name; } } class InnerTreeRootDataNode extends InnerDataNode{ @Override public String toString(){ return super.toString(); } } class InnerDataNode extends DefaultTableNode { private boolean toStringIsCalc = false; private String toStringValue = ""; @Override public String toString(){ if(toStringIsCalc){ return toStringValue; } super.toString(); toStringValue = getTreeNodeDisplayText(this); toStringIsCalc = true; return toStringValue; } } private String getTreeNodeDisplayText(IDataNode sourceData){ String[] expandCols = getTreeTableExpandCols(); Map valueMap = sourceData.getValueMap(); StringBuffer sb = new StringBuffer(); if(expandCols != null && expandCols.length != 0){ for(String field : expandCols){ String fieldValue = ""; if(valueMap.containsKey(field)){ fieldValue = valueMap.get(field); } if(fieldValue != null && !"".equals(fieldValue.trim())){ sb.append(fieldValue + " "); } } } return sb.toString(); } private String[] getTreeTableExpandCols(){ return getDefination().getExpandCols() == null ? new String[0] : getDefination().getExpandCols().split(","); } public JTreeTable getTreeTable() { return treeTable; } public TreeTableDataModel getTreeTableModel() { return treeTableModel; } public Object getRootObj() { return rootObj; } public IDataNode[] getSelectTreeNodeObjects(){ TreePath[] paths = treeTable.getTree().getSelectionPaths(); if(paths == null) return null;//add by caicong 2014/6/3 paths为null时取其length,抛空指针异常。 IDataNode[] res = new IDataNode[paths.length]; for (int i = 0; i < res.length; i++) { Object obj = paths[i].getLastPathComponent(); if(paths[i].getLastPathComponent() instanceof TreeTableModel.TreeTableNode){ TreeTableModel.TreeTableNode treeTableNode = (TreeTableModel.TreeTableNode)obj; obj = treeTableNode.getObj(); if(obj instanceof IDataNode){ IDataNode iDataNode = (IDataNode) obj; res[i] = iDataNode; } } } return res; } /** * 重新加载当前选中对象的子对象数据 */ public void reloadCurrenTreeNodeData(){ try{ if(getSourceData() != null && getSourceData().getMaterObject() != null){ rootNode.setLeaf(false); rootNode.setExpand(false); rootNode.removeAll(); loadTreeTableData(rootNode, getSourceData(), getDefination().getExpandMode(), true); rootNode.setObj(getSourceData()); //为root设定sourcedata by liucq rootNode.setPropertyValueByName(headerColumns[0], getSourceData()); treeTable.updateUI(); } }catch(Exception e){ UIFUtils.showErrorMessage(this, e); } } /** * 刷新界面 ?by zhonggy 2015-07 */ public void refreshUI(){ this.reloadCurrenTreeNodeData(); } }