⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mxgraphmodel.java

📁 经典的java图像处理程序源码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/** * $Id: mxGraphModel.java,v 1.69 2009/04/06 14:49:24 gaudenz Exp $ * Copyright (c) 2007, Gaudenz Alder */package com.mxgraph.model;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.HashSet;import java.util.Hashtable;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import com.mxgraph.util.mxEvent;import com.mxgraph.util.mxEventObject;import com.mxgraph.util.mxEventSource;import com.mxgraph.util.mxPoint;import com.mxgraph.util.mxUndoableEdit;/** * Extends mxEventSource to implement a graph model. The graph model acts as * a wrapper around the cells which are in charge of storing the actual graph * datastructure. The model acts as a transactional wrapper with event * notification for all changes, whereas the cells contain the atomic * operations for updating the actual datastructure. *  * Layers: *  * The cell hierarchy in the model must have a top-level root cell which * contains the layers (typically one default layer), which in turn contain the * top-level cells of the layers. This means each cell is contained in a layer. * If no layers are required, then all new cells should be added to the default * layer. *  * Layers are useful for hiding and showing groups of cells, or for placing * groups of cells on top of other cells in the display. To identify a layer, * the <isLayer> function is used. It returns true if the parent of the given * cell is the root of the model. *  * See mxIGraphModel for a list of standard events. */public class mxGraphModel extends mxEventSource implements mxIGraphModel{	/**	 * Holds the root cell, which in turn contains the cells that represent the	 * layers of the diagram as child cells. That is, the actual element of the	 * diagram are supposed to live in the third generation of cells and below.	 */	protected mxICell root;	/**	 * Maps from Ids to cells.	 */	protected Hashtable cells;	/**	 * Specifies if edges should automatically be moved into the nearest common	 * ancestor of their terminals. Default is true.	 */	protected boolean maintainEdgeParent = true;	/**	 * Specifies if the model should automatically create Ids for new cells.	 * Default is true.	 */	protected boolean createIds = true;	/**	 * Specifies the next Id to be created. Initial value is 0.	 */	protected int nextId = 0;	/**	 * Holds the changes for the current transaction. If the transaction is	 * closed then a new object is created for this variable using	 * createUndoableEdit.	 */	protected transient mxUndoableEdit currentEdit;	/**	 * Counter for the depth of nested transactions. Each call to beginUpdate	 * increments this counter and each call to endUpdate decrements it. When	 * the counter reaches 0, the transaction is closed and the respective	 * events are fired. Initial value is 0.	 */	protected transient int updateLevel = 0;	/**	 * 	 */	protected transient boolean endingUpdate = false;	/**	 * Constructs a new empty graph model.	 */	public mxGraphModel()	{		this(null);	}	/**	 * Constructs a new graph model. If no root is specified	 * then a new root mxCell with a default layer is created.	 * 	 * @param root Cell that represents the root cell.	 */	public mxGraphModel(Object root)	{		currentEdit = createUndoableEdit();		if (root == null)		{			root = createRoot();		}		setRoot(root);	}	/**	 * 	 */	public int getUpdateLevel()	{		return updateLevel;	}	/**	 * Creates a new root cell with a default layer (child 0).	 */	public Object createRoot()	{		mxCell root = new mxCell();		root.insert(new mxCell());		return root;	}	/**	 * Returns the internal lookup table that is used to map from Ids to cells.	 */	public Hashtable getCells()	{		return cells;	}	/**	 * Returns the cell for the specified Id or null if no cell can be	 * found for the given Id.	 * 	 * @param id A string representing the Id of the cell.	 * @return Returns the cell for the given Id.	 */	public Object getCell(String id)	{		Object result = null;		if (cells != null)		{			result = cells.get(id);		}		return result;	}	/**	 * Returns true if the model automatically update parents of edges so that	 * the edge is contained in the nearest-common-ancestor of its terminals.	 * 	 * @return Returns true if the model maintains edge parents.	 */	public boolean isMaintainEdgeParent()	{		return maintainEdgeParent;	}	/**	 * Specifies if the model automatically updates parents of edges so that	 * the edge is contained in the nearest-common-ancestor of its terminals.	 * 	 * @param maintainEdgeParent Boolean indicating if the model should	 * maintain edge parents.	 */	public void setMaintainEdgeParent(boolean maintainEdgeParent)	{		this.maintainEdgeParent = maintainEdgeParent;	}	/**	 * Returns true if the model automatically creates Ids and resolves Id	 * collisions.	 * 	 * @return Returns true if the model creates Ids.	 */	public boolean isCreateIds()	{		return createIds;	}	/**	 * Specifies if the model automatically creates Ids for new cells and	 * resolves Id collisions.	 * 	 * @param value Boolean indicating if the model should created Ids.	 */	public void setCreateIds(boolean value)	{		createIds = value;	}	/* (non-Javadoc)	 * @see com.mxgraph.model.mxIGraphModel#getRoot()	 */	public Object getRoot()	{		return root;	}	/* (non-Javadoc)	 * @see com.mxgraph.model.mxIGraphModel#setRoot(Object)	 */	public Object setRoot(Object root)	{		execute(new mxRootChange(this, root));		return root;	}	/**	 * Inner callback to change the root of the model and update the internal	 * datastructures, such as cells and nextId. Returns the previous root.	 */	protected Object rootChanged(Object root)	{		Object oldRoot = this.root;		this.root = (mxICell) root;		// Resets counters and datastructures		nextId = 0;		cells = null;		cellAdded(root);		return oldRoot;	}	/**	 * Creates a new undoable edit.	 */	protected mxUndoableEdit createUndoableEdit()	{		return new mxUndoableEdit(this)		{			public void dispatch()			{				((mxGraphModel) source).fireEvent(mxEvent.CHANGE,						new mxEventObject(new Object[] { changes }));			}		};	}	/* (non-Javadoc)	 * @see com.mxgraph.model.mxIGraphModel#cloneCells(Object[], boolean)	 */	public Object[] cloneCells(Object[] cells, boolean includeChildren)	{		Map mapping = new Hashtable();		Object[] clones = new Object[cells.length];		for (int i = 0; i < cells.length; i++)		{			try			{				clones[i] = cloneCell(cells[i], mapping, includeChildren);			}			catch (CloneNotSupportedException e)			{				// ignore			}		}		for (int i = 0; i < cells.length; i++)		{			restoreClone(clones[i], cells[i], mapping);		}		return clones;	}	/**	 * Inner helper method for cloning cells recursively.	 */	protected Object cloneCell(Object cell, Map mapping, boolean includeChildren)			throws CloneNotSupportedException	{		if (cell instanceof mxICell)		{			mxICell mxc = (mxICell) ((mxICell) cell).clone();			mapping.put(cell, mxc);			if (includeChildren)			{				int childCount = getChildCount(cell);				for (int i = 0; i < childCount; i++)				{					Object clone = cloneCell(getChildAt(cell, i), mapping, true);					mxc.insert((mxICell) clone);				}			}			return mxc;		}		return null;	}	/**	 * Inner helper method for restoring the connections in	 * a network of cloned cells.	 */	protected void restoreClone(Object clone, Object cell, Map mapping)	{		if (clone instanceof mxICell)		{			mxICell mxc = (mxICell) clone;			Object source = getTerminal(cell, true);			if (source instanceof mxICell)			{				mxICell tmp = (mxICell) mapping.get(source);				if (tmp != null)				{					tmp.insertEdge(mxc, true);				}			}			Object target = getTerminal(cell, false);			if (target instanceof mxICell)			{				mxICell tmp = (mxICell) mapping.get(target);				if (tmp != null)				{					tmp.insertEdge(mxc, false);				}			}		}		int childCount = getChildCount(clone);		for (int i = 0; i < childCount; i++)		{			restoreClone(getChildAt(clone, i), getChildAt(cell, i), mapping);		}	}	/* (non-Javadoc)	 * @see com.mxgraph.model.mxIGraphModel#isAncestor(Object, Object)	 */	public boolean isAncestor(Object parent, Object child)	{		while (child != null && child != parent)		{			child = getParent(child);		}		return child == parent;	}	/* (non-Javadoc)	 * @see com.mxgraph.model.mxIGraphModel#contains(Object)	 */	public boolean contains(Object cell)	{		return isAncestor(getRoot(), cell);	}	/* (non-Javadoc)	 * @see com.mxgraph.model.mxIGraphModel#getParent(Object)	 */	public Object getParent(Object child)	{		return (child instanceof mxICell) ? ((mxICell) child).getParent()				: null;	}	/* (non-Javadoc)	 * @see com.mxgraph.model.mxIGraphModel#add(Object, Object, int)	 */	public Object add(Object parent, Object child, int index)	{		if (child != parent && parent != null && child != null)		{			boolean parentChanged = parent != getParent(child);			execute(new mxChildChange(this, parent, child, index));			// Maintains the edges parents by moving the edges			// into the nearest common ancestor of its			// terminals			if (maintainEdgeParent && parentChanged)			{				updateEdgeParents(child);			}		}		return child;	}	/**	 * Invoked after a cell has been added to a parent. This recursively	 * creates an Id for the new cell and/or resolves Id collisions.	 * 	 * @param cell Cell that has been added.	 */	protected void cellAdded(Object cell)	{		if (cell instanceof mxICell)		{			mxICell mxc = (mxICell) cell;			if (mxc.getId() == null && isCreateIds())			{				mxc.setId(createId(cell));			}			if (mxc.getId() != null)			{				Object collision = getCell(mxc.getId());				if (collision != cell)				{					while (collision != null)					{						mxc.setId(createId(cell));						collision = getCell(mxc.getId());					}					if (cells == null)					{						cells = new Hashtable();					}					cells.put(mxc.getId(), cell);				}			}			// Makes sure IDs of deleted cells are not reused			try			{				int id = Integer.parseInt(mxc.getId());				nextId = Math.max(nextId, id + 1);			}			catch (NumberFormatException e)			{				// ignore			}			int childCount = mxc.getChildCount();			for (int i = 0; i < childCount; i++)			{				cellAdded(mxc.getChildAt(i));			}		}	}	/**	 * Creates a new Id for the given cell and increments the global counter	 * for creating new Ids.	 * 	 * @param cell Cell for which a new Id should be created.	 * @return Returns a new Id for the given cell.	 */	public String createId(Object cell)	{		String id = String.valueOf(nextId);		nextId++;		return id;	}	/* (non-Javadoc)	 * @see com.mxgraph.model.mxIGraphModel#remove(Object)	 */	public Object remove(Object cell)	{		if (cell == root)		{			setRoot(null);		}		else if (getParent(cell) != null)		{			execute(new mxChildChange(this, null, cell));		}		return cell;	}	/**	 * Invoked after a cell has been removed from the model. This recursively	 * removes the cell from its terminals and removes the mapping from the Id	 * to the cell.	 * 	 * @param cell Cell that has been removed.	 */	protected void cellRemoved(Object cell)	{		if (cell instanceof mxICell)		{			mxICell mxc = (mxICell) cell;			int childCount = mxc.getChildCount();			for (int i = 0; i < childCount; i++)			{				cellRemoved(mxc.getChildAt(i));			}			if (cells != null && mxc.getId() != null)			{				cells.remove(mxc.getId());			}		}	}	/**	 * Inner callback to update the parent of a cell using mxCell.insert	 * on the parent and return the previous parent.	 */	protected Object parentForCellChanged(Object cell, Object parent, int index)	{		mxICell child = (mxICell) cell;		mxICell previous = (mxICell) getParent(cell);		if (parent != null)		{			if (parent != previous || previous.getIndex(child) != index)			{				((mxICell) parent).insert(child, index);			}		}		else if (previous != null)		{			int oldIndex = previous.getIndex(child);			previous.remove(oldIndex);		}		// Checks if the previous parent was already in the		// model and avoids calling cellAdded if it was.		if (!contains(previous) && parent != null)		{			cellAdded(cell);		}		else if (parent == null)		{			cellRemoved(cell);		}		return previous;	}	/* (non-Javadoc)	 * @see com.mxgraph.model.mxIGraphModel#getChildCount(Object)	 */	public int getChildCount(Object cell)	{		return (cell instanceof mxICell) ? ((mxICell) cell).getChildCount() : 0;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -