Java實(shí)現(xiàn)的具有GUI的校園導(dǎo)航系統(tǒng)的完整代碼
0.寫在前面
2020-5-18更新
這個(gè)東西已經(jīng)是兩年前的了,現(xiàn)在問我具體細(xì)節(jié)我也不是很清楚了,而且現(xiàn)在review兩年前的代碼感覺寫的好爛。。。請(qǐng)大家有問題下面留言,不要加我的企鵝了,正在準(zhǔn)備考研,比較忙。
一點(diǎn)建議:
1.當(dāng)時(shí)會(huì)的比較少,對(duì)象實(shí)例化對(duì)于單純的數(shù)據(jù)查詢來說效率極低而且很蠢,我現(xiàn)在更建議使用數(shù)據(jù)庫,或者簡(jiǎn)單點(diǎn)用xmlorjson都可以,建議想寫的好一點(diǎn)的同學(xué)把里面的數(shù)據(jù)讀寫邏輯改一改,用數(shù)據(jù)庫不香嗎
2.這個(gè)是分客戶端服務(wù)端的,服務(wù)端相當(dāng)于用底層手?jǐn)]了一個(gè)相當(dāng)簡(jiǎn)單的tomcat,所有的界面都是要從Client進(jìn)去的。先開server再開Client,在注冊(cè)時(shí)以邀請(qǐng)碼判斷是否為管理員。以管理員身份進(jìn)入client之后再去添加信息。
3.如果注冊(cè)時(shí)報(bào)access is denied 在Flie的路徑下加一層文件夾,如下

小一個(gè)月沒更新博客了,主要是臨近期末,各科的大作業(yè)都下來了,今天把自己奮斗了一個(gè)禮拜的校園導(dǎo)航系統(tǒng)貼在上面,也算滿足下自己的小成就感('ᴗ' )و
實(shí)驗(yàn)要求如下:
以我校為例,設(shè)計(jì)一個(gè)校園導(dǎo)航系統(tǒng),主要為來訪的客人提供信息查詢。系統(tǒng)有兩類登陸賬號(hào),一類是游客,使用該系統(tǒng)方便校內(nèi)路線查詢;一類是管理員,可以使用該系統(tǒng)查詢校內(nèi)路線,可對(duì)校園景點(diǎn)路線可編輯。
說簡(jiǎn)單點(diǎn),就是給定一個(gè)地圖數(shù)據(jù),然后地圖上有好幾個(gè)點(diǎn),每個(gè)點(diǎn)間有距離,這個(gè)程序提供了查詢兩點(diǎn)間最短路徑的功能。當(dāng)然,你可以為他增加很多細(xì)節(jié),比如查看景點(diǎn)信息啊,后臺(tái)的管理啊等等,這些都是加分項(xiàng)。
老師推薦使用C,其實(shí)題目也是這么要求的。但是使用C有幾個(gè)比較麻煩的問題:
第一,要是只實(shí)現(xiàn)基本的功能用C的話肯定是沒什么問題,但是要是想添枝加葉的話,C的代碼就沒法看了,寫起來麻煩讀起來也難受。
第二,地圖是有地圖數(shù)據(jù)的,要是用C的話一般人都會(huì)直接printf N多行的地圖吧,這也是一個(gè)比較麻煩的事兒。
思來想去,我決定還是用Java來做這個(gè)系統(tǒng),最短路徑用迪杰斯特拉算法。
其實(shí)我還是第一次用Java做一個(gè)功能比較多的程序,既然是第一次我就想做好點(diǎn),做的與眾不同點(diǎn)。于是,我為這個(gè)程序增加了注冊(cè)登錄、邀請(qǐng)碼注冊(cè)管理員系統(tǒng)。
1.客戶端與服務(wù)端
題目中既然區(qū)分了一般用戶與管理員的權(quán)限,不如在這上面發(fā)揮一下。
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.net.Socket;
public class Client
{
private JFrame jFrame;
private JLabel accountLabel, passwdLabel, inviteLabel;
private JTextField accountText, passwdText, inviteText;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
private JPanel accountJPanel, passwdJPanel, buttonjPanel, invitejPanel;
private JButton loginButton, registButton;
static JDialog jDialog=new JDialog();
private Font font = new Font("微軟雅黑", 1, 18);
private BufferedWriter bufferedWriter;
private BufferedReader bufferedReader;
private String account, passwd;
private String tips;
private boolean isAdmin = false;
public Client()
{
init();
}
public void init()
{
jFrame = new JFrame("用戶登錄");
jFrame.setLayout(new FlowLayout());
jFrame.setBounds((toolkit.getScreenSize().width - 270) / 2, (toolkit.getScreenSize().height - 200) / 2, 270, 200);
componentInit(accountJPanel = new JPanel(), accountLabel = new JLabel(), accountText = new JTextField(), " 帳號(hào)");
componentInit(passwdJPanel = new JPanel(), passwdLabel = new JLabel(), passwdText = new JTextField(), " 密碼");
componentInit(invitejPanel = new JPanel(), inviteLabel = new JLabel(), inviteText = new JTextField(), "邀請(qǐng)碼");
loginButtonInit();
registButtonInit();
jFrame.setVisible(true);
jFrame.setResizable(false);
}
public void componentInit(JPanel jPanel, JLabel jLabel, JTextField jTextField, String str)
{
jPanel.setLayout(new FlowLayout());
jLabel.setText(str);
jLabel.setFont(font);
jTextField.setText("");
jTextField.setColumns(14);
jPanel.add(jLabel);
jPanel.add(jTextField);
jFrame.add(jPanel);
}
public void loginButtonInit()
{
loginButton = new JButton("登錄");
loginButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
try
{
Socket socket = new Socket("localhost", 10001);
//每點(diǎn)擊一次必須新建一個(gè)新的Socket,否則無法一直獲取服務(wù)端的數(shù)據(jù),具體原因不明,日后考證
sendInfo(0, socket);
if (tips.contains("成功"))
{
Home home = new Home(isAdmin);
}
} catch (IOException e1)
{
e1.printStackTrace();
}
}
});
jFrame.add(loginButton);
}
public void registButtonInit()
{
registButton = new JButton("注冊(cè)");
registButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
try
{
Socket socket = new Socket("localhost", 10001);
sendInfo(1, socket);
} catch (IOException e1)
{
e1.printStackTrace();
}
}
});
jFrame.add(registButton);
}
public void sendInfo(int code, Socket socket)//封裝了注冊(cè)登錄的共性方法
{
account = accountText.getText();
passwd = passwdText.getText();
String string;
if (code == 0)
{
string = "登錄";
}
else
string = "注冊(cè)";
try
{
bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//這里同樣要使用每次的新的Socket獲取寫入流
bufferedWriter.write(code + "\r\n");
bufferedWriter.flush();//輸出標(biāo)示,告訴服務(wù)端是登錄還是注冊(cè),登錄為0,注冊(cè)為1
bufferedWriter.write(account + "\r\n");//必須要有結(jié)束標(biāo)示,否則服務(wù)端不會(huì)停止讀取
bufferedWriter.flush(); //刷新流
bufferedWriter.write(passwd + "\r\n");
bufferedWriter.flush();
if (code == 1) //注冊(cè)的話有一個(gè)邀請(qǐng)碼,需要多傳輸一次
{
bufferedWriter.write(inviteText.getText() + "\r\n");
bufferedWriter.flush();
}
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
tips = bufferedReader.readLine();
if (tips.contains("管理員"))
{
isAdmin = true;
}
} catch (IOException e1)
{
new mDialog(string + "結(jié)果", "交換數(shù)據(jù)失?。?,jFrame);
} catch (NullPointerException e1)
{
new mDialog(string + "結(jié)果", "服務(wù)端關(guān)閉!請(qǐng)先打開服務(wù)端!",jFrame);
} finally
{
try
{
bufferedReader.close();
bufferedWriter.close();
} catch (IOException e1)
{
tips = "流關(guān)閉失?。?;
new mDialog(string + "結(jié)果", tips,jFrame);
}
new mDialog(string + "結(jié)果", tips,jFrame);
}
}
public static void main(String[] args)
{
Client client = new Client();
}
}
運(yùn)用了Socket,并與Server交換數(shù)據(jù)。
詳細(xì)解釋不再說,注釋里有,也沒什么好說的,比較基礎(chǔ)的代碼。
這里有個(gè)bug沒解決(主要是沒精力也懶得改了):注冊(cè)成功后立刻點(diǎn)擊登錄的話會(huì)無視注冊(cè)身份,統(tǒng)一使用管理員身份,重啟客戶端之后正常。我似乎隱約知道是哪里的問題?
import com.sun.source.tree.Scope;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
import java.util.Iterator;
public class Server
{
private Socket socket;
private ServerSocket serverSocket;
private String ipInfo;
private BufferedReader bufferedReader;
private BufferedOutputStream bufferedOutputStream;
private FileOutputStream fileOutputStream;
private String adminKey;
private HashSet<User> hashSet;
private String account, passwd, inviteCode;
private File infofile = new File("D://info.key");
private boolean isAdmin = false;
public Server(String adminKey)
{
this.adminKey = adminKey;
try
{
serverSocket = new ServerSocket(10001);
while (true)//循環(huán)接受Socket
{
System.out.println("服務(wù)端開啟,等待客戶端建立連接。");
socket = serverSocket.accept();
ipInfo = socket.getInetAddress().getHostAddress().toString();
System.out.println(ipInfo+" Connected! ");
new Thread(new Task(socket)).start();//并且每次接收到Socket之后,就要新建一個(gè)線程以達(dá)到多次返回?cái)?shù)據(jù)接受數(shù)據(jù)的目的
}
} catch (IOException e)
{
e.printStackTrace();
}
}
public class Task implements Runnable
{
private Socket socket;
public Task(Socket socket)
{
this.socket = socket;
}
@Override
public void run()
{
try
{
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(ipInfo);
String code = bufferedReader.readLine();//客戶端先發(fā)送一個(gè)標(biāo)志,說明是登錄還是返回
if (code.equals("0"))
{
login();
}
else
regist();
code = bufferedReader.readLine();
System.out.println(code);
} catch (IOException e)
{
e.printStackTrace();
}
}
}
public void login()
{
String result;
String status;
PrintWriter printWriter = null;
if (isAdmin)//確定找到的用戶的身份
{
status = "管理員";
}
else
status = "一般用戶";
try
{
readFile(infofile);//先讀文件
account = bufferedReader.readLine();//客戶端傳回來的帳號(hào)密碼
passwd = bufferedReader.readLine();
User user = new User(account, passwd);//封裝對(duì)象
if (isExists(user, false))//找到了
{
result = "登錄成功,身份:" + status;//傳回相關(guān)信息
}
else
{
result = "登錄失敗,請(qǐng)查驗(yàn)帳號(hào)密碼!";
}
printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println(result);//返回客戶端
} catch (IOException e)
{
e.printStackTrace();
}
}
public void regist()
{
PrintWriter printWriter = null;
String status = null;
try
{
printWriter = new PrintWriter(socket.getOutputStream(), true);
account = bufferedReader.readLine();//客戶端傳回來的帳號(hào)密碼
passwd = bufferedReader.readLine();
inviteCode = bufferedReader.readLine();
User user = new User(account, passwd);
readFile(infofile);
if (!isExists(user, true))
{
user.setAdmin(inviteCode);
if (user.isAdmin())
{
status = "管理員";
}
else
status = "一般用戶";
hashSet.add(user);//沒找到就添加進(jìn)Set
writeFile(infofile);
printWriter.println("注冊(cè)成功!身份:" + status);
}
else
{
printWriter.println("注冊(cè)失敗,用戶已存在!");
}
} catch (IOException e)
{
e.printStackTrace();
}
}
public void readFile(File file)
{
ObjectInputStream objectInputStream = null;
PrintWriter printWriter = null;
try
{
printWriter = new PrintWriter(socket.getOutputStream());
objectInputStream = new ObjectInputStream(new FileInputStream(file));//讀取密碼文件
hashSet = (HashSet) objectInputStream.readObject();//信息是以hashSet的形式存放在文件中
} catch (IOException e)
{
if (hashSet == null)
{
hashSet = new HashSet<>();//程序第一次運(yùn)行時(shí)添加進(jìn)的hashMap是null,需要新實(shí)例化一個(gè)
writeFile(infofile);//然后再寫進(jìn)去
}
} catch (ClassNotFoundException e)
{
printWriter.println("數(shù)據(jù)文件異常,請(qǐng)檢查文件!");
}
}
public void writeFile(File file)
{
PrintWriter printWriter = null;
ObjectOutputStream objectOutputStream = null;
try
{
objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));//對(duì)象寫入流
objectOutputStream.writeObject(hashSet);//將hashSet寫入文件
printWriter = new PrintWriter(socket.getOutputStream());
} catch (IOException e)
{
printWriter.println("數(shù)據(jù)文件異常,請(qǐng)檢查文件!");
}
}
public boolean isExists(User user, boolean isRegister)
{
String account = user.getAccount();
String passwd = user.getPasswd();
Iterator iterator = hashSet.iterator();
while (iterator.hasNext())
{
User stu = (User) iterator.next();
isAdmin = stu.isAdmin();
if (stu.getAccount().equals(account))//如果找到了相同用戶名
{
if (isRegister)//注冊(cè)的話
{
return true;//已經(jīng)找到了
}
return stu.getPasswd().equals(passwd);//登陸的話還要比較密碼是否相同
}
}
return false;//沒找到就是假
}
public void setAdminKey(String string)
{
adminKey = string;
}
public String getAdminKey()
{
return adminKey;
}
public static void main(String[] args)
{
Server server = new Server("KangYh is very handsome!");
}
}
class User implements Serializable
{
private String account;
private String passwd;
private boolean isAdmin = false;
public User(String account, String passwd)
{
this.account = account;
this.passwd = passwd;
}
public String getAccount()
{
return account;
}
public void setAccount(String account)
{
this.account = account;
}
public String getPasswd()
{
return passwd;
}
public void setPasswd(String passwd)
{
this.passwd = passwd;
}
public boolean isAdmin()
{
return isAdmin;
}
public void setAdmin(String string)
{
if (string.equals(new Server("KangYh is very handsome!").getAdminKey()))
{
isAdmin = true;
}
}
@Override
public int hashCode()
{
return account.hashCode() + passwd.hashCode() * 3;
}
@Override
public boolean equals(Object obj)
{
if (!(obj instanceof User))
{
return false;
}
User user = (User) obj;
return account.equals(user.account);
}
}
服務(wù)端,里面有User.class。其實(shí)可以把這個(gè)class寫出來的。把User裝入HashSet<User>,保證唯一性。
這里面踩的雷就是讀寫的換行,刷新問題。寫入完畢一次必須再寫一個(gè)換行標(biāo)記,否則另一頭是沒數(shù)據(jù)的。換行標(biāo)記可以是
bufferedWriter.write(code + "\r\n"); bufferedWriter.newLine();
兩者中的一種。
還有一點(diǎn),序列化的對(duì)象文件,官方推薦擴(kuò)展名為.ser,我用的是.obj。
放張截圖:(請(qǐng)無視邀請(qǐng)碼內(nèi)容(゜ロ゜))

2.主界面
登錄成功后就是主界面了。為了省事兒,我直接截了張圖為導(dǎo)航的地圖。這個(gè)地圖是可以更換的。(動(dòng)態(tài)更改我也不會(huì)啊(`Δ´)?。?/p>
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
public class Home
{
private JFrame jFrame;
private JPanel mapLabel;
private JLabel title, map;
private JButton admin, menu, close;
private Font titleFont = new Font("微軟雅黑", 1, 28);
private Font charFont = new Font("微軟雅黑", 1, 20);
private Toolkit toolkit = Toolkit.getDefaultToolkit();
private File pointFile = new File("D://point.obj");
private File lengthFile = new File("D://length.obj");
private File mapFile = new File("D://map.png");
private boolean isAdmin = false;
public Home(boolean isAdmin)
{
this.isAdmin = isAdmin;//確定用戶身份
init();
}
public void init()
{
jFrame = new JFrame();
jFrame.setLayout(new BorderLayout());
titleInit();//初始化標(biāo)題欄
mapInit();//初始化地圖
jFrame.setBounds((toolkit.getScreenSize().width - 700) / 2, (toolkit.getScreenSize().height - 450) / 2, 700, 450);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
admin = new JButton("管理員菜單");
admin.setFont(charFont);
admin.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new AdminMenu();
}
});
menu = new JButton("功能菜單");
menu.setFont(charFont);
menu.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new NormalMenu();
}
});
buttonPanel.add(menu);
if (isAdmin)
{
buttonPanel.add(admin);
adminTips();
}
close = new JButton("關(guān)閉");
close.setFont(charFont);
close.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
System.exit(0);
}
});
buttonPanel.add(close);
jFrame.add(buttonPanel, BorderLayout.SOUTH);
jFrame.setResizable(false);
jFrame.setVisible(true);
}
public void titleInit()
{
title = new JLabel("校園導(dǎo)航系統(tǒng)", SwingConstants.CENTER);
title.setFont(titleFont);
jFrame.add(title, BorderLayout.NORTH);//標(biāo)題文字
}
public void mapInit()
{
ImageIcon imageIcon = new ImageIcon(mapFile.getPath());
imageIcon.setImage(imageIcon.getImage().getScaledInstance(imageIcon.getIconWidth(),
imageIcon.getIconHeight(), Image.SCALE_DEFAULT));
map = new JLabel();
map.setBounds(0, 0, 690, 400);
map.setHorizontalAlignment(0);
map.setIcon(imageIcon);
mapLabel = new JPanel();
mapLabel.setSize(690, 400);
mapLabel.add(map);
jFrame.add(mapLabel, BorderLayout.CENTER);//地圖顯示
}
public void adminTips()
{
String errorTitle = "數(shù)據(jù)錯(cuò)誤!";
try
{
checkFile(mapFile, "地圖");
} catch (IOException e)
{
e.printStackTrace();
new mDialog(errorTitle, "請(qǐng)管理員先錄入地圖數(shù)據(jù)!", jFrame);
//writeMap
}
try
{
checkFile(pointFile, "景點(diǎn)");
} catch (IOException e)
{
e.printStackTrace();
new mDialog(errorTitle, "請(qǐng)管理員先錄入景點(diǎn)數(shù)據(jù)!", jFrame);
//writePoint
}
try
{
checkFile(lengthFile, "距離");
} catch (IOException e)
{
e.printStackTrace();
new mDialog(errorTitle, "請(qǐng)管理員先錄入距離數(shù)據(jù)!", jFrame);
//writeLength
}
}
public void checkFile(File file, String string) throws IOException
{
if (!file.exists() || file.length() == 0)
{
throw new IOException(string + "文件打開失??!");
}
}
}
這個(gè)沒啥坑,需要注意的是:
因?yàn)榫包c(diǎn)的數(shù)據(jù),距離數(shù)據(jù)都是以文件的形式保存的,所以一定會(huì)有IO異常。這時(shí)候就得提供一個(gè)比較友好的提示界面,并同時(shí)將異常信息輸出到控制臺(tái)上:



這個(gè)過程我,我美名其曰為“自檢”。聽著就高大上~(︶ω︶)~
然后就是主界面了。主界面的地圖我直接放了一個(gè)題目要求中的截圖。
確實(shí)比較簡(jiǎn)陋,但是該有的都有了。


兩個(gè)界面,一個(gè)是管理員的一個(gè)是一般用戶的。
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
public class AdminMenu
{
private JFrame jFrame;
private JButton createPoint, editPoint, deletePoint, createLength, editLength;
private JButton cancelButton;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
private Font font = new Font("微軟雅黑", 1, 20);
private File pointFile = new File("D://point.txt");
private File lengthFile = new File("D://length.txt");
private JFrame childFrame;
private JPanel childPanel;
private BufferedReader bufferedReader;
private BufferedWriter bufferedWriter;
public AdminMenu()
{
jFrame = new JFrame("管理員菜單");
jFrame.setBounds((toolkit.getScreenSize().width - 250) / 2, (toolkit.getScreenSize().height - 310) / 2, 250, 310);
jFrame.setLayout(new FlowLayout());
childPanel = new JPanel();
childPanel.setLayout(new FlowLayout());
cancelButton = new JButton("關(guān)閉");
childPanel.add(cancelButton);
cancelButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
jFrame.setVisible(false);
}
});
createPoint = new JButton("1.創(chuàng)建景點(diǎn)信息");
createPoint.setFont(font);
createPoint.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new CreatePoint();
}
});
editPoint = new JButton("2.修改景點(diǎn)信息");
editPoint.setFont(font);
editPoint.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new EditPoint();
}
});
deletePoint = new JButton("3.刪除景點(diǎn)信息");
deletePoint.setFont(font);
deletePoint.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new DeletePoint();
}
});
createLength = new JButton("4.創(chuàng)建道路信息");
createLength.setFont(font);
createLength.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new CreateLength(jFrame);
}
});
editLength = new JButton("5.修改道路信息");
editLength.setFont(font);
editLength.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new CreateLength(jFrame);
}
});
jFrame.add(createPoint);
jFrame.add(editPoint);
jFrame.add(deletePoint);
jFrame.add(createLength);
jFrame.add(editLength);
jFrame.add(childPanel);
jFrame.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
class NormalMenu
{
private JFrame jFrame;
private JButton visitButton, searchButton, okayButton;
private Font font = new Font("微軟雅黑", 1, 20);
private Toolkit toolkit = Toolkit.getDefaultToolkit();
public NormalMenu()
{
jFrame = new JFrame("功能菜單");
jFrame.setBounds((toolkit.getScreenSize().width - 250) / 2, (toolkit.getScreenSize().height - 200) / 2, 250, 200);
jFrame.setLayout(new FlowLayout());
visitButton = new JButton("1.瀏覽景點(diǎn)信息");
visitButton.setFont(font);
searchButton = new JButton("2.查詢最短路徑");
searchButton.setFont(font);
okayButton = new JButton("關(guān)閉");
okayButton.setFont(font);
visitButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new VisitPoint();
}
});
searchButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new SearchLength();
}
});
okayButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
jFrame.setVisible(false);
}
});
jFrame.add(visitButton);
jFrame.add(searchButton);
jFrame.add(okayButton);
jFrame.setResizable(false);
jFrame.setVisible(true);
}
}
兩個(gè)菜單的java文件。
3.管理員菜單
管理員有5個(gè)功能。

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.util.TreeMap;
public class CreatePoint
{
private File file;
private ObjectInputStream objectInputStream;
private ObjectOutputStream objectOutputStream;
private TreeMap treeMap;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
public CreatePoint()
{
try
{
file = new File("D://point.obj");
objectInputStream = new ObjectInputStream(new FileInputStream(file));
treeMap = (TreeMap) objectInputStream.readObject();
} catch (IOException e)
{
treeMap = new TreeMap();
} catch (ClassNotFoundException e)
{
}finally
{
frameInit();
}
}
public void frameInit()
{
JSeparator jSeparator = new JSeparator(SwingConstants.HORIZONTAL);
JTextArea jTextArea = new JTextArea(15, 30);
JTextField jTextField = new JTextField(20);
JFrame jFrame = new JFrame();
jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 450) / 2, 350, 450);
jFrame.setLayout(new FlowLayout());
jFrame.add(jTextField);
jFrame.add(jSeparator);
jFrame.add(jTextArea);
JButton okayButton = new JButton("確定");
JButton cancelButton = new JButton("取消");
cancelButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
jFrame.setVisible(false);
}
});
okayButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
treeMap.put(jTextField.getText(), jTextArea.getText());
try
{
objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
objectOutputStream.writeObject(treeMap);
new mDialog("成功", "數(shù)據(jù)正常保存", jFrame);
jFrame.setVisible(false);
} catch (IOException e1)
{
new mDialog("失敗", "數(shù)據(jù)異常!", jFrame);
}
}
});
jFrame.add(cancelButton);
jFrame.add(okayButton);
jFrame.setVisible(true);
}
public static void main(String[] args)
{
new CreatePoint();
}
}

其實(shí)可以把兩個(gè)框里的字體改一下。還有一個(gè),每個(gè)框前面其實(shí)應(yīng)該有個(gè)提示信息的。我嫌麻煩,后來有點(diǎn)懶得弄了。難度也不是很大,一個(gè)JLabel完事兒。
3.2 修改景點(diǎn)信息
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.util.TreeMap;
import java.util.Iterator;
import java.util.Set;
public class EditPoint
{
private JComboBox jComboBox;
private String key;
private ObjectInputStream objectInputStream;
private ObjectOutputStream objectOutputStream;
private TreeMap treeMap;
private Set<String> set;
private File file;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
JFrame jFrame;
public EditPoint()
{
try
{
file = new File("D://point.obj");
jFrame = new JFrame("");
objectInputStream = new ObjectInputStream(new FileInputStream(file));
treeMap = (TreeMap) objectInputStream.readObject();
set = treeMap.keySet();
frameInit();
} catch (IOException e)
{
new mDialog("錯(cuò)誤", "沒有文件!", jFrame);
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
public void frameInit()
{
jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 450) / 2, 350, 450);
jFrame.setLayout(new FlowLayout());
jComboBox = new JComboBox();
jComboBox.setPreferredSize(new Dimension(270, 30));
Iterator iterator = set.iterator();
while (iterator.hasNext())
{
jComboBox.addItem((String) iterator.next());
}
JTextArea jTextArea = new JTextArea(15, 30);
jTextArea.setText((String) treeMap.get(jComboBox.getSelectedItem()));
jComboBox.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
jTextArea.setText((String) treeMap.get(jComboBox.getSelectedItem()));
}
});
JButton okayButton = new JButton("確定");
JButton cancelButton = new JButton("取消");
cancelButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
jFrame.setVisible(false);
}
});
okayButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
String string = jTextArea.getText();
treeMap.put((String) jComboBox.getSelectedItem(), string);
try
{
objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
objectOutputStream.writeObject(treeMap);
new mDialog("成功", "數(shù)據(jù)成功修改", jFrame);
jFrame.setVisible(false);
} catch (IOException e1)
{
new mDialog("失敗", "數(shù)據(jù)異常!", jFrame);
}
}
});
jFrame.add(jComboBox);
jFrame.add(jTextArea);
jFrame.add(cancelButton);
jFrame.add(okayButton);
jFrame.setResizable(false);
jFrame.setVisible(true);
}
public static void main(String[] args)
{
new EditPoint();
}
}

3.3刪除景點(diǎn)信息
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.util.TreeMap;
import java.util.Iterator;
import java.util.Set;
public class DeletePoint
{
private JComboBox jComboBox;
private TreeMap treeMap;
private ObjectInputStream objectInputStream;
private ObjectOutputStream objectOutputStream;
private Set set;
private File file;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
private JFrame jFrame;
public DeletePoint()
{
try
{
jFrame = new JFrame();
file = new File("D://point.obj");
objectInputStream = new ObjectInputStream(new FileInputStream(file));
treeMap = (TreeMap) objectInputStream.readObject();
frameInit();
} catch (IOException e)
{
new mDialog("錯(cuò)誤", "沒有文件!", jFrame);
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
public void frameInit()
{
jFrame.setLayout(new FlowLayout());
jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 250) / 2, 350, 250);
jComboBox = new JComboBox();
jComboBox.setPreferredSize(new Dimension(270,30));//設(shè)置大小
jFrame.add(jComboBox);
set = treeMap.keySet();
Iterator iterator = set.iterator();
while (iterator.hasNext())
{
jComboBox.addItem((String) iterator.next());
}
JLabel jLabel = new JLabel();
jLabel.setText((String)treeMap.get(jComboBox.getSelectedItem()));//設(shè)置景點(diǎn)的相關(guān)信息顯示
jLabel.setPreferredSize(new Dimension(270,80));
jFrame.add(jLabel);
JButton cancelButton = new JButton("取消");
JButton okayButton = new JButton("確認(rèn)");
jFrame.add(cancelButton);
jFrame.add(okayButton);
jComboBox.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
jLabel.setText((String)treeMap.get(jComboBox.getSelectedItem()));
}
});
cancelButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
jFrame.setVisible(false);
}
});
okayButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
try
{
treeMap.remove((String) jComboBox.getSelectedItem());
objectOutputStream = new ObjectOutputStream(new FileOutputStream(file));
objectOutputStream.writeObject(treeMap);
new mDialog("成功", "刪除" + (String) jComboBox.getSelectedItem() + "成功!", jFrame);
jLabel.setText("");
jFrame.setVisible(false);
} catch (IOException e1)
{
new mDialog("失敗", "數(shù)據(jù)異常!", jFrame);
} catch (NullPointerException e1)
{
new mDialog("失敗", "已經(jīng)沒有景點(diǎn)信息了!", jFrame);//刪到最后就變成null了,拋異常就得處理一下
jFrame.setVisible(false);
}
}
});
jFrame.setResizable(false);
jFrame.setVisible(true);
}
public static void main(String[] args)
{
new DeletePoint();
}
}

3.4創(chuàng)建兩點(diǎn)間的距離信息
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
public class CreateLength
{
private JComboBox jComboBox1, jComboBox2;
private JTextField jTextField;
private ObjectInputStream objectInputStream1, objectInputStream2;
private ObjectOutputStream objectOutputStream;
private File lengthFile;
private File pointFile;
private double length[][];
private Toolkit toolkit = Toolkit.getDefaultToolkit();
private TreeMap treeMap;
private Set set;
private LengthInfo lengthInfo;
private ArrayList arrayList;
public CreateLength(JFrame jFrame)
{
lengthFile = new File("D://length.obj");
pointFile = new File("D://point.obj");
try
{
objectInputStream1 = new ObjectInputStream(new FileInputStream(pointFile));
} catch (IOException e)
{
new mDialog("錯(cuò)誤", "沒有景點(diǎn)信息!", jFrame);
}
try
{
objectInputStream2 = new ObjectInputStream(new FileInputStream(lengthFile));
treeMap = (TreeMap) objectInputStream1.readObject();
arrayList = (ArrayList) objectInputStream2.readObject();
} catch (IOException e)
{
lengthInfo = new LengthInfo();
lengthInfo.init();
arrayList = new ArrayList();
arrayList.add(lengthInfo);
try
{
objectOutputStream = new ObjectOutputStream(new FileOutputStream(lengthFile));
objectOutputStream.writeObject(arrayList);
objectOutputStream.flush();
} catch (IOException e1)
{
}
} catch (ClassNotFoundException e)
{
}
frameInit();
}
public void frameInit()
{
JFrame jFrame = new JFrame();
jFrame.setLayout(new FlowLayout());
jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 200) / 2, 350, 200);
jTextField = new JTextField(27);
jComboBox1 = new JComboBox();
jComboBox1.setPreferredSize(new Dimension(270, 30));
jComboBox2 = new JComboBox();
jComboBox2.setPreferredSize(new Dimension(270, 30));
set = treeMap.keySet();
Iterator iterator = set.iterator();
while (iterator.hasNext())
{
String string = (String) iterator.next();
jComboBox1.addItem(string);
jComboBox2.addItem(string);
}
int from = jComboBox1.getSelectedIndex();
int to = jComboBox2.getSelectedIndex();
lengthInfo = (LengthInfo) arrayList.get(0);
jTextField.setText(lengthInfo.getLength(from, to) + "");
jComboBox1.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
jTextField.setText(lengthInfo.getLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex()) + "");
}
});
jComboBox2.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
jTextField.setText(lengthInfo.getLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex()) + "");
}
});
JButton cancelButton = new JButton("取消");
JButton okayButton = new JButton("確認(rèn)");
cancelButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
jFrame.setVisible(false);
}
});
okayButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
try
{
double weight = Double.parseDouble(jTextField.getText().toString());
lengthInfo.editLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex(), weight);
objectOutputStream = new ObjectOutputStream(new FileOutputStream(lengthFile));
objectOutputStream.writeObject(arrayList);
new mDialog("成功", "數(shù)據(jù)修改成功!", jFrame);
jFrame.setVisible(false);
} catch (NumberFormatException e1)
{
e1.printStackTrace();
new mDialog("錯(cuò)誤", "請(qǐng)輸入正確信息!", jFrame);
} catch (IOException e1)
{
new mDialog("錯(cuò)誤", "信息寫入失??!", jFrame);
}
}
});
jFrame.add(jComboBox1);
jFrame.add(jComboBox2);
jFrame.add(jTextField);
jFrame.add(cancelButton);
jFrame.add(okayButton);
jFrame.setVisible(true);
jFrame.setResizable(false);
}
public static void main(String[] args)
{
new CreateLength(new JFrame());
}
}

這個(gè)就要說明下了,因?yàn)楫?dāng)時(shí)在寫這個(gè)模塊的時(shí)候遇到了不少問題。
第一,存儲(chǔ)結(jié)構(gòu)。
既然是選用了迪杰斯特拉算法,那么使用鄰接矩陣就是最方便的。我一開始所希望的是一個(gè)動(dòng)態(tài)的二維數(shù)組,也就是ArrayList<<ArrayList<Integer>> arraylists。但是實(shí)際上操作起來會(huì)比較麻煩。最后為了趕時(shí)間還是用的普通的二維數(shù)組int length[][],長(zhǎng)度也就固定了。這個(gè)動(dòng)態(tài)的二維數(shù)組以后再研究下。
還有就是兩個(gè)JCombobox中元素的順序問題。景點(diǎn)信息是隨時(shí)可以更改的,所以這個(gè)JCombobox中元素的個(gè)數(shù)與順序也是個(gè)問題。怎么能保證item與鄰接矩陣中的位置精確對(duì)應(yīng)?
我采取的做法,全局將景點(diǎn)的信息用TreeMap存儲(chǔ),key為景點(diǎn)的名稱,value為景點(diǎn)的詳細(xì)信息。然后使用.ketSet()來將key存入set。因?yàn)門reeMap保存我存入的相對(duì)順序。要是用HashMap順序就亂了。
既然相對(duì)順序是固定的,那么我就不需要去鏈接鄰接矩陣與jcombobox了。只需要在改變景點(diǎn)信息的時(shí)候順便將鄰接矩陣中的數(shù)據(jù)改一下就行了。這樣就可以保證對(duì)應(yīng)關(guān)系。
第二,數(shù)據(jù)的賦值
兩點(diǎn)間的距離默認(rèn)應(yīng)該是無限大,所以初始化的時(shí)候應(yīng)該是Integer.INT_MAX。自己和自己是沒有距離的,也就是0。這些工作都應(yīng)該在初始化的時(shí)候做好。
有兩點(diǎn)可以進(jìn)行優(yōu)化:一是目前的版本如果第一次輸入數(shù)據(jù),編輯框會(huì)將初始化的值顯示在上面。其實(shí)這種情況還是留白比較好。二是既然自己跟自己沒有距離,那么兩個(gè)JCombobox就不應(yīng)該出現(xiàn)一樣的值。
3.5 修改兩點(diǎn)間的距離
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
public class CreateLength
{
private JComboBox jComboBox1, jComboBox2;
private JTextField jTextField;
private ObjectInputStream objectInputStream1, objectInputStream2;
private ObjectOutputStream objectOutputStream;
private File lengthFile;
private File pointFile;
private double length[][];
private Toolkit toolkit = Toolkit.getDefaultToolkit();
private TreeMap treeMap;
private Set set;
private LengthInfo lengthInfo;
private ArrayList arrayList;
public CreateLength(JFrame jFrame)
{
lengthFile = new File("D://length.obj");
pointFile = new File("D://point.obj");
try
{
objectInputStream1 = new ObjectInputStream(new FileInputStream(pointFile));
} catch (IOException e)
{
new mDialog("錯(cuò)誤", "沒有景點(diǎn)信息!", jFrame);
}
try
{
objectInputStream2 = new ObjectInputStream(new FileInputStream(lengthFile));
treeMap = (TreeMap) objectInputStream1.readObject();
arrayList = (ArrayList) objectInputStream2.readObject();
} catch (IOException e)
{
lengthInfo = new LengthInfo();
lengthInfo.init();
arrayList = new ArrayList();
arrayList.add(lengthInfo);
try
{
objectOutputStream = new ObjectOutputStream(new FileOutputStream(lengthFile));
objectOutputStream.writeObject(arrayList);
objectOutputStream.flush();
} catch (IOException e1)
{
}
} catch (ClassNotFoundException e)
{
}
frameInit();
}
public void frameInit()
{
JFrame jFrame = new JFrame();
jFrame.setLayout(new FlowLayout());
jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 200) / 2, 350, 200);
jTextField = new JTextField(27);
jComboBox1 = new JComboBox();
jComboBox1.setPreferredSize(new Dimension(270, 30));
jComboBox2 = new JComboBox();
jComboBox2.setPreferredSize(new Dimension(270, 30));
set = treeMap.keySet();
Iterator iterator = set.iterator();
while (iterator.hasNext())
{
String string = (String) iterator.next();
jComboBox1.addItem(string);
jComboBox2.addItem(string);
}
int from = jComboBox1.getSelectedIndex();
int to = jComboBox2.getSelectedIndex();
lengthInfo = (LengthInfo) arrayList.get(0);
jTextField.setText(lengthInfo.getLength(from, to) + "");
jComboBox1.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
jTextField.setText(lengthInfo.getLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex()) + "");
}
});
jComboBox2.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
jTextField.setText(lengthInfo.getLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex()) + "");
}
});
JButton cancelButton = new JButton("取消");
JButton okayButton = new JButton("確認(rèn)");
cancelButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
jFrame.setVisible(false);
}
});
okayButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
try
{
double weight = Double.parseDouble(jTextField.getText().toString());
lengthInfo.editLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex(), weight);
objectOutputStream = new ObjectOutputStream(new FileOutputStream(lengthFile));
objectOutputStream.writeObject(arrayList);
new mDialog("成功", "數(shù)據(jù)修改成功!", jFrame);
jFrame.setVisible(false);
} catch (NumberFormatException e1)
{
e1.printStackTrace();
new mDialog("錯(cuò)誤", "請(qǐng)輸入正確信息!", jFrame);
} catch (IOException e1)
{
new mDialog("錯(cuò)誤", "信息寫入失??!", jFrame);
}
}
});
jFrame.add(jComboBox1);
jFrame.add(jComboBox2);
jFrame.add(jTextField);
jFrame.add(cancelButton);
jFrame.add(okayButton);
jFrame.setVisible(true);
jFrame.setResizable(false);
}
public static void main(String[] args)
{
new CreateLength(new JFrame());
}
}
我承認(rèn),這個(gè)我偷懶了,這個(gè)我直接用的是上一個(gè)類。不過話說過來,這倆不是差不多嘛(´_`)
4.一般用戶的操作菜單

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
class NormalMenu
{
private JFrame jFrame;
private JButton visitButton, searchButton, okayButton;
private Font font = new Font("微軟雅黑", 1, 20);
private Toolkit toolkit = Toolkit.getDefaultToolkit();
public NormalMenu()
{
jFrame = new JFrame("功能菜單");
jFrame.setBounds((toolkit.getScreenSize().width - 250) / 2, (toolkit.getScreenSize().height - 200) / 2, 250, 200);
jFrame.setLayout(new FlowLayout());
visitButton = new JButton("1.瀏覽景點(diǎn)信息");
visitButton.setFont(font);
searchButton = new JButton("2.查詢最短路徑");
searchButton.setFont(font);
okayButton = new JButton("關(guān)閉");
okayButton.setFont(font);
visitButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new VisitPoint();
}
});
searchButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
new SearchLength();
}
});
okayButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
jFrame.setVisible(false);
}
});
jFrame.add(visitButton);
jFrame.add(searchButton);
jFrame.add(okayButton);
jFrame.setResizable(false);
jFrame.setVisible(true);
}
}
4.1 瀏覽景點(diǎn)信息
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
public class VisitPoint
{
private JFrame jFrame;
private JComboBox jComboBox;
private JLabel jLabel;
private JButton okayButton;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
private File file = new File("D://point.obj");
private ObjectInputStream objectInputStream;
private TreeMap treeMap;
private Set set;
public VisitPoint()
{
try
{
objectInputStream = new ObjectInputStream(new FileInputStream(file));
jFrame = new JFrame();
} catch (IOException e)
{
new mDialog("錯(cuò)誤", "無景點(diǎn)信息文件!", jFrame);
}
frameInit();
}
public void frameInit()
{
try
{
jFrame.setLayout(new BorderLayout());
jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 250) / 2, 350, 250);
} catch (Exception e)
{
e.printStackTrace();
}
jComboBox = new JComboBox();
jComboBox.setPreferredSize(new Dimension(270,30));
try
{
treeMap = (TreeMap) objectInputStream.readObject();
set = treeMap.keySet();
} catch (IOException e)
{
} catch (ClassNotFoundException e)
{
}
Iterator iterator = set.iterator();
while (iterator.hasNext())
{
jComboBox.addItem((String) iterator.next());
}
jLabel = new JLabel();
jLabel.setPreferredSize(new Dimension(270,20));
jLabel.setFont(new Font("宋體", 1, 20));
jLabel.setText((String) treeMap.get(jComboBox.getSelectedItem()));
jComboBox.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
jLabel.setText((String) treeMap.get(jComboBox.getSelectedItem()));
}
});
okayButton = new JButton("確定");
okayButton.setFont(new Font("微軟雅黑", 1, 20));
okayButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
jFrame.setVisible(false);
}
});
jFrame.add(jComboBox,BorderLayout.NORTH);
jFrame.add(jLabel,BorderLayout.CENTER);
jFrame.add(okayButton,BorderLayout.SOUTH);
jFrame.setResizable(false);
jFrame.setVisible(true);
}
public static void main(String[] args)
{
new VisitPoint();
}
}
很簡(jiǎn)單,想不出啥需要強(qiáng)調(diào)的。
4.2查詢?nèi)我鈨牲c(diǎn)間的最短路徑
import javax.imageio.event.IIOReadProgressListener;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
public class SearchLength
{
private JFrame jFrame;
private JComboBox jComboBox1, jComboBox2;
private JLabel jLabel;
private JButton jButton;
private ObjectInputStream objectInputStream1, objectInputStream2;
private File lengthFile, pointFile;
private TreeMap treeMap;
private ArrayList arrayList;
private Set set;
private LengthInfo lengthInfo;
private Toolkit toolkit = Toolkit.getDefaultToolkit();
public SearchLength()
{
jFrame = new JFrame();
try
{
lengthFile = new File("D://length.obj");
pointFile = new File("D://point.obj");
objectInputStream1 = new ObjectInputStream(new FileInputStream(lengthFile));
objectInputStream2 = new ObjectInputStream(new FileInputStream(pointFile));
arrayList = (ArrayList) objectInputStream1.readObject();
lengthInfo = (LengthInfo) arrayList.get(0);
treeMap = (TreeMap) objectInputStream2.readObject();
} catch (IOException e)
{
new mDialog("錯(cuò)誤", "無景點(diǎn)信息!", jFrame);
} catch (ClassNotFoundException e)
{
new mDialog("錯(cuò)誤!", "文件信息錯(cuò)誤!", jFrame);
}
try
{
set = treeMap.keySet();
} catch (NullPointerException e)
{
new mDialog("錯(cuò)誤", "無道路長(zhǎng)度信息!", jFrame);
}
frameInit();
}
public void frameInit()
{
jFrame.setLayout(new FlowLayout());
jFrame.setBounds((toolkit.getScreenSize().width - 200) / 2, (toolkit.getScreenSize().height - 200) / 2, 400, 200);
jComboBox1 = new JComboBox();
jComboBox1.setPreferredSize(new Dimension(180, 30));
jComboBox1.setFont(new Font("微軟雅黑", 1, 20));
jComboBox2 = new JComboBox();
jComboBox2.setPreferredSize(new Dimension(180, 30));
jComboBox2.setFont(new Font("微軟雅黑", 1, 20));
Iterator iterator = set.iterator();
while (iterator.hasNext())
{
String string = (String) iterator.next();
jComboBox1.addItem(string);
jComboBox2.addItem(string);
}
jLabel = new JLabel();
jLabel.setPreferredSize(new Dimension(350, 80));
jLabel.setFont(new Font("微軟雅黑", 1, 20));
double str1 = lengthInfo.getMin(0, 1, treeMap);
jComboBox1.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
double str1 = lengthInfo.getMin(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex(), treeMap);
String str2 = lengthInfo.getStringBuilder();
jLabel.setText("<html><body>" + "最優(yōu)路徑: " + str2 + "<br>" + "里程: " + str1 + "m" + "<body></html>");
}
});
jComboBox2.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
double str1 = lengthInfo.getMin(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex(), treeMap);
String str2 = lengthInfo.getStringBuilder();
jLabel.setText("<html><body>" + "最優(yōu)路徑: " + str2 + "<br>" + "里程: " + str1 + "m" + "<body></html>");
}
});
jButton = new JButton("確定");
jButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
jFrame.setVisible(false);
}
});
jFrame.add(jComboBox1);
jFrame.add(jComboBox2);
jFrame.add(jLabel);
jFrame.add(jButton);
jFrame.setResizable(false);
jFrame.setVisible(true);
}
}
這里面的代碼主要就是界面。實(shí)質(zhì)的工作沒在這里面。

有個(gè)可以優(yōu)化的:就拿上面那個(gè)圖來說,這個(gè)路徑其實(shí)是反的,因?yàn)樗惴ㄗ詈笥玫氖腔厮?,stringBuilder.append()也就是從后往前拼接的。要是正的就更好了。
還有,在JLabel中居然可以使用html的格式控制,上面的“最優(yōu)路程”與“里程”的換行就是使用<br>實(shí)現(xiàn)的。
但是這里我有一個(gè)疑惑:字符串中的“<”“>”是顯示不出來的。一開始想使用“<--”來間隔,最后無奈只能用“---”了。
5.后記
程序不算完美,有很多我已經(jīng)意識(shí)到的bug和可以繼續(xù)優(yōu)化的點(diǎn)。但是好歹是自己的一次實(shí)踐,也是非常有價(jià)值的。
idea工程文件:
https://github.com/0-0MrLonely/SourceCode/tree/master/Java/NaviDemo
到此這篇關(guān)于Java實(shí)現(xiàn)的具有GUI的校園導(dǎo)航系統(tǒng)的完整代碼的文章就介紹到這了,更多相關(guān)Java校園導(dǎo)航系統(tǒng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之校園一卡通系統(tǒng)的實(shí)現(xiàn)
- Java實(shí)戰(zhàn)項(xiàng)目之校園跑腿管理系統(tǒng)的實(shí)現(xiàn)
- Java?實(shí)戰(zhàn)范例之校園二手市場(chǎng)系統(tǒng)的實(shí)現(xiàn)
- Java 實(shí)戰(zhàn)練手項(xiàng)目之校園超市管理系統(tǒng)的實(shí)現(xiàn)流程
- Java 實(shí)戰(zhàn)項(xiàng)目錘煉之校園宿舍管理系統(tǒng)的實(shí)現(xiàn)流程
- JavaWeb開發(fā)基于ssm的校園服務(wù)系統(tǒng)(實(shí)例詳解)
- Java模擬HTTP Get Post請(qǐng)求 輕松實(shí)現(xiàn)校園BBS自動(dòng)回帖
- Java基于Dijkstra算法實(shí)現(xiàn)校園導(dǎo)游程序
相關(guān)文章
SpringBoot項(xiàng)目的多文件兼多線程上傳下載
本文主要介紹了SpringBoot項(xiàng)目的多文件兼多線程上傳下載,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
Java?設(shè)計(jì)模式以虹貓藍(lán)兔的故事講解單例模式
單例模式(Singleton?Pattern)是?Java?中最簡(jiǎn)單的設(shè)計(jì)模式之一。這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式2022-03-03
spring boot實(shí)現(xiàn)profiles動(dòng)態(tài)切換的示例
Spring Boot支持在不同的環(huán)境下使用不同的配置文件,該技術(shù)非常有利于持續(xù)集成,在構(gòu)建項(xiàng)目的時(shí)候只需要使用不同的構(gòu)建命令就可以生成不同運(yùn)行環(huán)境下war包,而不需要手動(dòng)切換配置文件。2020-10-10
Java中Redis存儲(chǔ)String類型會(huì)有亂碼的問題及解決方案
在java中使用Redis存儲(chǔ)String類型的數(shù)據(jù)時(shí),會(huì)出現(xiàn)亂碼,我寫了一條存儲(chǔ)key為name,值為虎哥的字符串,然后獲取一下這個(gè)key為name的值,打印得到的值,下面通過實(shí)例代碼介紹Java中Redis存儲(chǔ)String類型會(huì)有亂碼的問題及解決方案,一起看看吧2024-04-04
Spring Boot中的WebSocketMessageBrokerConfigurer接口使用
在SpringBoot中,我們可以使用 WebSocketMessageBrokerConfigurer接口來配置WebSocket消息代理,以實(shí)現(xiàn)實(shí)時(shí)通信,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11
Java多線程異步調(diào)用性能調(diào)優(yōu)方法詳解
這篇文章主要為大家詳細(xì)介紹了Java多線程異步調(diào)用性能調(diào)優(yōu),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03

