📄 abstractgridlayout.java
字号:
package salvo.jesus.graph.visual.layout;
import salvo.jesus.graph.*;
import salvo.jesus.graph.visual.*;
import java.awt.Point;
import java.awt.geom.*;
import java.awt.event.*;
import java.util.*;
import java.lang.reflect.*;
import java.io.*;
import org.apache.log4j.Category;
/**
* An abstract implementation of the GraphLayoutManager interface.
* Neither layout() nor drawLayout() are implemented. However, this
* abstract implementation provides internal variables used by
* concrete implementations of the interface. This class has an internal
* instance of a VisualGraph to gain access to the graph itself and a
* Grid object used to place the vertices on a hypothetical grid.
*
* It also has general purpose methods for grid point assignments of vertices.
* These methods places the vertices in general position and median placement.
*
* @author Jesus M. Salvo Jr.
*/
public abstract class AbstractGridLayout implements GraphGridLayoutManager, Runnable {
/**
* The Grid object where the vertices are laid out and aligned.
*/
Grid grid;
/**
* Used as a translation point when finally drawing the layout.
*
* Since the vertices are laid out on a Grid object, the Grid object
* itself have no assigned x,y coordinates on a Container.
*
* When finally drawing the layout, position 0,0 of the Grid object is translated
* to the Point specified by the startAt variable.
*/
Point startAt = new Point( 50, 50 );
/**
* The distance between vertical grid lines when finally drawing the layout.
* Since this is a fixed value, this class does not take into account a VisualVertex's
* actual width, so much so that a VisualVertex positioned on a specified
* vertical grid line may overlap another vertical grid line if the width of the VisualVertex
* is greater than the distance between vertical grid lines.
*/
int xGridDistance = 100;
/**
* The distance between horizontal grid lines when finally drawing the layout.
* Since this is a fixed value, this class does not take into account a VisualVertex's
* actual width, so much so that a VisualVertex positioned on a specified
* horizontal grid line may overlap another horizontal grid line if the height of the VisualVertex
* is greater than the distance between horizontal grid lines.
*/
int yGridDistance = 100;
/**
* Indicator whether or not the grid should be drawn.
*/
boolean drawGrid = false;
/**
* The VisualGraph object that will be laid out.
*/
VisualGraph vgraph;
/**
* An GraphLayoutListener object that receives notification whenever a vertex
* in the graph has been laid out by the layout manager.
*/
GraphLayoutListener listener;
boolean initialized = false;
ThreadQueue threadqueue = new ThreadQueue();
ThreadGroup threadgroup;
List grids = new ArrayList( 10 );
/**
* Log4J Category. The name of the category is the fully qualified name of the
* enclosing class.
*/
static Category logCategory;
static {
logCategory = Category.getInstance( AbstractGridLayout.class.getName());
}
/**
* Creates a GraphLayoutManager object, specifying vgraph as the
* VisualGraph object to be laid out. This will also initialize
* the internal Grid object based on the number of vertices
* that the graph has.
*/
public AbstractGridLayout( VisualGraph vgraph ) {
this.vgraph = vgraph;
}
/**
* This method sets the point at which the grid starts.
*
* @param startAt Point object indicating the upper left corner of the grid.
*/
public void setStartAt( Point startAt ){
this.startAt = startAt;
}
/**
* This method sets the distance between vertical grids
*
* @param xGridDistance Distance between vertical grids
*/
public void setXGridDistance( int xGridDistance ){
this.xGridDistance = xGridDistance;
}
/**
* This method sets the distance between horizontal grids
*
* @param xGridDistance Distance between horizontal grids
*/
public void setYGridDistance( int yGridDistance ){
this.yGridDistance = yGridDistance;
}
/**
* This method sets or unsets the drawing of the grid
*
* @param isdrawgrid Boolean: If true, the grid will be drawn on the next
* paint operation. Otherwise, the grid will not be drawn.
*/
public void setDrawGrid( boolean isdrawgrid ){
this.drawGrid = isdrawgrid;
}
/**
* Returns the starting position where the grid will be drawn.
*
* @return Point object indicating the starting position where the grid
* will be drawn. By default, this is (0,0).
*/
public Point getStartAt() {
return this.startAt;
}
/**
* Returns the distance between horizontal grid lines.
*
* @return An int indicating the uniform distance between horizontal grid lines.
* By default, this is 100.
*/
public int getXGridDistance() {
return this.xGridDistance;
}
/**
* Returns the distance between vertical grid lines.
*
* @return An int indicating the uniform distance between vertical grid lines.
* By default, this is 100.
*/
public int getYGridDistance() {
return this.yGridDistance;
}
/**
* Determines if the grid is to be drawn.
*
* @return A boolean indicating if the grid will be drawn on the next
* paint operation of the containers of the visual graph.
*/
public boolean getDrawgrid() {
return this.drawGrid;
}
/**
* Returns the grid object where the visual vertices are laid out.
*
* @return A Grid object where the visual vertices are laid out.
*/
public Grid getGrid() {
return this.grid;
}
/**
* Sets the listener object that receives notification whenever a
* vertex in the graph is laid out, either intermediately or for its
* final position, by the layout manager.
*
* @param listener The listener object that will received such notifications.
* Any previous listener will no longer receive notification.
*/
public void setGraphLayoutListener( GraphLayoutListener listener ) {
this.listener = listener;
}
/**
* Partial implementation of the layout() method
* of GraphLayoutManager. All this do is initialize the grid
* and does not really layout the vertices at all.
*
* Subclasses of this class must override this method and
* and call this method first before proceeding with any grid
* actvity.
*/
public void layout(){
this.grid = new Grid( this.vgraph.getVisualVertices() );
this.grid.initGrid();
}
public void drawLayout() {
Iterator iterator;
VisualVertex vvertex;
Point gridpoint;
int startingxgridpoint = this.grid.getStartingXGridPoint();
int startingygridpoint = this.grid.getStartingYGridPoint();
logCategory.debug( "Starting X point" + startingxgridpoint );
logCategory.debug( "Starting Y point" + startingygridpoint );
logCategory.debug( "X distance" + this.xGridDistance );
logCategory.debug( "Y distance" + this.yGridDistance );
iterator = this.vgraph.getGraph().getVerticesIterator();
while( iterator.hasNext()){
vvertex = this.vgraph.getVisualVertex( (salvo.jesus.graph.Vertex) iterator.next());
gridpoint = this.grid.findVisualVertex( vvertex );
logCategory.debug( "Drawing " + vvertex + " at " + gridpoint );
vvertex.setLocation(
(int) (this.startAt.x + this.xGridDistance * gridpoint.x -
(startingxgridpoint - 1) * this.xGridDistance -
vvertex.getBounds2D().getWidth() / 2),
(int) (this.startAt.y + this.yGridDistance * gridpoint.y -
(startingygridpoint - 1) * this.yGridDistance -
vvertex.getBounds2D().getHeight() / 2));
}
this.vgraph.repaint();
}
/**
* Determines if the graph has been initially laid out.
* This method should be called prior to any painting to be done by the
* graph layout manager, as most internal variables are only
* initialized during layout.
*
* @return True if the graph has at least been laid out once.
*/
public boolean isInitialized() {
return this.initialized;
}
/**
* Lays out the visual vertices of the specified connected set general position,
* meaning that only one visual vertex reside on each grid line. The end result
* of this operation is that all visual vertices are in a straight diagonal line.
* The VisualVertex object with the highest degree is placed in the center, and
* those with lesser degrees are farther away from the center.
*
* To accomplish this, the grid matrix must be of size m x m,
* which is what is done.
*
* @param connectedset List of VisualVertex that are connected to each other
* @param grid Grid object where the visual vertices in the connected set
* will be laid out for general position.
* @return Returns a VisualVertex object which is placed at the center. Put in another
* way, this is the VisualVertex object with the highest degree. If there are tweo or more
* vertices with the same highest degree, there is no guarantee as to which among them
* will be returned or placed in the center first.
*/
public VisualVertex generalPosition( java.util.List connectedset, Grid grid ){
int i, size, center, increment, point;
int randomx, randomy;
Random random = new Random();
Iterator iterator;
VisualVertex centervertex;
size = connectedset.size();
Collections.sort( connectedset, new NumberofEdgesComparator( this.vgraph.getGraph() ));
center = size / 2 + ( size % 2 == 0 ? 0 : 1 );
for( i = 0, increment = 0, point = center + increment - 1, centervertex = (VisualVertex) connectedset.get(0);
i < size; i++ ) {
increment = ( i + 1 )/2 * (i % 2 == 0 ? 1 : -1 );
point = center + increment - 1;
if( point < 0 || point >= size )
point = center + (-increment) - 1;
grid.setGridPoint(
point, point,
(VisualVertex) connectedset.get( i ));
}
return centervertex;
}
/**
* Positions a VisualVertex to be in median placement, meaning
* that the vertex should be in the center of all of its adjacent vertices,
* without adjusting the positions of other vertices.
*
* The resulting position is not always on the center, since vertices are
* restricted to grid points and another vertex may reside on the median,
* in which case the grid points surrounding median is searched for an
* alternate median position based on the minimal total edge length of the
* incident edges of the vertex.
*
* @param vvertex The VisualVertex object which will be placed in the median
* of its adjacent vertices.
*/
private void medianPlacement( VisualVertex vvertex, List finalplacedvertices ){
this.medianPlacement( vvertex,
new HashSet( this.vgraph.translateToVisualVertices( this.vgraph.getGraph().getAdjacentVertices( vvertex.getVertex()))),
this.grid, finalplacedvertices );
}
/**
* Positions a VisualVertex to be in median placement, meaning
* that the vertex should be in the center of all of its adjacent vertices,
* specified in the argument adjacentVertices,
* without adjusting the positions of other vertices.
*
* The resulting position is not always on the center, since vertices are
* restricted to grid points and another vertex may reside on the median,
* in which case the grid points surrounding median is searched for an
* alternate median position based on the minimal total edge length of the
* incident edges of the vertex.
*
* @param vvertex The VisualVertex object which will be placed in the median
* of its adjacent vertices.
* @param adjacentVertices Position the visual vertex in the center of its
* adjacent vertices specified in this set only.
*/
private void medianPlacement( VisualVertex vvertex, Set adjacentVertices,
Grid grid, List finalplacedvertices ) {
Iterator iterator;
Point point, median, alternatemedian;
VisualVertex preplacedvertex;
int adjacentcount, xtotal = 0, ytotal = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -