import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
/**
* 程序入口所在类。<br>实现程序主窗口的控制以及对其他类及窗口的控制。
* @author Fe
*/
public class GraphMain {
/**
* 程序中图的邻接表的引用。
*/
GraphFromFile graph1 = new GraphFromFile(“GraphInfo//CityGraph.txt”, “GraphInfo//CityPosition.txt”, “GraphInfo//CityID.txt”);
GraphFromFile graph2 = new GraphFromFile(“GraphInfo//TestGraph1.txt”, “GraphInfo//NodePosition1.txt”, “GraphInfo//NodeID1.txt”);
GraphFromFile graph3 = new GraphFromFile(“GraphInfo//TestGraph2.txt”, “GraphInfo//NodePosition2.txt”, “GraphInfo//NodeID2.txt”);
GraphFromFile graph4 = null;
GraphAdjList graphAdjList1[] = null;
GraphAdjList graphAdjList2[] = null;
GraphAdjList graphAdjList3[] = null;
GraphAdjList graphAdjList4[] = null;
/**
* 程序主窗口。
*/
JFrame frame = new JFrame(“RouteAlgorithm”);
/**
* 程序菜单条。
*/
MenuBar menuBar = new MenuBar();
/**
* 功能选择菜单。
*/
Menu panelChoise = new Menu(“功能选择”);
/**
* 功能选择菜单项:”用Dijkstra算法求指定城市间最短路径”。
*/
MenuItem specifiedNodes = new MenuItem(“用Dijkstra路由算法求指定城市间的路由路径”);
/**
* 功能选择菜单项:”用Dijkstra算法求任意城市间最短路径”。
*/
MenuItem anyNodes = new MenuItem(“用Dijkstra路由算法求任意城市间的路由路径”);
/**
* 功能选择菜单项:”用改进的Dijkstra算法求两点间所有的最短路径”
*/
MenuItem allPath = new MenuItem(“用改进的Dijkstra路由算法求两点间所有的路由路径”);
////////////////////////////////////////////////////////////////////////////
MenuItem inputGraphFromFile = new MenuItem(“从文件输入路由节点图”);
/**
* 帮助菜单。
*/
Menu help = new Menu(“帮助”);
/**
* 帮助菜单项:”关于”。
*/
MenuItem about = new MenuItem(“关于”);
/**
* 功能”指定城市间”的面板。
*/
JPanel specifiedNodesPanel = new JPanel();
JButton showMap = new JButton(“显示地图”);
JButton exit1 = new JButton(“退出”);
CheckboxGroup cbg = new CheckboxGroup();
Checkbox showOriginalMap = new Checkbox(“完整的路由节点地图”, cbg, true);
Checkbox showPath1 = new Checkbox(“从哈尔滨到昆明的路由路径”, cbg, false);
Checkbox showPath2 = new Checkbox(“从哈尔滨到昆明中途不经过郑州的路由路径”, cbg, false);
Checkbox showPath3 = new Checkbox(“从哈尔滨到昆明中途必经过株洲的路由路径”, cbg, false);
/**
* 功能”任意城市间”的面板。
*/
JPanel anyNodesPanel = new JPanel();
JComboBox sourceNodeBox1 = null;
JComboBox targetNodeBox1 = null;
JButton showMap2 = new JButton(“显示路由路径”);
JButton exit2 = new JButton(“退出”);
ShowMap2Action showMap2Action = null;
/**
* 功能”用改进的Dijkstra算法求两点间所有的最短路径”的面板。
*/
JPanel allPathPanel = new JPanel();
String graphs[] = new String[3];
JComboBox graphChoise = null;
JComboBox sourceNodeBox2 = null;
JComboBox targetNodeBox2 = null;
JButton showMap3 = new JButton(“显示路由路径”);
JButton exit3 = new JButton(“退出”);
//////////////////////////////////////////////////////////////////////////////
FileDialog fileInputDialog = new FileDialog(frame, “FileInput”);
JPanel chooseFilePanel = new JPanel();
JTextField graphAdjListFile = new JTextField(15);
JButton adjBrowse = new JButton(“Browse”);
JTextField graphPositionFile = new JTextField(15);
JButton positionBrowse = new JButton(“Browse”);
JTextField graphIDFile = new JTextField(15);
JButton idBrowse = new JButton(“Browse”);
JButton okButton = new JButton(“确定”);
JButton resetButton = new JButton(“重置”);
/**
* 完成主程序窗口的基本布局及管理。
*/
public GraphMain() {
graphAdjList1 = graph1.getList();
graphAdjList2 = graph2.getList();
graphAdjList3 = graph3.getList();
JFrame.setDefaultLookAndFeelDecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
frame.setMenuBar(menuBar);
menuBar.add(panelChoise);
menuBar.add(help);
panelChoise.add(specifiedNodes);
panelChoise.add(anyNodes);
panelChoise.add(allPath);
panelChoise.add(inputGraphFromFile);
help.add(about);
setSpecifiedNodesPanel();
setAnyNodesPanel(graph1);
setAllPathPanel();
/////////////////////////////////////////////////////////////////////////
setChooseFilePanel();
frame.getContentPane().add(specifiedNodesPanel, BorderLayout.CENTER);
addAction();
showMap2Action = new ShowMap2Action(graph1);
frame.setSize(340, 250);
//得到屏幕的大小,即屏幕的分辨率。
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(d.width/2-160, d.height/2-200);
frame.setVisible(true);
}
/**
* 完成对功能”指定城市间”面板的基本布局及管理。
*/
private void setSpecifiedNodesPanel() {
JPanel checkboxPanel = new JPanel();
checkboxPanel.setLayout(new GridLayout(4, 1));
JPanel temp1 = new JPanel();
temp1.add(showOriginalMap);
checkboxPanel.add(temp1);
JPanel temp2 = new JPanel();
temp2.add(showPath1);
checkboxPanel.add(temp2);
JPanel temp3 = new JPanel();
temp3.add(showPath2);
checkboxPanel.add(temp3);
JPanel temp4 = new JPanel();
temp4.add(showPath3);
checkboxPanel.add(temp4);
JPanel buttonPanel = new JPanel();
buttonPanel.add(showMap);
buttonPanel.add(exit1);
specifiedNodesPanel.setLayout(new BorderLayout());
specifiedNodesPanel.add(checkboxPanel, BorderLayout.CENTER);
specifiedNodesPanel.add(buttonPanel, BorderLayout.SOUTH);
}
/////////////////////////////////////////////////////////////////////////////
/**
* 完成对功能”任意城市间”面板的基本布局及管理。
*/
private void setAnyNodesPanel(GraphFromFile graph) {
anyNodesPanel.removeAll();
sourceNodeBox1 = new JComboBox(graph.getNodeID());
JPanel sourceBoxPanel = new JPanel();
sourceBoxPanel.add(new JLabel(“请选择起始节点 “));
sourceBoxPanel.add(sourceNodeBox1);
targetNodeBox1 = new JComboBox(graph.getNodeID());
JPanel targetBoxPanel = new JPanel();
targetBoxPanel.add(new JLabel(“请选择目的节点 “));
targetBoxPanel.add(targetNodeBox1);
JPanel showMap2Panel = new JPanel();
showMap2Panel.add(showMap2);
showMap2Panel.add(exit2);
JPanel titlePanel = new JPanel();
titlePanel.add(new JLabel(“选择任意两个不同的路由节点,求出它们之间的路由路径”));
anyNodesPanel.setLayout(new GridLayout(0, 1));
anyNodesPanel.add(titlePanel);
anyNodesPanel.add(sourceBoxPanel);
anyNodesPanel.add(targetBoxPanel);
anyNodesPanel.add(showMap2Panel);
}
/**
* 完成对功能”所有路径”面板的基本布局及管理。
*/
private void setAllPathPanel() {
graphs[0] = new String(“测试图一”);
graphs[1] = new String(“测试图二”);
graphs[2] = new String(“测试图三”);
graphChoise = new JComboBox(graphs);
sourceNodeBox2 = new JComboBox(graph1.getNodeID());
targetNodeBox2 = new JComboBox(graph1.getNodeID());
allPathPanel.setLayout(new GridLayout(0,1));
JPanel titlePanel = new JPanel();
titlePanel.add(new JLabel(“用Dijkstra算法的改进算法求两节点间的所有路由路径”));
JPanel graphChoisePanel = new JPanel();
graphChoisePanel.add(new JLabel(“请选择一个测试图 “));
graphChoisePanel.add(graphChoise);
final JPanel sourceBoxPanel = new JPanel();
sourceBoxPanel.add(new JLabel(“请选择源节点 “));
sourceBoxPanel.add(sourceNodeBox2);
JPanel targetBoxPanel = new JPanel();
targetBoxPanel.add(new JLabel(“请选择目的节点 “));
targetBoxPanel.add(targetNodeBox2);
JPanel buttonPanel = new JPanel();
buttonPanel.add(showMap3);
buttonPanel.add(exit3);
allPathPanel.add(titlePanel);
allPathPanel.add(graphChoisePanel);
allPathPanel.add(sourceBoxPanel);
allPathPanel.add(targetBoxPanel);
allPathPanel.add(buttonPanel);
}
/////////////////////////////////////////////////////////////////
private void setChooseFilePanel() {
chooseFilePanel.setLayout(new GridLayout(0, 1));
JPanel titlePanel = new JPanel();
titlePanel.add(new JLabel(“请选择你需要输入的路由节点图的信息的文件路径”), BorderLayout.NORTH);
JPanel graphAdjListFilePanel = new JPanel();
graphAdjListFilePanel.add(new JLabel(“邻接链表”));
graphAdjListFilePanel.add(graphAdjListFile);
graphAdjListFilePanel.add(adjBrowse);
JPanel graphPositionFilePanel = new JPanel();
graphPositionFilePanel.add(new JLabel(“节点位置”));
graphPositionFilePanel.add(graphPositionFile);
graphPositionFilePanel.add(positionBrowse);
JPanel graphIDFilePanel = new JPanel();
graphIDFilePanel.add(new JLabel(“节点ID “));
graphIDFilePanel.add(graphIDFile);
graphIDFilePanel.add(idBrowse);
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(okButton);
buttonsPanel.add(resetButton);
chooseFilePanel.add(titlePanel);
chooseFilePanel.add(graphAdjListFilePanel);
chooseFilePanel.add(graphPositionFilePanel);
chooseFilePanel.add(graphIDFilePanel);
chooseFilePanel.add(buttonsPanel);
}
/**
* 对程序中各个组件添加监听器。以实现各个组件的具体功能。
*/
private void addAction() {
showMap.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int path[] = null;
STDijkstra std = new STDijkstra(graphAdjList1);
if (showOriginalMap.getState()) {
MapCanvas.setDrawSubGraph(null, false);
MapCanvas.setDrawSpecifiedPath(null, false);
GraphShow.setLabelText(showOriginalMap.getLabel());
GraphShow.setLengthButtonEnable(false);
}
if (showPath1.getState()) {
std.setST(0, 21);
std.go();
path = std.getPath();
MapCanvas.setDrawSubGraph(null, false);
MapCanvas.setDrawSpecifiedPath(path, true);
GraphShow.setLengthButtonInfo(0, 21, std.getDistance());
GraphShow.setLabelText(showPath1.getLabel());
GraphShow.setLengthButtonEnable(true);
}
if (showPath2.getState()) {
NextAdjNode temp = graphAdjList1[13].firstNode;
Vector queue = new Vector();
while (temp != null) {
queue.add(new Integer(temp.edgeWeight));
temp.edgeWeight = 0X0FFFFFFF;
temp = temp.nextNode;
}
std.setST(0, 21);
std.go();
path = std.getPath();
MapCanvas.setDrawSubGraph(null, false);
MapCanvas.setDrawSpecifiedPath(path, true);
GraphShow.setLengthButtonInfo(0, 21, std.getDistance());
GraphShow.setLabelText(showPath2.getLabel());
GraphShow.setLengthButtonEnable(true);
temp = graphAdjList1[13].firstNode;
while (temp != null) {
if (queue.get(0) instanceof Integer) {
temp.edgeWeight = ((Integer)queue.remove(0)).intValue();
temp = temp.nextNode;
}
}
}
if (showPath3.getState()) {
int path1[] = null;
int path2[] = null;
int distanceTemp = -1;
std.setST(0, 9);
std.go();
path1 = std.getPath();
distanceTemp = std.getDistance();
std.setST(9, 21);
std.go();
path2 = std.getPath();
distanceTemp += std.getDistance();
path = new int[(path1.length+path2.length)-1];
for (int i = 0; i < path2.length; i++) {
path[i] = path2[i];
}
for (int i = 1; i < path1.length; i++) {
path[(path2.length-1) + i] = path1[i];
}
MapCanvas.setDrawSubGraph(null, false);
MapCanvas.setDrawSpecifiedPath(path, true);
GraphShow.setLengthButtonInfo(0, 21, distanceTemp);
GraphShow.setLabelText(showPath3.getLabel());
GraphShow.setLengthButtonEnable(true);
}
new GraphShow(frame, graph1);
}
});
//////////////////////////////////////////////////////////////////////////////////////////////////
/*
showMap2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int source = -1, target = -1;
int path[] = null;
for (int i = 0; i < (graph1.getNodeID()).length; i++) {
if (graph1.getNodeID()[i].equals(sourceNodeBox1.getSelectedItem())) {
source = i;
}
if (graph1.getNodeID()[i].equals(targetNodeBox1.getSelectedItem())) {
target = i;
}
}
if (source != target) {
STDijkstra std = new STDijkstra(graphAdjList1, source, target);
std.go();
path = std.getPath();
MapCanvas.setDrawSubGraph(null, false);
MapCanvas.setDrawSpecifiedPath(path, true);
GraphShow.setLabelText(“从” + graph1.getNodeID()[source] + “到” + graph1.getNodeID()[target] + “的路由路径”);
GraphShow.setLengthButtonEnable(true);
GraphShow.setLengthButtonInfo(source, target, std.getDistance());
new GraphShow(frame, graph1);
} else {
JOptionPane.showMessageDialog(frame, “请选择不同的节点”, “WARNING”, JOptionPane.WARNING_MESSAGE);
}
}
});
*/
showMap3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
GraphFromFile graph = null;
int source = -1, target = -1;
int path[][] = null;
if (graphChoise.getSelectedItem().equals(“测试图一”)) {
graph = graph1;
} else if (graphChoise.getSelectedItem().equals(“测试图二”)) {
graph = graph2;
} else {
graph = graph3;
}
for (int i = 0; i < (graph.getNodeID()).length; i++) {
if (graph.getNodeID()[i].equals(sourceNodeBox2.getSelectedItem())) {
source = i;
}
if (graph.getNodeID()[i].equals(targetNodeBox2.getSelectedItem())) {
target = i;
}
}
if (source != target) {
STDijkstraAdv stda = new STDijkstraAdv(graph.getList(), source, target);
stda.go();
path = stda.getPath();
//MapCanvas.setDrawSpecifiedPath(path[0], true);
MapCanvas.setDrawSpecifiedPath(null, false);
MapCanvas.setDrawSubGraph(path, true);
GraphShowAdv.setSubGraph(path);
GraphShowAdv.setLabelText(“从” + graph.getNodeID()[source] + “到” + graph.getNodeID()[target] + “的路由路径”);
GraphShowAdv.setLengthButtonInfo(source, target, stda.getDistance());
GraphShowAdv.setPathNumLabel(“共有” + path.length + “条路由路径”);
new GraphShowAdv(frame, graph);
} else {
JOptionPane.showMessageDialog(frame, “请选择不同的节点”, “WARNING”, JOptionPane.WARNING_MESSAGE);
}
}
});
specifiedNodes.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
anyNodesPanel.setVisible(false);
allPathPanel.setVisible(false);
chooseFilePanel.setVisible(false);
specifiedNodesPanel.setVisible(false);
frame.getContentPane().add(specifiedNodesPanel, BorderLayout.CENTER);
specifiedNodesPanel.setVisible(true);
}
});
anyNodes.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
specifiedNodesPanel.setVisible(false);
allPathPanel.setVisible(false);
chooseFilePanel.setVisible(false);
anyNodesPanel.setVisible(false);
setAnyNodesPanel(graph1);
showMap2Action.setGraph(graph1);
frame.getContentPane().add(anyNodesPanel, BorderLayout.CENTER);
anyNodesPanel.setVisible(true);
}
});
allPath.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
anyNodesPanel.setVisible(false);
specifiedNodesPanel.setVisible(false);
chooseFilePanel.setVisible(false);
allPathPanel.setVisible(false);
frame.getContentPane().add(allPathPanel, BorderLayout.CENTER);
allPathPanel.setVisible(true);
}
});
inputGraphFromFile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
anyNodesPanel.setVisible(false);
specifiedNodesPanel.setVisible(false);
allPathPanel.setVisible(false);
chooseFilePanel.setVisible(false);
frame.getContentPane().add(chooseFilePanel, BorderLayout.CENTER);
chooseFilePanel.setVisible(true);
}
});
about.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame,
“网络原理实验路由算法/n”
+ “计科0302 岑科铁/n”
+ “计科0302 白璐”,
“About”, JOptionPane.INFORMATION_MESSAGE);
}
});
graphChoise.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if ((graphChoise.getSelectedItem()).equals(“测试图一”)) {
sourceNodeBox2.removeAllItems();
targetNodeBox2.removeAllItems();
for (int i = 0; i < graph1.getNodeNum(); i++) {
sourceNodeBox2.addItem((graph1.getNodeID())[i]);
targetNodeBox2.addItem((graph1.getNodeID())[i]);
}
}
if ((graphChoise.getSelectedItem()).equals(“测试图二”)) {
sourceNodeBox2.removeAllItems();
targetNodeBox2.removeAllItems();
for (int i = 0; i < graph2.getNodeNum(); i++) {
sourceNodeBox2.addItem((graph2.getNodeID())[i]);
targetNodeBox2.addItem((graph2.getNodeID())[i]);
}
}
if ((graphChoise.getSelectedItem()).equals(“测试图三”)) {
sourceNodeBox2.removeAllItems();
targetNodeBox2.removeAllItems();
for (int i = 0; i < graph3.getNodeNum(); i++) {
sourceNodeBox2.addItem((graph3.getNodeID())[i]);
targetNodeBox2.addItem((graph3.getNodeID())[i]);
}
}
}
});
exit1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
exit2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
exit3.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
/////////////////////////////////////////////////////////////////////
adjBrowse.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fileInputDialog.setVisible(true);
if (fileInputDialog.getFile() != null) {
graphAdjListFile.setText(fileInputDialog.getDirectory() + fileInputDialog.getFile());
}
}
});
positionBrowse.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fileInputDialog.setVisible(true);
if (fileInputDialog.getFile() != null) {
graphPositionFile.setText(fileInputDialog.getDirectory() + fileInputDialog.getFile());
}
}
});
idBrowse.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fileInputDialog.setVisible(true);
if (fileInputDialog.getFile() != null) {
graphIDFile.setText(fileInputDialog.getDirectory() + fileInputDialog.getFile());
}
}
});
resetButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
graphAdjListFile.setText(“”);
graphPositionFile.setText(“”);
graphIDFile.setText(“”);
}
});
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
graph4 = new GraphFromFile(graphAdjListFile.getText(),
graphPositionFile.getText(), graphIDFile.getText());
graphAdjList4 = graph4.getList();
setAnyNodesPanel(graph4);
showMap2Action.setGraph(graph4);
chooseFilePanel.setVisible(false);
specifiedNodesPanel.setVisible(false);
allPathPanel.setVisible(false);
anyNodesPanel.setVisible(false);
frame.getContentPane().add(anyNodesPanel, BorderLayout.CENTER);
anyNodesPanel.setVisible(true);
graphAdjListFile.setText(“”);
graphPositionFile.setText(“”);
graphIDFile.setText(“”);
}
});
}
///////////////////////////////////////////////////////////////////////////////////////////
protected class ShowMap2Action implements ActionListener {
GraphFromFile graph;
GraphAdjList[] graphAdjList;
public ShowMap2Action(GraphFromFile g) {
graph = g;
graphAdjList = g.getList();
showMap2.addActionListener(this);
}
public void setGraph(GraphFromFile g) {
graph = g;
graphAdjList = g.getList();
}
public void actionPerformed(ActionEvent e) {
int source = -1, target = -1;
int path[] = null;
for (int i = 0; i < (graph.getNodeID()).length; i++) {
if (graph.getNodeID()[i].equals(sourceNodeBox1.getSelectedItem())) {
source = i;
}
if (graph.getNodeID()[i].equals(targetNodeBox1.getSelectedItem())) {
target = i;
}
}
if (source != target) {
STDijkstraAdv stdAdv = new STDijkstraAdv(graphAdjList, source, target);
stdAdv.go();
path = stdAdv.getPath()[0];
MapCanvas.setDrawSubGraph(null, false);
MapCanvas.setDrawSpecifiedPath(path, true);
GraphShow.setLabelText(“从” + graph.getNodeID()[source] + “到” + graph.getNodeID()[target] + “的路由路径”);
GraphShow.setLengthButtonEnable(true);
GraphShow.setLengthButtonInfo(source, target, stdAdv.getDistance());
new GraphShow(frame, graph);
} else {
JOptionPane.showMessageDialog(frame, “请选择不同的节点”, “WARNING”, JOptionPane.WARNING_MESSAGE);
}
}
}
/**
* 程序入口函数。
* @param args
* 程序参数 在本程序中未使用
*/
public static void main(String args[]) {
new GraphMain();
}
}