next up previous contents
Next: General Class Up: GraphStuff Package Previous: Edge Class

Vertex Class

The Vertex class provides methods to edit various Vertex properties including color, demand, vNum and vName. Note that access to the vNum(int) method may be restricted by the use of a lock() method. This mechanisim allows a Graph object to insure that the vertex number cannot be changed after the Vertex is stored in the Graph. This is critical since a Graph uses the Vertex vNum in hashing. The edges(), inEdges() and outEdges() methods allow access to the Edge objects--stored in a HashTable--which contain the Vertex. The draw() methods are used to draw the Vertex using a Graphic object. The beenSelected() method may be used to set or determine whether a Vertex is currently selected. The Vertex class provides toString(), fromString(), arrayFromString() methods which a Graph object can use to convert Vertex objects to or from text. The class also implements the Sortable interface, so that an array of Vertex objects can be sorted by vNum, demand, vName, or colorNum.

package GraphStuff;

import java.awt.*;
import MyUtil.*;
import java.util.*; 

public final class Vertex implements Cloneable, Sortable {

   public final static int vNumOrderA = 0,  // A = ascending
                           vNumOrderD = 1,  // D = descending
                           demandOrderA = 2,
                           demandOrderD = 3,
                           vNameOrderA = 4,
                           vNameOrderD = 5,
                           colorNumOrderA = 6,
                           colorNumOrderD = 7;

   public Vertex(int vNum, String vName, int demand, 
                 int colorNum, int x, int y) {
      demand(demand);
      vNum(vNum);
      vName(vName);
      p_center = new xPoint(x,y);
      colorNum(colorNum);
      eHt = new Hashtable(35);
   }

   public Vertex(int vNum, String vName) {
      this(vNum,vName,0,General.defaultColorNum,20,20); // ;-)
   }

   public Vertex(int vNum) {
      this(vNum,null);
   }

   private boolean p_lock=false,         // used to lock the vertex number
                   changed_edges=true,
                   p_beenSelected=false; 

   private Hashtable eHt;

   private Edge p_edges[];  // lazy array of adjacent edges

   private int p_demand,
               p_inDegree=0,
               p_outDegree=0;

   private int p_colorNum,
               p_vNum;

   private String p_vName;

   private xPoint p_center;

   public final Vertex lock(boolean tf) {
      p_lock=p_lock || tf;
      return this;
   }

   public final boolean lock() { return p_lock;} 

   public final boolean beenSelected() { return p_beenSelected;}

   public final Vertex beenSelected(boolean haveI) {
      p_beenSelected=haveI;
      return this;
   }

   public final xPoint center() { return p_center ;}

   public final Vertex center(xPoint p) {
      p_center.x=p.x;
      p_center.y=p.y;
      return this;
   }

   public final Vertex center(int x, int y) {
      p_center.x=x;
      p_center.y=y;
      return this;
   }

   public final int degree() { return p_inDegree+p_outDegree; }

   public final int inDegree() { return p_inDegree; }

   public final int outDegree() { return p_outDegree; }

   public Edge[] edges() {
      if (eHt==null || eHt.size()<=0)
         return null;
      int i=0;
      Edge[] edges=new Edge[eHt.size()];
      Enumeration tmp = eHt.elements();
      while (tmp.hasMoreElements()) {
         edges[i++]=(Edge)(tmp.nextElement());
      }
      return edges;
   }

   public Edge[] inEdges() {
      if (eHt==null || eHt.size()<=0)
         return null;
      int i=0;
      Edge[] edges=new Edge[inDegree()];
      Enumeration tmp = eHt.elements();
      Edge E;
      while (tmp.hasMoreElements() && i<inDegree()) {
         E=(Edge)(tmp.nextElement());
           if (E.V()==this)
                edges[i++]=E;
      }
      return edges;
   }

   public Edge[] outEdges() {
      if (eHt==null || eHt.size()<=0)
         return null;
      int i=0;
      Edge[] edges=new Edge[outDegree()];
      Enumeration tmp = eHt.elements();
      Edge E;
      while (tmp.hasMoreElements() && i<outDegree()) {
         E=(Edge)(tmp.nextElement());
           if (E.U()==this)
                edges[i++]=E;
      }
      return edges;
   }

   private Edge[] p_edges() {
      if (!changed_edges)
         return p_edges;
      else if (eHt.size()>0) {
         int i=0;
         p_edges=new Edge[eHt.size()];
         Enumeration tmp = eHt.elements();
         while (tmp.hasMoreElements()) {
            p_edges[i++]=(Edge)(tmp.nextElement());
         }
      } else p_edges=null;
      return p_edges;
   }

   protected boolean addEdge(Edge E) {
      if (E==null || E.U()==null || E.V()==null ||(E.U()!=this && E.V()!=this) )
         return false;
      removeEdge(E);
      eHt.put(""+E.U().vNum()+" "+E.V().vNum(),E);
      if (E.U()==this)
         p_outDegree++;
      if (E.V()==this)
         p_inDegree++;
      changed_edges=true;
      return true;
   }

   protected void removeEdge(Edge E) {
      if (E!=null
         && E.U()!=null && E.V()!=null
         && (E.U()==this || E.V()==this)
         && eHt.remove(""+E.U().vNum()+" "+E.V().vNum())!=null ) {
         if (E.U()==this)
            p_outDegree--;
         if (E.V()==this)
            p_inDegree--;
         changed_edges=true;
      }
   }

   public static String header() {
      return "Vertex= v label demand color (x,y)";
   }

   public String toString() {
      return "Vertex: "+vNum()
         +" " + vName()
         +" " + demand()
         +" " + colorNum()
         +" " + center();
   }

   public static Vertex[] arrayFromString(String string) {
      int c=0, index=0;
      while(0!=(index=string.indexOf("Vertex:",index)+1))
         c++;
      if (c==0)
         return null;
      Vertex[] v = new Vertex[c];
      index=0;
      for(int i=0;i<c;i++) {
         index=string.indexOf("Vertex:",index);
         if (null==(v[i]=fromString(string,index)))
            return null;
         index++;
      }
      return v;
   }

   public static Vertex fromString(String string) {
      return fromString(string,0);
   }

   public static Vertex fromString(String string, int first) {
      int t_vNum,t_colorNum, t_demand;
      String tag,t_vName;
      xPoint t_center;
      StringTokenizer st = new StringTokenizer(string.substring(first));
      try {
         tag=st.nextToken();
         if (!tag.equals("Vertex:")) {
            System.out.println(
                "Error: Vertex.fromString() - bad tag\n"); 
            return null;
         }
         t_vNum=Integer.parseInt(st.nextToken());
         t_vName=st.nextToken();
         t_demand=Integer.parseInt(st.nextToken());
         t_colorNum=Integer.parseInt(st.nextToken());
         t_center=xPoint.fromString(st.nextToken());
         if (t_center==null)
            return null;
         return new Vertex(t_vNum,t_vName,t_demand,t_colorNum,
                          t_center.x,t_center.y);         
      } 
      catch (NumberFormatException e) {
         System.out.println(
            "Error: Vertex.fromString() - NumberFormatException\n"); 
      }
      catch (NoSuchElementException e) {
         System.out.println("Error: Vertex.fromString() - Missing Data\n"); 
      }
      return null;
   }

   private String defaultName() {
      return defaultName(p_vNum-1);
   }

   private String defaultName(int x) {
      int L=General.alphas.length();
      if (x>L-1)
         return defaultName(x/L-1) + General.alphas.substring(x%L,x%L+1);
      else return General.alphas.substring(x,x+1);
   }

   public final Vertex colorNum(int cNum) {
      if (cNum>=0)
         p_colorNum = cNum;
      return this;
   }

   public final int colorNum() {
      return p_colorNum;
   }

   public final int demand() {
      return p_demand;
   }

   public final Vertex demand(int d) {
      p_demand = d;
      return this;
   }

   public final Vertex vName(String vName) {
      if (vName==p_vName)
         return this;
      if (vName!=null && vName.length()>0 ) {
         p_vName=vName.replace(' ','_');
      }
      else p_vName=null;
      return this;
   }

   public final String vName() {
      return p_vName;
   } 

   public final Vertex vNum(int vNumber) {
      if (!p_lock) {
         p_vNum = vNumber;
         if (p_vName==null)
            p_vName= defaultName();
      }
      return this;
   }

   public final int vNum() {
      return p_vNum;
   }

   public Object clone() {
      return new Vertex(vNum(), vName(), demand(),
                        colorNum(), p_center.x, p_center.y);
   } 

   protected void drawWithEdges(Graphics g) {
      Edge Es[]=p_edges();
      if (Es!=null)
         for(int i=0;i<Es.length;i++)
            Es[i].draw(g);
      draw(g);
      if (Es!=null)
         for(int i=0;i<Es.length;i++)
            Es[i].draw(g,true);
   }

   public void draw(Graphics g) {
      int vir = General.vir();
      int vor = General.vor();
      int x = center().x- vor;
      int y =  center().y- vor;
      int ix = center().x- vir;
      int iy =  center().y- vir;
      int id = 2* vir;
      int od = 2* vor;
      if (beenSelected()) {
          g.setColor(General.highlightColor);
          g.fillOval(x-3,y-3,od+6,od+6);
      }
      g.setColor(General.gridBright);
      g.fillOval(x-1, y-1, od, od);
      g.setColor(General.gridDark);
      g.fillOval(x, y+1, od, od);
      g.setColor(General.gridColor);
      g.fillOval(x, y, od-2, od-2);
      g.setColor(General.gridDark);
                g.fillOval(ix-2,iy-2,id+4,id+4);
      g.setColor(General.colors(colorNum()));
                g.fillOval(ix,iy,id,id);
      g.setFont(General.f());
      g.setColor(General.textColor);
      if (General.showLabels && General.showDemands)
         g.drawString(vName() + "," + demand(), 
                      center().x+vir, center().y-vir);
      else if (General.showLabels)
         g.drawString(vName(), center().x+vir, center().y-vir);
      else if (General.showDemands)
         g.drawString(demand()+"", center().x+vir, center().y-vir);
   }

   public boolean contains(xPoint p) {
      return (center().dist2(p)<General.vor()*General.vor());
   }

   public boolean precedes(Sortable s, int order) {
      Vertex v = (Vertex)s;
      switch(order) {
         case demandOrderA:
            return demand() < v.demand();
         case vNumOrderA:
            return vNum() < v.vNum();
         case colorNumOrderA:
            return colorNum() < v.colorNum();
         case vNameOrderA:
            return vName().compareTo(v.vName()) < 0;
         case demandOrderD:
            return demand() > v.demand();
         case vNumOrderD:
            return vNum() > v.vNum();
         case colorNumOrderD:
            return colorNum() > v.colorNum();
         case vNameOrderD:
            return vName().compareTo(v.vName()) > 0;
         default:
            return false;
      }
   }

}



Kelly Waters
Mon Oct 27 18:18:15 EST 1997