jgraphmodeladapter.java
来自「JAVA图论的算法包。用过觉得还不错」· Java 代码 · 共 1,149 行 · 第 1/3 页
JAVA
1,149 行
*
* @return the JGraph edge cell that corresponds to the specified JGraphT
* edge, or <code>null</code> if no corresponding cell found.
*/
public DefaultEdge getEdgeCell(E jGraphTEdge)
{
return (DefaultEdge) edgeToCell.get(jGraphTEdge);
}
/**
* Returns the JGraph vertex cell that corresponds to the specified JGraphT
* vertex. If no corresponding cell found, returns <code>null</code>.
*
* @param jGraphTVertex a JGraphT vertex of the JGraphT graph.
*
* @return the JGraph vertex cell that corresponds to the specified JGraphT
* vertex, or <code>null</code> if no corresponding cell found.
*/
public DefaultGraphCell getVertexCell(Object jGraphTVertex)
{
return (DefaultGraphCell) vertexToCell.get(jGraphTVertex);
}
/**
* Returns the JGraph port cell that corresponds to the specified JGraphT
* vertex. If no corresponding port found, returns <code>null</code>.
*
* @param jGraphTVertex a JGraphT vertex of the JGraphT graph.
*
* @return the JGraph port cell that corresponds to the specified JGraphT
* vertex, or <code>null</code> if no corresponding cell found.
*/
public DefaultPort getVertexPort(Object jGraphTVertex)
{
DefaultGraphCell vertexCell = getVertexCell(jGraphTVertex);
if (vertexCell == null) {
return null;
} else {
return (DefaultPort) vertexCell.getChildAt(0);
}
}
/**
* Adds/removes an edge to/from the underlying JGraphT graph according to
* the change in the specified JGraph edge. If both vertices are connected,
* we ensure to have a corresponding JGraphT edge. Otherwise, we ensure NOT
* to have a corresponding JGraphT edge.
*
* <p>This method is to be called only for edges that have already been
* changed in the JGraph graph.</p>
*
* @param jEdge the JGraph edge that has changed.
*/
void handleJGraphChangedEdge(org.jgraph.graph.Edge jEdge)
{
if (isDangling(jEdge)) {
if (cellToEdge.containsKey(jEdge)) {
// a non-dangling edge became dangling -- remove the JGraphT
// edge by faking as if the edge is removed from the JGraph.
// TODO: Consider keeping the JGraphT edges outside the graph
// to avoid loosing user data, such as weights.
handleJGraphRemovedEdge(jEdge);
} else {
// a dangling edge is still dangling -- just ignore.
}
} else {
// edge is not dangling
if (cellToEdge.containsKey(jEdge)) {
// edge already has a corresponding JGraphT edge.
// check if any change to its endpoints.
E jtEdge = cellToEdge.get(jEdge);
Object jSource = getSourceVertex(this, jEdge);
Object jTarget = getTargetVertex(this, jEdge);
Object jtSource = cellToVertex.get(jSource);
Object jtTarget = cellToVertex.get(jTarget);
if ((jtGraph.getEdgeSource(jtEdge) == jtSource)
&& (jtGraph.getEdgeTarget(jtEdge) == jtTarget))
{
// no change in edge's endpoints -- nothing to do.
} else {
// edge's end-points have changed -- need to refresh the
// JGraphT edge. Refresh by faking as if the edge has been
// removed from JGraph and then added again.
// ALSO HERE: consider an alternative that maintains user
// data
handleJGraphRemovedEdge(jEdge);
handleJGraphInsertedEdge(jEdge);
}
} else {
// a new edge
handleJGraphInsertedEdge(jEdge);
}
}
}
/**
* Adds to the underlying JGraphT graph an edge that corresponds to the
* specified JGraph edge. If the specified JGraph edge is a dangling edge,
* it is NOT added to the underlying JGraphT graph.
*
* <p>This method is to be called only for edges that have already been
* added to the JGraph graph.</p>
*
* @param jEdge the JGraph edge that has been added.
*/
void handleJGraphInsertedEdge(org.jgraph.graph.Edge jEdge)
{
if (isDangling(jEdge)) {
// JGraphT forbid dangling edges so we cannot add the edge yet. If
// later the edge becomes connected, we will add it.
} else {
// FIXME hb 28-nov-05: waiting for jgraph to go generic
Object jSource = getSourceVertex(this, jEdge);
Object jTarget = getTargetVertex(this, jEdge);
V jtSource = cellToVertex.get(jSource);
V jtTarget = cellToVertex.get(jTarget);
E jtEdge = jtGraph.addEdge(jtSource, jtTarget);
if (jtEdge != null) {
cellToEdge.put(jEdge, jtEdge);
edgeToCell.put(jtEdge, jEdge);
} else {
// Adding failed because user is using a JGraphT graph the
// forbids parallel edges.
// For consistency, we remove the edge from the JGraph too.
internalRemoveCell(jEdge);
System.err.println(
"Warning: an edge was deleted because the underlying "
+ "JGraphT graph refused to create it. "
+ "This situation can happen when a constraint of the "
+ "underlying graph is violated, e.g., an attempt to add "
+ "a parallel edge or a self-loop to a graph that forbids "
+ "them. To avoid this message, make sure to use a "
+ "suitable underlying JGraphT graph.");
}
}
}
/**
* Adds to the underlying JGraphT graph a vertex corresponding to the
* specified JGraph vertex. In JGraph, two vertices with the same user
* object are in principle allowed; in JGraphT, this would lead to duplicate
* vertices, which is not allowed. So if such vertex already exists, the
* specified vertex is REMOVED from the JGraph graph and a a warning is
* printed.
*
* <p>This method is to be called only for vertices that have already been
* added to the JGraph graph.</p>
*
* @param jVertex the JGraph vertex that has been added.
*/
@SuppressWarnings("unchecked")
void handleJGraphInsertedVertex(GraphCell jVertex)
{
V jtVertex;
if (jVertex instanceof DefaultGraphCell) {
// FIXME hb 28-nov-05: waiting for jgraph to go generic
jtVertex = (V) ((DefaultGraphCell) jVertex).getUserObject();
} else {
// FIXME: Why toString? Explain if for a good reason otherwise fix.
jtVertex = (V) jVertex.toString();
}
if (vertexToCell.containsKey(jtVertex)) {
// We have to remove the new vertex, because it would lead to
// duplicate vertices. We can't use ShieldedGraph.removeVertex for
// that, because it would remove the wrong (existing) vertex.
System.err.println(
"Warning: detected two JGraph vertices with "
+ "the same JGraphT vertex as user object. It is an "
+ "indication for a faulty situation that should NOT happen."
+ "Removing vertex: " + jVertex);
internalRemoveCell(jVertex);
} else {
jtGraph.addVertex(jtVertex);
cellToVertex.put(jVertex, jtVertex);
vertexToCell.put(jtVertex, jVertex);
}
}
/**
* Removes the edge corresponding to the specified JGraph edge from the
* JGraphT graph. If the specified edge is not contained in {@link
* #cellToEdge}, it is silently ignored.
*
* <p>This method is to be called only for edges that have already been
* removed from the JGraph graph.</p>
*
* @param jEdge the JGraph edge that has been removed.
*/
void handleJGraphRemovedEdge(org.jgraph.graph.Edge jEdge)
{
if (cellToEdge.containsKey(jEdge)) {
E jtEdge = cellToEdge.get(jEdge);
jtGraph.removeEdge(jtEdge);
cellToEdge.remove(jEdge);
edgeToCell.remove(jtEdge);
}
}
/**
* Removes the vertex corresponding to the specified JGraph vertex from the
* JGraphT graph. If the specified vertex is not contained in {@link
* #cellToVertex}, it is silently ignored.
*
* <p>If any edges are incident with this vertex, we first remove them from
* the both graphs, because otherwise the JGraph graph would leave them
* intact and the JGraphT graph would throw them out. TODO: Revise this
* behavior now that we gracefully tolerate dangling edges. It might be
* possible to remove just the JGraphT edges. The JGraph edges will be left
* dangling, as a result.</p>
*
* <p>This method is to be called only for vertices that have already been
* removed from the JGraph graph.</p>
*
* @param jVertex the JGraph vertex that has been removed.
*/
void handleJGraphRemovedVertex(GraphCell jVertex)
{
if (cellToVertex.containsKey(jVertex)) {
V jtVertex = cellToVertex.get(jVertex);
Set<E> jtIncidentEdges = jtGraph.edgesOf(jtVertex);
if (!jtIncidentEdges.isEmpty()) {
// We can't just call removeAllEdges with this list: that
// would throw a ConcurrentModificationException. So we create
// a shallow copy.
// This also triggers removal of the corresponding JGraph
// edges.
jtGraph.removeAllEdges(new ArrayList<E>(jtIncidentEdges));
}
jtGraph.removeVertex(jtVertex);
cellToVertex.remove(jVertex);
vertexToCell.remove(jtVertex);
}
}
/**
* Adds the specified JGraphT edge to be reflected by this graph model. To
* be called only for edges that already exist in the JGraphT graph.
*
* @param jtEdge a JGraphT edge to be reflected by this graph model.
*/
void handleJGraphTAddedEdge(E jtEdge)
{
DefaultEdge edgeCell = cellFactory.createEdgeCell(jtEdge);
edgeToCell.put(jtEdge, edgeCell);
cellToEdge.put(edgeCell, jtEdge);
ConnectionSet cs = new ConnectionSet();
cs.connect(
edgeCell,
getVertexPort(jtGraph.getEdgeSource(jtEdge)),
getVertexPort(jtGraph.getEdgeTarget(jtEdge)));
internalInsertCell(edgeCell, createEdgeAttributeMap(edgeCell), cs);
}
/**
* Adds the specified JGraphT vertex to be reflected by this graph model. To
* be called only for edges that already exist in the JGraphT graph.
*
* @param jtVertex a JGraphT vertex to be reflected by this graph model.
*/
void handleJGraphTAddedVertex(V jtVertex)
{
DefaultGraphCell vertexCell = cellFactory.createVertexCell(jtVertex);
vertexCell.add(new DefaultPort());
vertexToCell.put(jtVertex, vertexCell);
cellToVertex.put(vertexCell, jtVertex);
internalInsertCell(
vertexCell,
createVertexAttributeMap(vertexCell),
null);
}
/**
* Removes the specified JGraphT vertex from being reflected by this graph
* model. To be called only for vertices that have already been removed from
* the JGraphT graph.
*
* @param jtVertex a JGraphT vertex to be removed from being reflected by
* this graph model.
*/
void handleJGraphTRemoveVertex(Object jtVertex)
{
DefaultGraphCell vertexCell =
(DefaultGraphCell) vertexToCell.remove(jtVertex);
cellToVertex.remove(vertexCell);
List<Object> ports = new ArrayList<Object>();
for (Object child : vertexCell.getChildren()) {
if (this.isPort(child)) {
ports.add(child);
}
}
this.remove(ports.toArray());
internalRemoveCell(vertexCell);
}
/**
* Removes the specified JGraphT edge from being reflected by this graph
* model. To be called only for edges that have already been removed from
* the JGraphT graph.
*
* @param jtEdge a JGraphT edge to be removed from being reflected by this
* graph model.
*/
void handleJGraphTRemovedEdge(E jtEdge)
{
DefaultEdge edgeCell = (DefaultEdge) edgeToCell.remove(jtEdge);
cellToEdge.remove(edgeCell);
internalRemoveCell(edgeCell);
}
/**
* Tests if the specified JGraph edge is 'dangling', that is having at least
* one endpoint which is not connected to a vertex.
*
* @param jEdge the JGraph edge to be tested for being dangling.
*
* @return <code>true</code> if the specified edge is dangling, otherwise
* <code>false</code>.
*/
private boolean isDangling(org.jgraph.graph.Edge jEdge)
{
Object jSource = getSourceVertex(this, jEdge);
Object jTarget = getTargetVertex(this, jEdge);
return !cellToVertex.containsKey(jSource)
|| !cellToVertex.containsKey(jTarget);
}
@SuppressWarnings("unchecked")
private AttributeMap createEdgeAttributeMap(DefaultEdge edgeCell)
{
AttributeMap attrs = new AttributeMap();
// FIXME hb 28-nov-05: waiting for graph to go generic
attrs.put(edgeCell, getDefaultEdgeAttributes().clone());
return attrs;
}
@SuppressWarnings("unchecked")
private AttributeMap createVertexAttributeMap(GraphCell vertexCell)
{
AttributeMap attrs = new AttributeMap();
// FIXME hb 28-nov-05: waiting for graph to go generic
attrs.put(vertexCell, getDefaultVertexAttributes().clone());
return attrs;
}
/**
* Inserts the specified cell into the JGraph graph model.
*
* @param cell
* @param attrs
* @param cs
*/
// FIXME hb 28-nov-05: waiting for graph to go generic
private void internalInsertCell(
GraphCell cell,
AttributeMap attrs,
ConnectionSet cs)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?