天天看點

一個用Dijkstra算法實作的路由算法的java程式——4 MapCanvas類

import java.awt.*;

public class MapCanvas extends Canvas {

 GraphFromFile graph = null;

 int nodeNum = 0;

 GraphAdjList graphAdjList[] = null;

 int nodePosition[][] = null;

 String nodeID[] = null;

 public MapCanvas(GraphFromFile g) {

  super();

  graph = g;

  nodeNum = graph.getNodeNum();

  graphAdjList = graph.getList();

  nodePosition = graph.getNodePosition();

  nodeID = graph.getNodeID();

 }

 public void paint(Graphics g) {

  //地圖周圍的空白邊框。

  final int BLANK_BORDER = 15;

  //每個結點的直徑。

  final int POINT_DIAMETER = 10;

  //每個網格的寬度。

  int cellWidth = (int)((getSize().getWidth() - 2*BLANK_BORDER)/40);

  //每個網格的高度。

  int cellHeight = (int)((getSize().getHeight() - 2*BLANK_BORDER)/40);

  //地圖網格區域的總寬度。(網格數為40)

  int graphWidthRange = cellWidth * 40;

  //地圖網格區域的總高度。(網格數為40)

  int graphHeightRange = cellHeight * 40;

  //繪制灰色的地圖網格。

  g.setColor(Color.GRAY);

  for (int i = BLANK_BORDER; i <= graphHeightRange + BLANK_BORDER; i += cellHeight) {

   g.drawLine(BLANK_BORDER, i, graphWidthRange + BLANK_BORDER, i);

  }

  for (int j = BLANK_BORDER; j <= graphWidthRange + BLANK_BORDER; j += cellWidth) {

   g.drawLine(j, BLANK_BORDER, j, graphHeightRange + BLANK_BORDER);

  }

  //将每個結點根據其坐标資訊繪制在相應的網格點上。并在其旁繪制相應的結點名稱。

  g.setColor(Color.BLACK);

  for (int i = 0; i < nodeNum; i++) {

   g.fillOval((nodePosition[i][0]*cellWidth - POINT_DIAMETER/2) + BLANK_BORDER, (nodePosition[i][1]*cellHeight - POINT_DIAMETER/2) + BLANK_BORDER, POINT_DIAMETER, POINT_DIAMETER);

   g.setColor(Color.BLUE);

   g.drawString(nodeID[i], (nodePosition[i][0]*cellWidth + (POINT_DIAMETER/2+2)) + BLANK_BORDER, (nodePosition[i][1]*cellHeight + POINT_DIAMETER/2) + BLANK_BORDER);

   g.setColor(Color.BLACK);

  }

  //根據鄰接表的資訊,在鄰接結點之間連線,并線上中央繪制邊權大小。

  for (int i = 0; i < nodeNum; i++) {

   NextAdjNode temp = null;

   //如果該結點有鄰接結點,則繪制。

   if (graphAdjList[i] != null) {

    temp = graphAdjList[i].firstNode;

    while (temp != null) {

     g.drawLine(nodePosition[i][0]*cellWidth + BLANK_BORDER, nodePosition[i][1]*cellHeight + BLANK_BORDER,

       nodePosition[temp.nodeNum][0]*cellWidth + BLANK_BORDER, nodePosition[temp.nodeNum][1]*cellHeight + BLANK_BORDER);

     g.setColor(Color.RED);

     g.drawString("" + temp.edgeWeight,

        (nodePosition[i][0]*cellWidth + nodePosition[temp.nodeNum][0]*cellWidth)/2 + BLANK_BORDER,

        (nodePosition[i][1]*cellHeight + nodePosition[temp.nodeNum][1]*cellHeight)/2 + BLANK_BORDER);

     g.setColor(Color.BLACK);

     //通過連結清單的周遊,實作所有鄰接結點間的連線。

     temp = temp.nextNode;

    }

   }

  }

  //如果需要對特定路徑進行特殊顔色的繪制,則繪制。其中,是否繪制由主程式通過接口控制。

  if (drawSpecifiedPath) {

   drawPath(g, path, cellWidth, cellHeight, BLANK_BORDER);

  }

  if (drawSubGraph) {

   for (int i = 0; i < subGraph.length; i++) {

    drawPath(g, subGraph[i], cellWidth, cellHeight, BLANK_BORDER);

   }

  }

 }

 static boolean drawSpecifiedPath = false;

 static int path[] = null;

 public static void setDrawSpecifiedPath(int pa[], boolean draw) {

  path = pa;

  drawSpecifiedPath = draw;

 }

 static boolean drawSubGraph = false;

 static int subGraph[][] = null;

 public static void setDrawSubGraph(int gr[][], boolean draw) {

  subGraph = gr;

  drawSubGraph = draw;

 }

 private void drawPath(Graphics g, int path[], int cellWidth, int cellHeight, int BLANK_BORDER) {

  g.setColor(Color.GREEN);

  for (int i = 0; i < path.length-1; i++) {

   g.drawLine(nodePosition[path[i]][0]*cellWidth + BLANK_BORDER, nodePosition[path[i]][1]*cellHeight + BLANK_BORDER,

     nodePosition[path[i+1]][0]*cellWidth + BLANK_BORDER, nodePosition[path[i+1]][1]*cellHeight + BLANK_BORDER);

  }

 }

}