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

📄 jawegraphmodel.java

📁 jawe的最新版本,基于Java的图形化工作流编辑器。图形化工作流编辑器 。使用JAVA语言开发
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
package org.enhydra.jawe.components.graph;import java.io.IOException;import java.io.ObjectInputStream;import java.io.Serializable;import java.util.ArrayList;import java.util.HashSet;import java.util.Hashtable;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Set;import java.util.Stack;import javax.swing.event.EventListenerList;import javax.swing.tree.DefaultMutableTreeNode;import javax.swing.tree.MutableTreeNode;import javax.swing.tree.TreeNode;import javax.swing.undo.AbstractUndoableEdit;import javax.swing.undo.CannotRedoException;import javax.swing.undo.CannotUndoException;import javax.swing.undo.CompoundEdit;import javax.swing.undo.UndoableEdit;import javax.swing.undo.UndoableEditSupport;import org.enhydra.jawe.ResourceManager;import org.jgraph.event.GraphModelEvent;import org.jgraph.event.GraphModelListener;import org.jgraph.graph.AttributeMap;import org.jgraph.graph.CellView;import org.jgraph.graph.ConnectionSet;import org.jgraph.graph.DefaultGraphCell;import org.jgraph.graph.DefaultGraphModel;import org.jgraph.graph.Edge;import org.jgraph.graph.GraphCell;import org.jgraph.graph.GraphConstants;import org.jgraph.graph.GraphLayoutCache;import org.jgraph.graph.GraphModel;import org.jgraph.graph.ParentMap;import org.jgraph.graph.Port;/** * A process editor implementation of a graph model. * @author Sasa Bojanic */public class JaWEGraphModel extends UndoableEditSupport implements Serializable, GraphModel {	/** The list of listeners that listen to the model. */	protected transient EventListenerList listenerList = new EventListenerList();	/** Default instance of an empty iterator. */	protected transient Iterator emptyIterator = new EmptyIterator();	/** Set that contains all root cells of this model. */	protected List roots = new ArrayList();	/** Indicates whether isLeaf is based on a node's allowsChildren value. */	protected boolean asksAllowsChildren = false;	/**	 * Constructs a model that is not an attribute store.	 */	public JaWEGraphModel() {	}	//	// Graph Model	//	/**	 * Returns the number of roots in the model.  Returns 0 if the	 * model is empty.	 *	 * @return  the number of roots in the model	 */	public int getRootCount() {		return roots.size();	}	/**	 * Returns the root at index <I>index</I> in the model.	 * This should not return null if <i>index</i> is a valid	 * index for the model (that is <i>index</i> >= 0 &&	 * <i>index</i> < getRootCount()).	 *	 * @return  the root of at index <I>index</I>	 */	public Object getRootAt(int index) {		return roots.get(index);	}	/**	 * Returns the index of <code>root</code> in the model.	 * If root is <code>null</code>, returns -1.	 * @param root a root in the model, obtained from this data source	 * @return the index of the root in the model, or -1	 *    if the parent is <code>null</code>	 */	public int getIndexOfRoot(Object root) {		return roots.indexOf(root);	}	/**	 * Returns <code>true</code> if <code>node</code> or one of its	 * ancestors is in the model.	 *	 * @return <code>true</code> if  <code>node</code> is in the model	 */	public boolean contains(Object node) {		Object parentNode = null;		while ((parentNode = getParent(node)) != null)			node = parentNode;		return roots.contains(node);	}	/**	 * Returns a <code>Map</code> that represents the attributes for	 * the specified cell. This attributes have precedence over each	 * view's attributes, regardless of isAttributeStore.	 *	 * @return attributes of <code>node</code> as a <code>Map</code>	 */	public AttributeMap getAttributes(Object node) {		if (node instanceof GraphCell) return ((GraphCell) node).getAttributes();		return null;	}	/**	 * @return Returns the user object of the given cell. This implementation	 *         checks if the cell is a default mutable tree node and returns	 *         it's user object.	 */	public Object getValue(Object cell) {		if (cell instanceof DefaultMutableTreeNode) return ((DefaultMutableTreeNode) cell).getUserObject();		return null;	}	//	// Graph Structure	//	/**	 * Returns the source of <code>edge</code>. <I>edge</I> must be an object	 * previously obtained from this data source.	 *	 * @return <code>Object</code> that represents the source of <i>edge</i>	 */	public Object getSource(Object edge) {		if (edge instanceof Edge) return ((Edge) edge).getSource();		return null;	}	/**	 * Returns the target of <code>edge</code>. <I>edge</I> must be an object	 * previously obtained from this data source.	 *	 * @return <code>Object</code> that represents the target of <i>edge</i>	 */	public Object getTarget(Object edge) {		if (edge instanceof Edge) return ((Edge) edge).getTarget();		return null;	}	/**	 * Returns <code>true</code> if <code>port</code> is a valid source	 * for <code>edge</code>. <I>edge</I> and <I>port</I> must be	 * objects previously obtained from this data source.	 *	 * @return <code>true</code> if <code>port</code> is a valid source	 *                           for <code>edge</code>.	 */	public boolean acceptsSource(Object edge, Object port) {		return true;	}	/**	 * Returns <code>true</code> if <code>port</code> is a valid target	 * for <code>edge</code>. <I>edge</I> and <I>port</I> must be	 * objects previously obtained from this data source.	 *	 * @return <code>true</code> if <code>port</code> is a valid target	 *                           for <code>edge</code>.	 */	public boolean acceptsTarget(Object edge, Object port) {		return true;	}	/**	 * Returns an iterator of the edges connected to <code>port</code>.	 * <I>port</I> must be a object previously obtained from	 * this data source. This method never returns null.	 *	 * @param   port  a port in the graph, obtained from this data source	 * @return  <code>Iterator</code> that represents the connected edges	 */	public Iterator edges(Object port) {		if (port instanceof Port) return ((Port) port).edges();		return emptyIterator;	}	/**	 * Returns <code>true</code> if <code>edge</code> is a valid edge.	 *	 * @return <code>true</code> if <code>edge</code> is a valid edge.	 */	public boolean isEdge(Object edge) {		return edge instanceof Edge;	}	/**	 * Returns <code>true</code> if <code>port</code> is a valid	 * port, possibly supporting edge connection.	 *	 * @return <code>true</code> if <code>port</code> is a valid port.	 */	public boolean isPort(Object port) {		return port instanceof Port;	}	//	// Group Structure	//	/**	 * Returns a map of (cell, clone)-pairs for all <code>cells</code>	 * and their children. Special care is taken to replace the anchor	 * references between ports. (Iterative implementation.)	 */	public Map cloneCells(Object[] cells) {		Map map = new Hashtable();		// Add Cells to Queue		ArrayList q = new ArrayList();		for (int i = 0; i < cells.length; i++)			q.add(cells[i]);		// Iterate Queue		while (!q.isEmpty()) {			// Remove Front Client From Queue			Object node = q.remove(0);			if (!map.containsKey(node)) {				Object parent = getParent(node);				if (parent != null) parent = map.get(parent);				Object clone = cloneCell(node, parent);				map.put(node, clone);			}		}		// Replace Anchors		Iterator it = map.values().iterator();		while (it.hasNext()) {			Object obj = it.next();			// For All Ports in Result Map do...			if (obj instanceof Port) {				Object anchor = ((Port) obj).getAnchor();				// Map Anchor to Cloned Anchor				if (anchor != null) ((Port) obj).setAnchor((Port) map.get(anchor));			}		}		return map;	}	/**	 * Creates a shallow copy of the cell including a copy of the user object	 * and a reference to the parent (which is a clone of the old parent or	 * null). Subclassers can override the cloneUserObject to provide a custom	 * user object cloning mechanism.	 */	protected Object cloneCell(Object cellObj, Object parent) {		if (cellObj instanceof DefaultMutableTreeNode && (parent == null || parent instanceof DefaultMutableTreeNode)) {			// Clone the cell			DefaultGraphCell cell = (DefaultGraphCell) cellObj;			DefaultGraphCell clone = (DefaultGraphCell) cell.clone();			// Add to parent			if (parent != null) {				DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) parent;				parentNode.add(clone);			}			// Clone the user object			clone.setUserObject(cloneUserObject(cell.getUserObject()));			return clone;		}		return cellObj;	}	/**	 * Clones the user object. Helper method that is invoked from cloneCells.	 * You must use cloneCells (or cloneCell for single cells) to get a deep	 * copy of a clone. Subclassers must override this and valueForCellChanged	 * to implement custom user objects. This implementation returns	 * <code>object</code>.	 */	protected Object cloneUserObject(Object userObject) {		if (userObject instanceof org.enhydra.shark.xpdl.XMLComplexElement)			return ((org.enhydra.shark.xpdl.XMLComplexElement) userObject).clone();		return userObject;	}	/**	 * Returns the parent of <I>child</I> in the model.	 * <I>child</I> must be a node previously obtained from	 * this data source. This returns null if <i>child</i> is	 * a root in the model.	 *	 * @param   child  a node in the graph, obtained from this data source	 * @return  the parent of <I>child</I>	 */	public Object getParent(Object child) {		if (child != null && child instanceof TreeNode) return ((TreeNode) child).getParent();		return null;	}	/**	 * Returns the index of child in parent.	 * If either the parent or child is <code>null</code>, returns -1.	 * @param parent a note in the tree, obtained from this data source	 * @param child the node we are interested in	 * @return the index of the child in the parent, or -1	 *    if either the parent or the child is <code>null</code>	 */	public int getIndexOfChild(Object parent, Object child) {		if (parent == null || child == null) return -1;		return ((TreeNode) parent).getIndex((TreeNode) child);	}	/**	 * Returns the child of <I>parent</I> at index <I>index</I> in the parent's	 * child array.  <I>parent</I> must be a node previously obtained from	 * this data source. This should not return null if <i>index</i>	 * is a valid index for <i>parent</i> (that is <i>index</i> >= 0 &&	 * <i>index</i> < getChildCount(<i>parent</i>)).	 *	 * @param   parent  a node in the tree, obtained from this data source	 * @return  the child of <I>parent</I> at index <I>index</I>	 */	public Object getChild(Object parent, int index) {		if (parent instanceof TreeNode) return ((TreeNode) parent).getChildAt(index);		return null;	}	/**	 * Returns the number of children of <I>parent</I>.  Returns 0 if the node	 * is a leaf or if it has no children.  <I>parent</I> must be a node	 * previously obtained from this data source.	 *	 * @param   parent  a node in the tree, obtained from this data source	 * @return  the number of children of the node <I>parent</I>	 */	public int getChildCount(Object parent) {		if (parent instanceof TreeNode) return ((TreeNode) parent).getChildCount();		return 0;	}	/**	 * Returns whether the specified node is a leaf node.	 * The way the test is performed depends on the.	 *	 * @param node the node to check	 * @return true if the node is a leaf node	 */	public boolean isLeaf(Object node) {		if (asksAllowsChildren && node instanceof TreeNode) return !((TreeNode) node).getAllowsChildren();		return ((TreeNode) node).isLeaf();	}	//	// Change Support	//	/**	 * Inserts the <code>roots</code> and connections into the model.	 * Notifies the model- and undo listeners of the change. The passed-in	 * edits are executed if they implement the	 * <code>GraphModelEvent.ExecutableGraphChange</code> interface	 * in ascending array-order, after execution of the model change.	 * (Note: The external order is important in a	 * special case: After insertion on a partial view, ie. one that does not	 * display all cells of the model, the cell is made visible after	 * it is inserted into the model. This requires the inserting view	 * to be able to add the cell to the visible set before it is	 * inserted into the model.)	 * Note: The passed-in propertyMap may contains PortViews	 * which must be turned into Points when stored in the model.	 */	public void insert(Object[] pRoots, Map pAttributes, ConnectionSet pCs, ParentMap pPm, UndoableEdit[] pEdits) {		String undoMsg = ResourceManager.getLanguageDependentString("MessageInsertingObjects");		GraphModelEdit edit = createInsertEdit(pRoots, pAttributes, pCs, pPm, pEdits, undoMsg);		if (edit != null) {			edit.execute();			if (pEdits != null) {				for (int i = 0; i < pEdits.length; i++)					if (pEdits[i] instanceof GraphLayoutCache.GraphLayoutCacheEdit)						((GraphLayoutCache.GraphLayoutCacheEdit) pEdits[i]).execute();			}			postEdit(edit);		}	}	/**	 * Removes <code>cells</code> from the model.	 * Notifies the model- and undo listeners of the change.	 */	public void remove(Object[] pRoots) {		String undoMsg = ResourceManager.getLanguageDependentString("MessageRemovingObjects");		GraphModelEdit edit = createRemoveEdit(pRoots, undoMsg);		if (edit != null) {			edit.execute();			postEdit(edit);		}	}	/**	 * Applies <code>attributes</code> and the connection changes to	 * the model. The initial <code>edits</code> that triggered the call	 * are considered to be part of this transaction.  The passed-in	 * edits are executed if they implement the	 * <code>GraphModelEvent.ExecutableGraphChange</code> interface	 * in ascending array-order, after execution of the model change.	 * Notifies the model- and undo listeners of the change.	 * <strong>Note:</strong> If only <code>edits</code> is non-null, the	 * edits are directly passed to the UndoableEditListeners.	 * Note: The passed-in propertyMap may contains PortViews	 * which must be turned into Points when stored in the model.	 */	public void edit(Map attributes, ConnectionSet cs, ParentMap pm, UndoableEdit[] edits) {		if ((attributes == null || attributes.isEmpty()) && (cs == null || cs.isEmpty()) && pm == null && edits != null				&& edits.length == 1) {			if (edits[0] instanceof GraphLayoutCache.GraphLayoutCacheEdit)				((GraphLayoutCache.GraphLayoutCacheEdit) edits[0]).execute();			postEdit(edits[0]); // UndoableEdit Relay		} else {			String undoMsg = ResourceManager.getLanguageDependentString("MessageEditingObject");			GraphModelEdit edit = createCellEdit(attributes, cs, pm, edits, undoMsg);			//System.out.println("DefaultGraphModel_edit_attributes="+attributes);			if (edit != null) {				edit.execute();				if (edits != null) {					for (int i = 0; i < edits.length; i++)						if (edits[i] instanceof GraphLayoutCache.GraphLayoutCacheEdit)							((GraphLayoutCache.GraphLayoutCacheEdit) edits[i]).execute();				}				postEdit(edit);			}		}	}	/**	 * Used for editing font sizes without haveing an undo action set.	 */	public void editFonts(Map attributes) {		GraphModelEdit edit = createCellEdit(attributes, null, null, null, null);		//System.out.println("DefaultGraphModel_edit_attributes="+attributes);		if (edit != null) {			edit.execute();		}	}	/**	 * Used for editing font sizes without haveing an undo action set.	 */	public void removeBubbles(Object[] bubbles, GraphModelListener gml) {		removeGraphModelListener(gml);		GraphModelEdit edit = createRemoveEdit(bubbles, null);		if (edit != null) {			edit.execute();		}		addGraphModelListener(gml);	}	/**

⌨️ 快捷键说明

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