📄 orthogonallinelayout.java
字号:
package salvo.jesus.graph.visual.layout;
import salvo.jesus.graph.visual.*;
import salvo.jesus.graph.java.awt.geom.Point2DDouble;
import java.awt.Point;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.*;
import java.util.*;
/**
* A concrete implementation of GraphLayoutManager, extending AbstractGraphLayout,
* used to layout the vertices of a graph with horizontal and vertices line edges.
*
* @author Jesus M. Salvo Jr.
*/
public class OrthogonalLineLayout extends AbstractGridLayout {
/**
* A List object where each element is in turn a List of VisualEdges.
* The index of a VisualVertex in vgraph.visualvertices matches the index of
* the VisualVertex's List of top VisualEdges.
*/
List topedges;
/**
* A List object where each element is in turn a List of VisualEdges.
* The index of a VisualVertex in vgraph.visualvertices matches the index of
* the VisualVertex's List of right VisualEdges.
*/
List rightedges;
/**
* A List object where each element is in turn a List of VisualEdges.
* The index of a VisualVertex in vgraph.visualvertices matches the index of
* the VisualVertex's List of left VisualEdges.
*/
List leftedges;
/**
* A List object where each element is in turn a List of VisualEdges.
* The index of a VisualVertex in vgraph.visualvertices matches the index of
* the VisualVertex's List of bottom VisualEdges.
*/
List bottomedges;
/**
* Creates a OrthogonalLineLayout object used to layout the VisualGraph object
* specified by vgraph.
*
* Because no translation parameters are specified, position 0,0
* of the internal Grid object will be drawn on 0,0 of the Container;
* and the distance between grid lines is 100.
*
* @param vgraph The VisualGraph object to be laid out.
*/
public OrthogonalLineLayout( VisualGraph vgraph ) {
super( vgraph );
}
/**
* Creates a OrthogonalLineLayout object used to layout the VisualGraph object
* specified by vgraph.
*
* Because no translation parameters are specified, position 0,0
* of the internal Grid object will be drawn on 0,0 of the Container;
* and the distance between grid lines is 100.
*
* @param gpane A GraphScrollPane object encapsulating the VisualGraph
* object to be laid out.
*/
public OrthogonalLineLayout( GraphScrollPane gpane ){
super( gpane.getVisualGraph() );
}
/**
* Creates a OrthogonalLineLayout object used to layout the VisualGraph object
* specified by vgraph.
*
* Because no translation parameters are specified, position 0,0
* of the internal Grid object will be drawn on 0,0 of the Container;
* and the distance between grid lines is 100.
*
* @param gedit A GraphEditor object encapsulating a GraphScrollPane object
* which in turn encapsulates the VisualGraph object to be laid out.
*/
public OrthogonalLineLayout( GraphEditor gedit ){
super( gedit.getVisualGraph() );
}
/**
* Initializes the internal List objects
*/
protected void initGraphLayout() {
int i, size = this.vgraph.getVisualVertices().size();
this.topedges = new ArrayList( size );
this.bottomedges = new ArrayList( size );
this.leftedges = new ArrayList( size );
this.rightedges = new ArrayList( size );
for( i = 0; i < size; i++ ) {
this.topedges.add( new ArrayList());
this.bottomedges.add( new ArrayList());
this.leftedges.add( new ArrayList());
this.rightedges.add( new ArrayList());
}
}
/**
* Automatically called by the VisualGraph's vertexAdded() method
* whenever a vertex has been added to the graph and consequently
* when the VisualVertex has been added to the VisualGraph object.
*
* @param vvertex The newly added VisualVertex object.
*/
public void addVertex( VisualVertex vvertex ){
// No need to do anything if layout has not been initialized,
// as the Lists will be reinitialized anyway during layout.
if( !this.initialized ) return;
int index = this.vgraph.getVisualVertices().indexOf( vvertex );
this.topedges.add( new ArrayList());
this.bottomedges.add( new ArrayList());
this.leftedges.add( new ArrayList());
this.rightedges.add( new ArrayList());
}
/**
* Automatically called by the VisualGraph's vertexRemoved() method
* whenever a vertex is about to be removed from the graph and
* consequently when a VisualVertex is about to be removed
* from the VisualGraph object.
*
* @param vvertex The VisualVertex object about to be removed.
*/
public void removeVertex( VisualVertex vvertex ){
// No need to do anything if layout has not been initialized,
// as the Lists will be reinitialized anyway during layout.
if( !this.initialized ) return;
int index = this.vgraph.getVisualVertices().indexOf( vvertex );
((List) this.topedges.get( index )).clear();
this.topedges.remove( index );
((List) this.bottomedges.get( index )).clear();
this.bottomedges.remove( index );
((List) this.leftedges.get( index )).clear();
this.leftedges.remove( index );
((List) this.rightedges.get( index )).clear();
this.rightedges.remove( index );
}
/**
* Automatically called by the VisualGraph's edgeAdded() method
* whenever an edge has been added to the graph and consequently
* when a VisualEdge has been added to the VisualGraph object.
*
* This method currently does not do anything as VisualEdges are
* not assigned their port assignments until during layout.
*
* @param vedge The newly added VisualEdge object
*/
public void addEdge( VisualEdge vedge ) {
// Nothing to do for this layuot manager, as visual edges are not
// assigned their port assignments until during layout.
}
/**
* Automatically called by the VisualGraph's edgeRemoved() method
* whenever an edge is about to be removed from the graph and consequently
* when a VisualEdge is about to be removed from the VisualGraph object.
*
* This method will remove all top, left, right, and bottom side assignments of
* a VisualEdge from all vertices.
*
* @param vedge The VisualEdge object about to be removed.
*/
public void removeEdge( VisualEdge vedge ) {
// No need to do anything if layout has not been initialized,
// as the Lists will be reinitialized anyway during layout.
if( !this.initialized ) return;
int fromindex = this.vgraph.getVisualVertices().indexOf( vedge.getVisualVertexA() );
int toindex = this.vgraph.getVisualVertices().indexOf( vedge.getVisualVertexB() );
int i, size;
List side;
side = ((List) this.topedges.get( fromindex ));
while( side.remove( vedge ));
side = ((List) this.bottomedges.get( fromindex ));
while( side.remove( vedge ));
side = ((List) this.leftedges.get( fromindex ));
while( side.remove( vedge ));
side = ((List) this.rightedges.get( fromindex ));
while( side.remove( vedge ));
side = ((List) this.topedges.get( toindex ));
while( side.remove( vedge ));
side = ((List) this.bottomedges.get( toindex ));
while( side.remove( vedge ));
side = ((List) this.leftedges.get( toindex ));
while( side.remove( vedge ));
side = ((List) this.rightedges.get( toindex ));
while( side.remove( vedge ));
}
public void routeEdge( Graphics2D g2d, VisualEdge vedge ) {
// No need to do anything if layout has not been initialized,
// as the Lists will be reinitialized anyway during layout.
if( !this.initialized ) return;
int fromindex = this.vgraph.getVisualVertices().indexOf( vedge.getVisualVertexA() );
int toindex = this.vgraph.getVisualVertices().indexOf( vedge.getVisualVertexB() );
g2d.setColor( vedge.getOutlinecolor() );
Point2D.Double fromport = vedge.getFromPortAssignment();
Point2D.Double toport = vedge.getToPortAssignment();
Point2D.Double fromcenter = new Point2D.Double(
vedge.getVisualVertexA().getBounds2D().getCenterX(),
vedge.getVisualVertexA().getBounds2D().getCenterY() );
Point2D.Double tocenter = new Point2D.Double(
vedge.getVisualVertexB().getBounds2D().getCenterX(),
vedge.getVisualVertexB().getBounds2D().getCenterY() );
GeneralPath gPath = vedge.getGeneralPath();
gPath.reset();
gPath.moveTo(
(float) (fromcenter.x + fromport.x),
(float) (fromcenter.y + fromport.y) );
// Find at which side of the vertex is the edge eminating from to determine
// where the bend should be
if( ((List) topedges.get( fromindex )).contains( vedge ) ||
((List) bottomedges.get( fromindex )).contains( vedge )) {
gPath.lineTo(
(float) (fromcenter.x + fromport.x),
(float) (tocenter.y + toport.y) );
}
else if( ((List) leftedges.get( fromindex )).contains( vedge ) ||
((List) rightedges.get( fromindex )).contains( vedge )) {
gPath.lineTo(
(float) (tocenter.x + toport.x),
(float) (fromcenter.y + fromport.y) );
}
gPath.lineTo(
(float) (tocenter.x + toport.x),
(float) (tocenter.y + toport.y) );
}
/**
* Routes all the edges
*/
protected void routeEdges() {
int i, size = this.vgraph.getVisualVertices().size();
// Clear the side assignments of edges.
for( i = 0; i < size; i++ ) {
((List) this.topedges.get( i )).clear();
((List) this.bottomedges.get( i )).clear();
((List) this.leftedges.get( i )).clear();
((List) this.rightedges.get( i )).clear();
}
size = this.vgraph.getVisualEdges().size();
for( i = 0; i < size; i++ )
this.routeEdge( (VisualEdge) this.vgraph.getVisualEdges().get( i ));
}
protected void routeEdge( VisualEdge vedge ) {
Rectangle frombounds = vedge.getVisualVertexA().getBounds();
Rectangle tobounds = vedge.getVisualVertexB().getBounds();
Point2D.Float fromcenter = new Point2D.Float(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -