📄 jgraphgraphfactory.java
字号:
package com.softwarematch.workflow;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.Frame;import java.awt.GridLayout;import java.awt.Toolkit;import java.awt.Window;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.util.Hashtable;import java.util.Map;import java.util.Random;import javax.swing.BorderFactory;import javax.swing.JButton;import javax.swing.JCheckBox;import javax.swing.JDialog;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextField;import javax.swing.border.EmptyBorder;import org.jgraph.JGraph;import org.jgraph.graph.AttributeMap;import org.jgraph.graph.ConnectionSet;import org.jgraph.graph.DefaultEdge;import org.jgraph.graph.DefaultGraphCell;import org.jgraph.graph.DefaultGraphModel;import org.jgraph.graph.Edge;import org.jgraph.graph.GraphConstants;import org.jgraph.graph.GraphModel;import org.jgraph.graph.ParentMap;import org.jgraph.graph.Port;/** * A helper class that creates graphs. Currently supports tree graphs and a * random graph where all edges are connected at least once */public class JGraphGraphFactory { public static final int FULLY_CONNECTED = 0; public static final int RANDOM_CONNECTED = 1; public static final int TREE = 2; public static final int FLOW = 3; /** * Shared <code>Random</code> */ private Random random = new Random(); /** * Number of vertices on current tree level being worked on */ private int numVerticesLevel; /** * Stores first unconnected edge available */ private int edgeIndex; /** * Stores first unconnected cell available in smaple tree, root cell never * is available */ private int vertexIndex; /** * Whether or not insert at performed directly on the model */ private boolean insertIntoModel = false; /** * Number of nodes for use as bean variable */ protected int numNodes = 36; /** * Number of edges for use as bean variable */ protected int numEdges = 36; /** * The maximum number of child nodes any parent in the tree graph can have */ protected int maxNodesPerTreeLevel = 2; protected FactoryConfigDialog dialog; /** * Default constructor */ public JGraphGraphFactory() { } /** * Entry method for inserting a sample graph * * @param graph * the JGraph to perform the insert on * @param graphType * which sample graph type is to be inserted * @param defaultVertexAttributes * the default attributes to use for vertices * @param defaultEdgeAttributes * the default attributes to use for edges */ public void insertGraph(JGraph graph, int graphType, Map defaultVertexAttributes, Map defaultEdgeAttributes) { if (dialog == null) { dialog = new FactoryConfigDialog(); } dialog.configureLayout(graph, graphType, defaultVertexAttributes, defaultEdgeAttributes); dialog.setModal(true); center(dialog); dialog.setVisible(true); } /** * clears the graph and inserts a random tree. The nodes are initially * placed a grid with the root node selected. The algorithm used is not * recursive as the number of nodes per level are not know at the size. A * DFS search would not work, since we don't know where the leaves are. * Cells are inserted over edges for clarity * * @param graph * the JGraph to perform the insert on * @param defaultVertexAttributes * the default attributes to use for vertices * @param defaultEdgeAttributes * the default attributes to use for edges * @return the root node of the tree */ public Object insertTreeSampleData(JGraph graph, Map defaultVertexAttributes, Map defaultEdgeAttributes) { // Create array big enough for all cells Object[] cells = new Object[numNodes * 2]; initialise(graph); numVerticesLevel = 1; edgeIndex = 0; vertexIndex = 1; int gridWidth = (int) Math.sqrt(numNodes); // Ensure arrows are present in edge attributes int arrow = GraphConstants.ARROW_CLASSIC; GraphConstants.setLineEnd(defaultEdgeAttributes, arrow); GraphConstants.setEndFill(defaultEdgeAttributes, true); // the cell occupy the first half of the cells array, i.e. from // 0 to numNodes-1, the edge the second half, from numNodes to // numNode*2-1 for (int i = 0; i < numNodes; i++) { Point2D cellPosition = calcCellPosition(i, gridWidth); DefaultGraphCell cell = createVertex(new Integer(i).toString(), cellPosition, defaultVertexAttributes); cells[i] = cell; } connectNextLevel(graph.getModel(), cells, defaultEdgeAttributes); Object[] cells2 = new Object[numNodes + numNodes - 1]; System.arraycopy(cells, numNodes, cells2, 0, numNodes - 1); System.arraycopy(cells, 0, cells2, numNodes - 1, numNodes); insertIntoGraph(graph, cells2); // Select the root cell graph.setSelectionCell(cells[0]); return cells[0]; } /** * clears the graph and inserts a random tree. The nodes are initially * placed a grid with the root node selected. The algorithm used is not * recursive as the number of nodes per level are not know at the size. A * DFS search would not work, since we don't know where the leaves are. * Cells are inserted over edges for clarity * * @param model * the model to perform the insert on * @param defaultVertexAttributes * the default attributes to use for vertices * @param defaultEdgeAttributes * the default attributes to use for edges * @return the root node of the tree */ public Object insertTreeSampleData(GraphModel model, Map defaultVertexAttributes, Map defaultEdgeAttributes) { // Create array big enough for all cells Object[] cells = new Object[numNodes * 2]; // Clear out the model Object[] roots = DefaultGraphModel.getRoots(model); Object[] descendants = DefaultGraphModel.getDescendants(model, roots).toArray(); model.remove(descendants); numVerticesLevel = 1; edgeIndex = 0; vertexIndex = 1; int gridWidth = (int) Math.sqrt(numNodes); // Ensure arrows are present in edge attributes int arrow = GraphConstants.ARROW_CLASSIC; GraphConstants.setLineEnd(defaultEdgeAttributes, arrow); GraphConstants.setEndFill(defaultEdgeAttributes, true); // the cell occupy the first half of the cells array, i.e. from // 0 to numNodes-1, the edge the second half, from numNodes to // numNode*2-1 for (int i = 0; i < numNodes; i++) { Point2D cellPosition = calcCellPosition(i, gridWidth); DefaultGraphCell cell = createVertex(new Integer(i).toString(), cellPosition, defaultVertexAttributes); cells[i] = cell; } connectNextLevel(model, cells, defaultEdgeAttributes); Object[] cells2 = new Object[numNodes + numNodes - 1]; System.arraycopy(cells, numNodes, cells2, 0, numNodes - 1); System.arraycopy(cells, 0, cells2, numNodes - 1, numNodes); JGraphGraphFactory.insert(model, cells2); return cells[0]; } /** * Takes all cells to be connected between one level and the next creates * * @param cells * @param defaultEdgeAttributes */ protected void connectNextLevel(GraphModel model, Object[] cells, Map defaultEdgeAttributes) { // If we've connected all vertices stop connecting if (vertexIndex < numNodes) { // Store the number of vertices on this level locally as the // variable is going to be reused int localNumVerticesLevel = numVerticesLevel; numVerticesLevel = 0; int localVertexCount = vertexIndex; // For each node in this level connect a random number of vertices for (int i = localVertexCount - localNumVerticesLevel; i < localVertexCount; i++) { connectChildrenVertices(model, cells, cells[i], defaultEdgeAttributes); } // Recurse connectNextLevel(model, cells, defaultEdgeAttributes); } } /** * Connects the next <code>numChildren</code> free vertices as targets * from the specified <code>parent</code> * * @param cells * @param parent * @param defaultEdgeAttributes */ protected void connectChildrenVertices(GraphModel model, Object[] cells, Object parent, Map defaultEdgeAttributes) { // If we've connected all vertices stop connecting if (vertexIndex < numNodes) { // Make a list of child cells first. We don't recurse straight down // to leaves since we don't how deep the tree is. Instead, each // level is connected at a time. Increasing maxNodesPerTreeLevel // makes the tree wider and shallower, decreasing makes it deeper // and narrower int numChildren = random.nextInt(maxNodesPerTreeLevel) + 1; Port parentPort; if (parent instanceof Port) { parentPort = (Port)parent; } else { parentPort = (Port)model.getChild(parent, 0); } for (int i = 0; i < numChildren; i++) { // If we've connected all vertices stop connecting if (vertexIndex < numNodes) { numVerticesLevel++; // Port of child i Port childPort; if (cells[vertexIndex] instanceof Port) { childPort = (Port)cells[vertexIndex++]; } else { childPort = (Port)model.getChild(cells[vertexIndex++], 0); } Edge edge = createEdge(defaultEdgeAttributes, parentPort, childPort); cells[(edgeIndex++) + numNodes] = edge; } } } } /** * clears the graph and inserts a random graph. The nodes are initially * placed a grid with no node selected. If there are at least as many edges * as nodes then all cells have at least one edge connected to them. * * @param graph * the JGraph instance to act upon * @param defaultVertexAttributes * the default attributes to use for vertices * @param defaultEdgeAttributes * the default attributes to use for edges */ public void insertConnectedGraphSampleData(JGraph graph, Map defaultVertexAttributes, Map defaultEdgeAttributes) { // Create array big enough for all cells Object[] cells = new DefaultGraphCell[numNodes + numEdges]; GraphModel model = graph.getModel(); initialise(graph); int gridWidth = (int) Math.sqrt(numNodes); for (int i = 0; i < numNodes; i++) { Point2D cellPosition = calcCellPosition(i, gridWidth); DefaultGraphCell cell = createVertex(new Integer(i).toString(), cellPosition, defaultVertexAttributes); cells[i] = cell; } // Connect every cell in turn to a random other for (int i = 0; i < Math.min(numNodes, numEdges); i++) { // Port of child i Port sourcePort; if (cells[i] instanceof Port) { sourcePort = (Port)cells[i]; } else { sourcePort = (Port)model.getChild(cells[i], 0); } // Select random other cell int node = random.nextInt(numNodes); if (numNodes > 1) { while (node == i) { node = random.nextInt(numNodes); } } Port targetPort; if (cells[node] instanceof Port) { targetPort = (Port)cells[node]; } else { targetPort = (Port)model.getChild(cells[node], 0); } Edge edge = createEdge(defaultEdgeAttributes, sourcePort, targetPort); cells[i + numNodes] = edge; } // Connect remaining edges randomly for (int i = numNodes; i < numEdges; i++) { int sourceNode = random.nextInt(numNodes); Port sourcePort; if (cells[sourceNode] instanceof Port) { sourcePort = (Port)cells[sourceNode]; } else { sourcePort = (Port)model.getChild(cells[sourceNode], 0); } // Select random other cell int targetNode = random.nextInt(numNodes); if (numNodes > 1) { while (targetNode == sourceNode) { targetNode = random.nextInt(numNodes); } } Port targetPort; if (cells[targetNode] instanceof Port) { targetPort = (Port)cells[targetNode]; } else { targetPort = (Port)model.getChild(cells[targetNode], 0); } Edge edge = createEdge(defaultEdgeAttributes, sourcePort, targetPort); cells[i + numNodes] = edge; } Object[] cells2 = new Object[numNodes + numEdges]; System.arraycopy(cells, numNodes, cells2, 0, numEdges); System.arraycopy(cells, 0, cells2, numEdges, numNodes); insertIntoGraph(graph, cells2); } /** * clears the graph and inserts a fully connected graph. The nodes are * initially placed a grid. There are the same number of cells and edges in * the graph, all cells have at least one edge connected to them. * * @param graph * the JGraph instance to act upon * @param defaultVertexAttributes * the default attributes to use for vertices * @param defaultEdgeAttributes * the default attributes to use for edges */ public void insertFullyConnectedGraphSampleData(JGraph graph, Map defaultVertexAttributes, Map defaultEdgeAttributes) { GraphModel model = graph.getModel(); // Calculate the number of edges int numEdges = ((numNodes - 1) * (numNodes)) / 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -