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);
}
}
}