📄 mxgraphmodel.java
字号:
/* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#getChildAt(Object, int) */ public Object getChildAt(Object parent, int index) { return (parent instanceof mxICell) ? ((mxICell) parent) .getChildAt(index) : null; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#getTerminal(Object, boolean) */ public Object getTerminal(Object edge, boolean isSource) { return (edge instanceof mxICell) ? ((mxICell) edge) .getTerminal(isSource) : null; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#setTerminal(Object, Object, boolean) */ public Object setTerminal(Object edge, Object terminal, boolean isSource) { boolean terminalChanged = terminal != getTerminal(edge, isSource); execute(new mxTerminalChange(this, edge, terminal, isSource)); if (maintainEdgeParent && terminalChanged) { updateEdgeParent(edge); } return terminal; } /** * Inner helper function to update the terminal of the edge using * mxCell.insertEdge and return the previous terminal. */ protected Object terminalForCellChanged(Object edge, Object terminal, boolean isSource) { mxICell previous = (mxICell) getTerminal(edge, isSource); if (terminal != null) { ((mxICell) terminal).insertEdge((mxICell) edge, isSource); } else if (previous != null) { previous.removeEdge((mxICell) edge, isSource); } return previous; } /** * Updates the parents of the edges connected to the given cell and all its * descendants so that each edge is contained in the nearest common * ancestor. * * @param cell Cell whose edges should be checked and updated. */ public void updateEdgeParents(Object cell) { updateEdgeParents(cell, getRoot()); } /** * Updates the parents of the edges connected to the given cell and all its * descendants so that the edge is contained in the nearest-common-ancestor. * * @param cell Cell whose edges should be checked and updated. * @param root Root of the cell hierarchy that contains all cells. */ public void updateEdgeParents(Object cell, Object root) { // Updates edges on children first int childCount = getChildCount(cell); for (int i = 0; i < childCount; i++) { Object child = getChildAt(cell, i); updateEdgeParents(child, root); } // Updates the parents of all connected edges int edgeCount = getEdgeCount(cell); List edges = new ArrayList(edgeCount); for (int i = 0; i < edgeCount; i++) { edges.add(getEdgeAt(cell, i)); } Iterator it = edges.iterator(); while (it.hasNext()) { Object edge = it.next(); // Updates edge parent if edge and child have // a common root node (does not need to be the // model root node) if (isAncestor(root, edge)) { updateEdgeParent(edge); } } // Updates the parent of the edge itself (if it's an edge) if (isEdge(cell)) { updateEdgeParent(cell); } } /** * Inner helper method to update the parent of the specified edge to the * nearest-common-ancestor of its two terminals. * * @param edge Specifies the edge to be updated. */ public void updateEdgeParent(Object edge) { Object source = getTerminal(edge, true); Object target = getTerminal(edge, false); Object cell = null; if (source == target) { cell = getParent(source); } else { cell = getNearestCommonAncestor(source, target); } if (cell != null && getParent(cell) != root && getParent(edge) != cell) { mxGeometry geo = getGeometry(edge); if (geo != null) { mxPoint origin1 = getOrigin(getParent(edge)); mxPoint origin2 = getOrigin(cell); double dx = origin2.getX() - origin1.getX(); double dy = origin2.getY() - origin1.getY(); geo = geo.translate(-dx, -dy); setGeometry(edge, geo); } add(cell, edge, getChildCount(cell)); } } /** * Returns the absolute, cummulated origin for the children inside the * given parent. */ public mxPoint getOrigin(Object cell) { mxPoint result = null; if (cell != null) { result = getOrigin(getParent(cell)); if (!isEdge(cell)) { mxGeometry geo = getGeometry(cell); if (geo != null) { result.setX(result.getX() + geo.getX()); result.setY(result.getY() + geo.getY()); } } } else { result = new mxPoint(); } return result; } /** * Returns the nearest common ancestor for the specified cells. * * @param cell1 Cell that specifies the first cell in the tree. * @param cell2 Cell that specifies the second cell in the tree. * @return Returns the nearest common ancestor of the given cells. */ public Object getNearestCommonAncestor(Object cell1, Object cell2) { Object result = null; if (cell1 != null && cell2 != null) { // Creates the cell path for the second cell String path = mxCellPath.create((mxICell) cell2); if (path != null && path.length() > 0) { // Bubbles through the ancestors of the first // cell to find the nearest common ancestor. Object cell = cell1; String current = mxCellPath.create((mxICell) cell); while (cell != null && result == null) { Object parent = getParent(cell); // Checks if the cell path is equal to the beginning // of the given cell path if (path.indexOf(current + mxCellPath.PATH_SEPARATOR) == 0 && parent != null) { result = cell; } current = mxCellPath.getParentPath(current); cell = parent; } } } return result; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#getEdgeCount(Object) */ public int getEdgeCount(Object cell) { return (cell instanceof mxICell) ? ((mxICell) cell).getEdgeCount() : 0; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#getEdgeAt(Object, int) */ public Object getEdgeAt(Object parent, int index) { return (parent instanceof mxICell) ? ((mxICell) parent) .getEdgeAt(index) : null; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#isVertex(Object) */ public boolean isVertex(Object cell) { return (cell instanceof mxICell) ? ((mxICell) cell).isVertex() : false; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#isEdge(Object) */ public boolean isEdge(Object cell) { return (cell instanceof mxICell) ? ((mxICell) cell).isEdge() : false; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#isConnectable(Object) */ public boolean isConnectable(Object cell) { return (cell instanceof mxICell) ? ((mxICell) cell).isConnectable() : true; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#getValue(Object) */ public Object getValue(Object cell) { return (cell instanceof mxICell) ? ((mxICell) cell).getValue() : null; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#setValue(Object, Object) */ public Object setValue(Object cell, Object value) { execute(new mxValueChange(this, cell, value)); return value; } /** * Inner callback to update the user object of the given mxCell * using mxCell.setValue and return the previous value, * that is, the return value of mxCell.getValue. */ protected Object valueForCellChanged(Object cell, Object value) { Object oldValue = ((mxICell) cell).getValue(); ((mxICell) cell).setValue(value); return oldValue; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#getGeometry(Object) */ public mxGeometry getGeometry(Object cell) { return (cell instanceof mxICell) ? ((mxICell) cell).getGeometry() : null; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#setGeometry(Object, mxGeometry) */ public mxGeometry setGeometry(Object cell, mxGeometry geometry) { if (geometry != getGeometry(cell)) { execute(new mxGeometryChange(this, cell, geometry)); } return geometry; } /** * Inner callback to update the mxGeometry of the given mxCell using * mxCell.setGeometry and return the previous mxGeometry. */ protected mxGeometry geometryForCellChanged(Object cell, mxGeometry geometry) { mxGeometry previous = getGeometry(cell); ((mxICell) cell).setGeometry(geometry); return previous; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#getStyle(Object) */ public String getStyle(Object cell) { return (cell instanceof mxICell) ? ((mxICell) cell).getStyle() : null; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#setStyle(Object, String) */ public String setStyle(Object cell, String style) { if (style != getStyle(cell)) { execute(new mxStyleChange(this, cell, style)); } return style; } /** * Inner callback to update the style of the given mxCell * using mxCell.setStyle and return the previous style. */ protected String styleForCellChanged(Object cell, String style) { String previous = getStyle(cell); ((mxICell) cell).setStyle(style); return previous; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#isCollapsed(Object) */ public boolean isCollapsed(Object cell) { return (cell instanceof mxICell) ? ((mxICell) cell).isCollapsed() : false; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#setCollapsed(Object, boolean) */ public boolean setCollapsed(Object cell, boolean collapsed) { if (collapsed != isCollapsed(cell)) { execute(new mxCollapseChange(this, cell, collapsed)); } return collapsed; } /** * Inner callback to update the collapsed state of the * given mxCell using mxCell.setCollapsed and return * the previous collapsed state. */ protected boolean collapsedStateForCellChanged(Object cell, boolean collapsed) { boolean previous = isCollapsed(cell); ((mxICell) cell).setCollapsed(collapsed); return previous; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#isVisible(Object) */ public boolean isVisible(Object cell) { return (cell instanceof mxICell) ? ((mxICell) cell).isVisible() : false; } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#setVisible(Object, boolean) */ public boolean setVisible(Object cell, boolean visible) { if (visible != isVisible(cell)) { execute(new mxVisibleChange(this, cell, visible)); } return visible; } /** * Sets the visible state of the given mxCell using mxVisibleChange and * adds the change to the current transaction. */ protected boolean visibleStateForCellChanged(Object cell, boolean visible) { boolean previous = isVisible(cell); ((mxICell) cell).setVisible(visible); return previous; } /** * Executes the given atomic change and adds it to the current edit. * * @param change Atomic change to be executed. */ public void execute(mxAtomicGraphModelChange change) { fireEvent(mxEvent.BEFORE_EXECUTE, new mxEventObject( new Object[] { change })); change.execute(); fireEvent(mxEvent.EXECUTE, new mxEventObject(new Object[] { change })); beginUpdate(); currentEdit.add(change); endUpdate(); fireEvent(mxEvent.AFTER_EXECUTE, new mxEventObject( new Object[] { change })); } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#beginUpdate() */ public void beginUpdate() { updateLevel++; fireEvent(mxEvent.BEGIN_UPDATE); } /* (non-Javadoc) * @see com.mxgraph.model.mxIGraphModel#endUpdate() */ public void endUpdate() { updateLevel--; if (!endingUpdate) { endingUpdate = updateLevel == 0; fireEvent(mxEvent.END_UPDATE, new mxEventObject( new Object[] { currentEdit })); try { if (endingUpdate && !currentEdit.isEmpty()) { fireEvent(mxEvent.BEFORE_UNDO, new mxEventObject( new Object[] { currentEdit })); mxUndoableEdit tmp = currentEdit; currentEdit = createUndoableEdit(); tmp.dispatch(); fireEvent(mxEvent.UNDO, new mxEventObject( new Object[] { tmp })); } } finally { endingUpdate = false; } } } /** * Merges the children of the given cell into the given target cell inside * this model. All cells are cloned unless there is a corresponding cell in * the model with the same id, in which case the source cell is ignored and * all edges are connected to the corresponding cell in this model. Edges * are considered to have no identity and are always cloned unless the * cloneAllEdges flag is set to false, in which case edges with the same * id in the target model are reconnected to reflect the terminals of the * source edges. * * @param from * @param to * @param cloneAllEdges */ public void mergeChildren(mxICell from, mxICell to, boolean cloneAllEdges) throws CloneNotSupportedException { beginUpdate(); try { Hashtable mapping = new Hashtable(); mergeChildrenImpl(from, to, cloneAllEdges, mapping); // Post-processes all edges in the mapping and // reconnects the terminals to the corresponding // cells in the target model Iterator it = mapping.keySet().iterator(); while (it.hasNext()) { Object edge = it.next(); Object cell = mapping.get(edge); Object terminal = getTerminal(edge, true); if (terminal != null) { terminal = mapping.get(terminal); setTerminal(cell, terminal, true); } terminal = getTerminal(edge, false); if (terminal != null) { terminal = mapping.get(terminal); setTerminal(cell, terminal, false); } } } finally { endUpdate(); } } /** * Clones the children of the source cell into the given target cell in * this model and adds an entry to the mapping that maps from the source * cell to the target cell with the same id or the clone of the source cell * that was inserted into this model. */ protected void mergeChildrenImpl(mxICell from, mxICell to, boolean cloneAllEdges, Hashtable mapping) throws CloneNotSupportedException { beginUpdate(); try { int childCount = from.getChildCount();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -