The Edge class provides methods to edit various Edge properties including color, weight, flow, capacity and minimum. The U() and V() methods allow access to the Vertex objects which the Edge contains, and the draw() methods are used to draw the Edge using a Graphic object. The beenSelected() method may be used to set or determine whether an Edge is currently selected, and the directed() method returns true if the Edge is directed. The Edge class provides toString(), fromString() and arrayFromString() methods which a Graph object can use to convert Edge objects to or from text. The class also implements the Sortable interface, so that an array of Edge objects can be sorted by color, weight, flow, capacity, minimum, or even by either the U or V Vertex number.
package GraphStuff;
import java.awt.*;
import MyUtil.*;
import java.util.*;
public final class Edge implements Cloneable, Sortable {
public static final int weightOrderA = 0, // A = ascending
weightOrderD = 1, // D = descending
VvNumOrderA = 2,
VvNumOrderD = 3,
UvNumOrderA = 4,
UvNumOrderD = 5,
capacityOrderA = 6,
capacityOrderD = 7,
flowOrderA = 8,
flowOrderD = 9,
colorNumOrderA = 10,
colorNumOrderD = 11,
minimumOrderA = 12,
minimumOrderD = 13;
protected int[] X = new int[8], // used for polygon in drawing
Y = new int[8];
int tmpVNum, tmpUNum; // These are only accessible within the GraphStuff
// package. They are used by a Graph when a
// Vertex has not yet been inserted.
private Vertex p_U,p_V;
private int p_colorNum;
private boolean p_beenSelected,
p_directed;
private int p_weight,
p_capacity,
p_flow,
p_minimum,
p_shapePoints;
protected Edge(int UNum, int VNum, int colorNum, int weight,
int flow, int capacity, int minimum) {
this(colorNum,weight,flow,capacity,minimum);
tmpUNum = UNum;
tmpVNum = VNum;
}
public Edge(int colorNum,int weight, int flow, int capacity, int minimum) {
colorNum(colorNum>=0?colorNum:0);
weight(weight>=0?weight:1);
flow(flow>=0?flow:0);
minimum(minimum>=0?minimum:0);
capacity(capacity>=minimum?capacity:minimum);
directed(true);
p_V=null;
p_U=null;
}
public Edge(int colorNum,int weight, int flow, int capacity) {
this(colorNum,weight,flow,capacity,0);
}
public Edge(int colorNum,int weight, int capacity) {
this(colorNum,weight,0,capacity,0);
}
public Edge(int colorNum,int weight) {
this(colorNum,weight,0,100,0);
}
public Edge(int colorNum) {
this(colorNum,1);
}
public String toString() {
return "Edge: "
+ (U()!=null?U().vNum():tmpUNum)
+ " " + (V()!=null?V().vNum():tmpVNum)
+ " " + colorNum()
+ " " + weight()
+ " " + flow()
+ " " + capacity()
+ " " + minimum();
}
public static String header() {
return "Edge= u v color wt flow cap min";
}
public static Edge[] arrayFromString(String string) {
int c=0, index=0;
while(0!=(index=string.indexOf("Edge:",index)+1))
c++;
if (c==0)
return null;
Edge[] e = new Edge[c];
index=0;
for(int i=0;i<c;i++) {
index=string.indexOf("Edge:",index);
if (null==(e[i]=fromString(string,index)))
return null;
index++;
}
return e;
}
public static Edge fromString(String string) {
return fromString(string,0);
}
public static Edge fromString(String string, int first) {
int t_UNum, t_VNum, t_colorNum,
t_weight, t_flow, t_capacity, t_minimum;
String tag;
xPoint t_center;
StringTokenizer st = new StringTokenizer(string.substring(first));
try {
tag=st.nextToken();
if (!tag.equals("Edge:")) {
System.out.println(
"Error: Edge.fromString() - bad tag\n");
return null;
}
t_UNum=Integer.parseInt(st.nextToken());
t_VNum=Integer.parseInt(st.nextToken());
t_colorNum=Integer.parseInt(st.nextToken());
t_weight=Integer.parseInt(st.nextToken());
t_flow=Integer.parseInt(st.nextToken());
t_capacity=Integer.parseInt(st.nextToken());
t_minimum=Integer.parseInt(st.nextToken());
return new Edge(t_UNum,t_VNum, t_colorNum, t_weight,
t_flow,t_capacity,t_minimum);
}
catch (NumberFormatException e) {
System.out.println(
"Error: Edge.fromString() - NumberFormatException\n");
}
catch (NoSuchElementException e) {
System.out.println("Error: Edge.fromString() - Missing Data\n");
}
return null;
}
public final Edge beenSelected(boolean tf ) {
p_beenSelected = tf;
return this;
}
public final boolean beenSelected() {
return p_beenSelected;
}
public final Edge colorNum(int cNum) {
p_colorNum=cNum;
return this;
}
public final int colorNum() { return p_colorNum; }
public final Vertex U() { return p_U; }
public final Vertex V() { return p_V; }
public final boolean directed() {
return p_directed;
}
protected Edge directed(boolean tf) {
if (tf)
p_shapePoints=7;
else p_shapePoints=4;
p_directed=tf;
return this;
}
protected boolean addVertices( Vertex u, Vertex v ) {
if (p_U==null && p_V==null && u!=null && v!=null ) {
p_U=u;
p_V=v;
return (p_U.addEdge(this)
&& p_V.addEdge(this));
}
return false;
}
protected Edge U(Vertex u) {
if (p_U!=null && u!=null) {
Vertex t = p_U;
p_U.removeEdge(this);
p_U=u;
if (!p_U.addEdge(this)) {
p_U=t;
p_U.addEdge(this);
}
}
return this;
}
protected Edge V(Vertex v) {
if (p_V!=null && v!=null) {
Vertex t = p_V;
p_V.removeEdge(this);
p_V=v;
if (!p_V.addEdge(this)) {
p_V=t;
p_V.addEdge(this);
}
}
return this;
}
protected void releaseVertices() {
if (p_U!=null && p_V!=null) {
p_U.removeEdge(this);
p_V.removeEdge(this);
p_U=null;
p_V=null;
}
}
private int shapePoints() {
return p_shapePoints;
}
public final int weight() {
return p_weight;
}
public final Edge weight( int wt ) {
p_weight = wt;
return this;
}
public final int flow() {
return p_flow;
}
public final Edge flow( int f ) {
p_flow = f;
return this;
}
public final int minimum() {
return p_minimum;
}
public final Edge minimum( int low ) {
p_minimum = low;
return this;
}
public final int capacity() {
return p_capacity;
}
public final Edge capacity( int cap ) {
p_capacity = cap;
return this;
}
public Object clone() {
Edge tmp = new Edge(colorNum(),weight(),flow(),capacity(), minimum());
tmp.p_directed = p_directed;
if (this.U()!=null)
tmp.p_U=(Vertex)(this.U().clone());
if (this.V()!=null)
tmp.p_V=(Vertex)(this.U().clone());
return tmp;
}
protected void setShape(int k) {
General G = new General();
xPoint v = p_V.center();
xPoint u = p_U.center();
xPoint a,b,s,t;
if (!directed()) {
a= u.moveToward(G.vor()-3,v);
b= v.moveToward(G.vor()-3,u);
t=a.moveRP(G.halfBarWidths[k],b);
XY(0,t);
XY(1,a.moveLP(G.halfBarWidths[k],b));
XY(2,b.moveRP(G.halfBarWidths[k],a));
XY(3,b.moveLP(G.halfBarWidths[k],a));
XY(4,t);
} else {
a=u.moveToward(G.vir(),v).moveRP(G.vor()/2,v);
b=v.moveToward(G.vor()*3/2,u).moveLP(G.vor()/2,u);
s=b.moveToward(G.halfBarWidths[1]
-3*G.halfBarWidths[k],a);
t=b.moveToward(2*G.halfBarWidths[k],a);
XY(0,s);
XY(1,t.moveRP(2*G.halfBarWidths[k],a));
XY(2,t.moveRP(G.halfBarWidths[k],a));
XY(3,a.moveToward(G.vir(),b).moveLP(G.halfBarWidths[k],b));
XY(4,a.moveRP(G.halfBarWidths[k],b));
XY(5,t.moveLP(G.halfBarWidths[k],a));
XY(6,t.moveLP(2*G.halfBarWidths[k],a));
XY(7,s);
}
}
protected void XY(int n, xPoint t) {
X[n]=t.x;
Y[n]=t.y;
}
public void draw(Graphics g) {
draw(g,false);
}
public void draw(Graphics g, boolean labelsOnly) {
int k;
if (V()!=null || U()!=null) {
if (!labelsOnly) {
if (beenSelected())
k=0;
else k=1;
for (;k<General.barsInUse;k++){
setShape(k);
if (k==General.barsInUse-1)
g.setColor(General.colors(colorNum()));
else
g.setColor(General.barColors[k]);
g.fillPolygon(X,Y,shapePoints());
}
} else if (General.showWeights||General.showFlows
||General.showCapacities||General.showMinimums) {
xPoint t=focus();
g.setFont(General.f());
g.setColor(General.textColor);
String tmp="";
if (General.showWeights)
tmp = "" + weight();
if (General.showFlows)
if (tmp.length()>0)
tmp = tmp + "," + flow();
else tmp = "" + flow();
if (General.showCapacities)
if (tmp.length()>0)
tmp = tmp + "," + capacity();
else tmp = "" + capacity();
if (General.showMinimums)
if (tmp.length()>0)
tmp = tmp+ "," + minimum();
else tmp = "" + minimum();
g.drawString(tmp,
t.x - g.getFontMetrics(General.f()).stringWidth(tmp)/2, t.y);
}
}
}
public xPoint focus() {
xPoint a,b,u=U().center(),v=V().center(),t;
if (!directed()) {
t = u.moveToward(u.dist(v)/2, v);
} else {
a=u.moveToward(General.vir(),v).moveRP(General.vor()/2,v);
b=v.moveToward(General.vor()*3/2,u).moveLP(General.vor()/2,u);
t = a.moveToward(3*a.dist(b)/4, b);
}
return t;
}
public boolean contains(xPoint p) {
if (V()==null || U()==null // not yet inserted
|| p ==null ) // cursor location not given
return false;
xPoint t;
setShape(1);
return new Polygon(X,Y,shapePoints()).inside(p.x,p.y);
}
public boolean precedes(Sortable s, int order) {
Edge e = (Edge)s;
switch(order) {
case weightOrderA:
return weight() < e.weight();
case VvNumOrderA:
return V().vNum() < e.V().vNum();
case UvNumOrderA:
return U().vNum() < e.U().vNum();
case capacityOrderA:
return capacity() < e.capacity();
case flowOrderA:
return flow() < e.flow();
case colorNumOrderA:
return colorNum() < e.colorNum();
case weightOrderD:
return weight() > e.weight();
case VvNumOrderD:
return V().vNum() > e.V().vNum();
case UvNumOrderD:
return U().vNum() > e.U().vNum();
case capacityOrderD:
return capacity() > e.capacity();
case flowOrderD:
return flow() > e.flow();
case colorNumOrderD:
return colorNum() > e.colorNum();
default:
return false;
}
}
}