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

📄 defaultgraphmodel.java

📁 用JGraph编的软件
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * @(#)DefaultGraphModel.java	1.0 1/1/02 *  * Copyright (c) 2001-2004, Gaudenz Alder  * All rights reserved.  *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: *  * - Redistributions of source code must retain the above copyright notice, *   this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, *   this list of conditions and the following disclaimer in the documentation  *   and/or other materials provided with the distribution. * - Neither the name of JGraph nor the names of its contributors may be used *   to endorse or promote products derived from this software without specific *   prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */package org.jgraph.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.CannotRedoException;import javax.swing.undo.CannotUndoException;import javax.swing.undo.CompoundEdit;import javax.swing.undo.UndoableEdit;import javax.swing.undo.UndoableEditSupport;import org.jgraph.event.GraphModelEvent;import org.jgraph.event.GraphModelListener;/** * A simple implementation of a graph model. * * @version 1.0 1/1/02 * @author Gaudenz Alder */public class DefaultGraphModel	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 DefaultGraphModel() {	}	//	// 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 parent 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 Map getAttributes(Object node) {		if (node instanceof GraphCell)			return ((GraphCell) node).getAttributes();		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 (node instanceof DefaultGraphCell) {				// Enqueue Children				for (int i = 0; i < getChildCount(node); i++)					q.add(getChild(node, i));				// Re-Establish Parent Relation for Front Client				DefaultGraphCell cell = (DefaultGraphCell) node;				DefaultGraphCell clone = (DefaultGraphCell) cell.clone();				Object par = getParent(cell);				if (par != null) {					DefaultMutableTreeNode p =						(DefaultMutableTreeNode) map.get(par);					if (p != null)						p.add(clone);				}				// Store (cell, clone)-pair				map.put(cell, 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;	}	/**	 * 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[] roots,		Map attributes,		ConnectionSet cs,		ParentMap pm,		UndoableEdit[] edits) {		GraphModelEdit edit =			createInsertEdit(roots, attributes, cs, pm, edits);		if (edit != null) {			edit.execute();			if (edits != null) {				for (int i = 0; i < edits.length; i++)					if (edits[i]						instanceof GraphModelEvent.ExecutableGraphChange)						((GraphModelEvent.ExecutableGraphChange) edits[i])							.execute();			}			postEdit(edit);		}	}	/**	 * Removes <code>cells</code> from the model.	 * Notifies the model- and undo listeners of the change.	 */	public void remove(Object[] roots) {		GraphModelEdit edit = createRemoveEdit(roots);		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 GraphModelEvent.ExecutableGraphChange)				 ((GraphModelEvent.ExecutableGraphChange) edits[0]).execute();			postEdit(edits[0]); // UndoableEdit Relay		} else {			GraphModelEdit edit = createCellEdit(attributes, cs, pm, edits);			//System.out.println("DefaultGraphModel_edit_attributes="+attributes);			if (edit != null) {

⌨️ 快捷键说明

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