package com.vci.client.workflow.editor; import java.awt.Color; import java.awt.Point; import java.io.InputStream; import java.io.Serializable; import java.text.NumberFormat; import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import com.mxgraph.io.mxCodec; import com.mxgraph.model.mxCell; import com.mxgraph.model.mxGraphModel; import com.mxgraph.model.mxGraphModel.Filter; import com.mxgraph.model.mxICell; import com.mxgraph.model.mxIGraphModel; import com.mxgraph.swing.mxGraphComponent; import com.mxgraph.view.mxGraph; import com.vci.client.workflow.editor.ui.IProcessProperty; import com.vci.client.workflow.editor.ui.TaskPanel; import com.vci.corba.common.VCIError; public class CustomGraphComponent extends mxGraphComponent { private static final long serialVersionUID = 1141100263201752158L; private static FlowDesigner flowDesigner; public CustomGraphComponent() throws VCIError { this(new CustomGraph()); } public CustomGraphComponent(final mxGraph graph) throws VCIError { super(graph); // Sets switches typically used in an editor // setPageVisible(true); // setGridVisible(true); setToolTips(true); // getConnectionHandler().setCreateTarget(true); getConnectionHandler().setHandleEnabled(false); // getConnectionHandler().setEnabled(false); mxCell cell = (mxCell)getGraph().getModel().getRoot(); cell.setValue(ProcessComponentFactory.getComponent(graph, cell)); // Loads the defalt stylesheet from an external file mxCodec codec = new mxCodec(); // mxCodec codec = new mxCodec(); Document doc = getDocument(); /* org.w3c.dom.Document doc = mxUtils.loadDocument(CustomGraphComponent.class.getResource( "/default-style.xml").toString());*/ codec.decode(doc.getDocumentElement(), graph.getStylesheet()); // Sets the background to white getViewport().setOpaque(true); getViewport().setBackground(Color.WHITE); } private Document getDocument() { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); ClassLoader cl = CustomGraphComponent.class.getClassLoader(); InputStream in = cl.getResourceAsStream("default-style.xml"); return db.parse(in); } catch (Exception e) { e.printStackTrace(); } return null; } /** * Overrides drop behaviour to set the cell style if the target is not a * valid drop target and the cells are of the same type (eg. both * vertices or both edges). */ public Object[] importCells(Object[] cells, double dx, double dy, Object target, Point location) { try{ if (target == null && cells.length == 1 && location != null) { target = getCellAt(location.x, location.y); if (target instanceof mxICell && cells[0] instanceof mxICell) { mxICell targetCell = (mxICell) target; mxICell dropCell = (mxICell) cells[0]; if (targetCell.isVertex() == dropCell.isVertex() || targetCell.isEdge() == dropCell.isEdge()) { mxIGraphModel model = graph.getModel(); model.setStyle(target, model.getStyle(cells[0])); graph.setSelectionCell(target); flowDesigner.getEditor().updatePanel(target); return null; } } } Object[] importCells = super.importCells(cells, dx, dy, target, location); return importCells; }catch(Exception e){ e.printStackTrace(); JOptionPane.showMessageDialog(null, e.getMessage(), "importCells", JOptionPane.ERROR_MESSAGE); return null; } } /** * A graph that creates new edges from a given template edge. */ public static class CustomGraph extends mxGraph implements Serializable { private static final long serialVersionUID = 5968783294124195597L; public static final NumberFormat numberFormat = NumberFormat.getInstance(); /** * Holds the edge to be used as a template for inserting new edges. */ protected Object edgeTemplate; /** * Custom graph that defines the alternate edge style to be used when * the middle control point of edges is double clicked (flipped). */ public CustomGraph() { setAlternateEdgeStyle("edgeStyle=mxEdgeStyle.ElbowConnector;elbow=vertical"); } /** * Sets the edge template to be used to inserting edges. */ public void setEdgeTemplate(Object template) { edgeTemplate = template; } /** * Overrides the method to use the currently selected edge template for * new edges. */ public Object createEdge(Object parent, String id, Object value, Object source, Object target, String style) { if (edgeTemplate != null) { mxCell edge = (mxCell) cloneCells(new Object[] { edgeTemplate })[0]; edge.setId(id); return edge; } return super.createEdge(parent, id, value, source, target, style); } @Override public void cellLabelChanged(Object cell, Object value, boolean autoSize) { model.beginUpdate(); try { mxCell tmpCell = (mxCell) cell; Object cellValue = tmpCell.getValue(); if(cellValue instanceof IProcessProperty){ IProcessProperty flowNode = (IProcessProperty) cellValue; flowNode.setValue(value.toString()); }else{ FlowNode flowNode = new FlowNode("transition_horizontal", value.toString()); tmpCell.setValue(flowNode); tmpCell.setValue(ProcessComponentFactory.getComponent(this, tmpCell)); } if (autoSize) { cellSizeUpdated(cell, false); } } catch (VCIError e) { // TODO Auto-generated catch block e.printStackTrace(); JOptionPane.showMessageDialog(null, e.messages, "cellLabelChanged", JOptionPane.ERROR_MESSAGE); } finally { model.endUpdate(); refresh(); } } public Object[] getCloneableCells(Object[] cells) { return mxGraphModel.filterCells(cells, new Filter() { public boolean filter(Object cell) { Object cellValue = ((mxCell)cell).getValue(); boolean isStart = false; if(cellValue != null && cellValue instanceof FlowNode){ //禁止start被克隆 if(((FlowNode)cellValue).getType().equals("start")){ isStart = true; } } return isCellCloneable(cell) && !isStart; } }); } @Override public Object[] cloneCells(Object[] cells, boolean allowInvalidEdges) { try{ Object[] clones = super.cloneCells(cells, allowInvalidEdges); if(clones != null && clones.length > 0){ for (int i = 0; i < clones.length; i++) { mxCell mxCell = (mxCell)clones[i]; Object value = mxCell.getValue(); if(value instanceof FlowNode){ JComponent component = ProcessComponentFactory.getComponent(this, mxCell); if(component instanceof TaskPanel) { // PhaseObject[] phaseObjects = flowDesigner.getDeployPanel().getPhaseObjects(); // ((TaskPanel)component).setPhaseObjects(phaseObjects); } mxCell.setValue(component); } } } return clones; }catch(Exception e){ e.printStackTrace(); JOptionPane.showMessageDialog(null, e.getMessage(), "cloneCells", JOptionPane.ERROR_MESSAGE); return null; } } } public void setFlowDesigner(final FlowDesigner flowDesigner) { this.flowDesigner = flowDesigner; } }