Java实现的具有GUI的校园导航系统
0.写在前面
2020-5-18 更新
这个东西已经是两年前的了,现在问我具体细节我也不是很清楚了,而且现在review两年前的代码感觉写的好烂。。。请大家有问题下面留言,不要加我的企鹅了,正在准备考研,比较忙。
一点建议:1.当时会的比较少,对象实例化对于单纯的数据查询来说效率极低而且很蠢,我现在更建议使用数据库,或者简单点用xml or json都可以,建议想写的好一点的同学把里面的数据读写逻辑改一改,用数据库不香吗
2.这个是分客户端服务端的,服务端相当于用底层手撸了一个相当简单的tomcat,所有的界面都是要从Client进去的。先开server再开Client,在注册时以邀请码判断是否为管理员。以管理员身份进入client之后再去添加信息。
3.如果注册时报access is denied 在Flie的路径下加一层文件夹,如下
小一个月没更新博客了,主要是临近期末,各科的大作业都下来了,今天把自己奋斗了一个礼拜的校园导航系统贴在上面,也算满足下自己的小成就感
2.主界面
登录成功后就是主界面了。为了省事儿,我直接截了张图为导航的地图。这个地图是可以更换的。(动态更改我也不会啊(`Δ′)!)
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.MouseAdapter; 4 import java.awt.event.MouseEvent; 5 import java.io.*; 6 7 8 public class Home 9 { 10 private JFrame jFrame; 11 private JPanel mapLabel; 12 private JLabel title, map; 13 private JButton admin, menu, close; 14 private Font titleFont = new Font("微软雅黑", 1, 28); 15 private Font charFont = new Font("微软雅黑", 1, 20); 16 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 17 18 private File pointFile = new File("D://point.obj"); 19 private File lengthFile = new File("D://length.obj"); 20 private File mapFile = new File("D://map.png"); 21 22 private boolean isAdmin = false; 23 24 public Home(boolean isAdmin) 25 { 26 this.isAdmin = isAdmin;//确定用户身份 27 init(); 28 } 29 30 public void init() 31 { 32 jFrame = new JFrame(); 33 jFrame.setLayout(new BorderLayout()); 34 35 titleInit();//初始化标题栏 36 mapInit();//初始化地图 37 38 jFrame.setBounds((toolkit.getScreenSize().width - 700) / 2, (toolkit.getScreenSize().height - 450) / 2, 700, 450); 39 40 JPanel buttonPanel = new JPanel(); 41 buttonPanel.setLayout(new FlowLayout()); 42 43 admin = new JButton("管理员菜单"); 44 admin.setFont(charFont); 45 admin.addMouseListener(new MouseAdapter() 46 { 47 @Override 48 public void mouseClicked(MouseEvent e) 49 { 50 new AdminMenu(); 51 } 52 }); 53 54 menu = new JButton("功能菜单"); 55 menu.setFont(charFont); 56 menu.addMouseListener(new MouseAdapter() 57 { 58 @Override 59 public void mouseClicked(MouseEvent e) 60 { 61 new NormalMenu(); 62 } 63 }); 64 buttonPanel.add(menu); 65 if (isAdmin) 66 { 67 buttonPanel.add(admin); 68 adminTips(); 69 } 70 close = new JButton("关闭"); 71 close.setFont(charFont); 72 close.addMouseListener(new MouseAdapter() 73 { 74 @Override 75 public void mouseClicked(MouseEvent e) 76 { 77 System.exit(0); 78 } 79 }); 80 buttonPanel.add(close); 81 82 jFrame.add(buttonPanel, BorderLayout.SOUTH); 83 84 jFrame.setResizable(false); 85 jFrame.setVisible(true); 86 } 87 88 public void titleInit() 89 { 90 title = new JLabel("校园导航系统", SwingConstants.CENTER); 91 title.setFont(titleFont); 92 jFrame.add(title, BorderLayout.NORTH);//标题文字 93 } 94 95 public void mapInit() 96 { 97 ImageIcon imageIcon = new ImageIcon(mapFile.getPath()); 98 imageIcon.setImage(imageIcon.getImage().getScaledInstance(imageIcon.getIconWidth(), 99 imageIcon.getIconHeight(), Image.SCALE_DEFAULT)); 100 map = new JLabel(); 101 map.setBounds(0, 0, 690, 400); 102 map.setHorizontalAlignment(0); 103 map.setIcon(imageIcon); 104 mapLabel = new JPanel(); 105 mapLabel.setSize(690, 400); 106 mapLabel.add(map); 107 jFrame.add(mapLabel, BorderLayout.CENTER);//地图显示 108 } 109 110 111 public void adminTips() 112 { 113 String errorTitle = "数据错误!"; 114 try 115 { 116 checkFile(mapFile, "地图"); 117 } catch (IOException e) 118 { 119 e.printStackTrace(); 120 new mDialog(errorTitle, "请管理员先录入地图数据!", jFrame); 121 //writeMap 122 } 123 try 124 { 125 checkFile(pointFile, "景点"); 126 127 } catch (IOException e) 128 { 129 e.printStackTrace(); 130 new mDialog(errorTitle, "请管理员先录入景点数据!", jFrame); 131 //writePoint 132 } 133 try 134 { 135 checkFile(lengthFile, "距离"); 136 137 } catch (IOException e) 138 { 139 e.printStackTrace(); 140 new mDialog(errorTitle, "请管理员先录入距离数据!", jFrame); 141 //writeLength 142 } 143 } 144 145 public void checkFile(File file, String string) throws IOException 146 { 147 if (!file.exists() || file.length() == 0) 148 { 149 throw new IOException(string + "文件打开失败!"); 150 } 151 } 152 153 154 }Home.java
这个没啥坑,需要注意的是:
因为景点的数据,距离数据都是以文件的形式保存的,所以一定会有IO异常。这时候就得提供一个比较友好的提示界面,并同时将异常信息输出到控制台上:
这个过程我,我美名其曰为“自检”。听着就高大上~(︶ω︶)~
然后就是主界面了。主界面的地图我直接放了一个题目要求中的截图。
确实比较简陋,但是该有的都有了。
两个界面,一个是管理员的一个是一般用户的。
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.MouseAdapter; 4 import java.awt.event.MouseEvent; 5 import java.io.BufferedReader; 6 import java.io.BufferedWriter; 7 import java.io.File; 8 9 public class AdminMenu 10 { 11 private JFrame jFrame; 12 private JButton createPoint, editPoint, deletePoint, createLength, editLength; 13 private JButton cancelButton; 14 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 15 private Font font = new Font("微软雅黑", 1, 20); 16 private File pointFile = new File("D://point.txt"); 17 private File lengthFile = new File("D://length.txt"); 18 private JFrame childFrame; 19 private JPanel childPanel; 20 21 private BufferedReader bufferedReader; 22 private BufferedWriter bufferedWriter; 23 24 25 public AdminMenu() 26 { 27 jFrame = new JFrame("管理员菜单"); 28 jFrame.setBounds((toolkit.getScreenSize().width - 250) / 2, (toolkit.getScreenSize().height - 310) / 2, 250, 310); 29 jFrame.setLayout(new FlowLayout()); 30 31 childPanel = new JPanel(); 32 childPanel.setLayout(new FlowLayout()); 33 cancelButton = new JButton("关闭"); 34 childPanel.add(cancelButton); 35 36 37 cancelButton.addMouseListener(new MouseAdapter() 38 { 39 @Override 40 public void mouseClicked(MouseEvent e) 41 { 42 jFrame.setVisible(false); 43 } 44 }); 45 46 createPoint = new JButton("1.创建景点信息"); 47 createPoint.setFont(font); 48 createPoint.addMouseListener(new MouseAdapter() 49 { 50 @Override 51 public void mouseClicked(MouseEvent e) 52 { 53 new CreatePoint(); 54 } 55 }); 56 57 editPoint = new JButton("2.修改景点信息"); 58 editPoint.setFont(font); 59 editPoint.addMouseListener(new MouseAdapter() 60 { 61 @Override 62 public void mouseClicked(MouseEvent e) 63 { 64 new EditPoint(); 65 } 66 }); 67 68 deletePoint = new JButton("3.删除景点信息"); 69 deletePoint.setFont(font); 70 deletePoint.addMouseListener(new MouseAdapter() 71 { 72 @Override 73 public void mouseClicked(MouseEvent e) 74 { 75 new DeletePoint(); 76 } 77 }); 78 79 createLength = new JButton("4.创建道路信息"); 80 createLength.setFont(font); 81 createLength.addMouseListener(new MouseAdapter() 82 { 83 @Override 84 public void mouseClicked(MouseEvent e) 85 { 86 new CreateLength(jFrame); 87 } 88 }); 89 90 editLength = new JButton("5.修改道路信息"); 91 editLength.setFont(font); 92 editLength.addMouseListener(new MouseAdapter() 93 { 94 @Override 95 public void mouseClicked(MouseEvent e) 96 { 97 new CreateLength(jFrame); 98 } 99 }); 100 101 jFrame.add(createPoint); 102 jFrame.add(editPoint); 103 jFrame.add(deletePoint); 104 jFrame.add(createLength); 105 jFrame.add(editLength); 106 jFrame.add(childPanel); 107 jFrame.setVisible(true); 108 } 109 110 111 }AdminMenu.java
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.MouseAdapter; 4 import java.awt.event.MouseEvent; 5 6 class NormalMenu 7 { 8 9 private JFrame jFrame; 10 private JButton visitButton, searchButton, okayButton; 11 private Font font = new Font("微软雅黑", 1, 20); 12 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 13 14 public NormalMenu() 15 { 16 jFrame = new JFrame("功能菜单"); 17 jFrame.setBounds((toolkit.getScreenSize().width - 250) / 2, (toolkit.getScreenSize().height - 200) / 2, 250, 200); 18 jFrame.setLayout(new FlowLayout()); 19 visitButton = new JButton("1.浏览景点信息"); 20 visitButton.setFont(font); 21 searchButton = new JButton("2.查询最短路径"); 22 searchButton.setFont(font); 23 okayButton = new JButton("关闭"); 24 okayButton.setFont(font); 25 26 27 visitButton.addMouseListener(new MouseAdapter() 28 { 29 @Override 30 public void mouseClicked(MouseEvent e) 31 { 32 new VisitPoint(); 33 } 34 }); 35 36 searchButton.addMouseListener(new MouseAdapter() 37 { 38 @Override 39 public void mouseClicked(MouseEvent e) 40 { 41 new SearchLength(); 42 } 43 }); 44 45 okayButton.addMouseListener(new MouseAdapter() 46 { 47 @Override 48 public void mouseClicked(MouseEvent e) 49 { 50 jFrame.setVisible(false); 51 } 52 }); 53 54 jFrame.add(visitButton); 55 jFrame.add(searchButton); 56 jFrame.add(okayButton); 57 jFrame.setResizable(false); 58 jFrame.setVisible(true); 59 60 } 61 62 }NormalMenu.java
两个菜单的java文件。
3.管理员菜单
管理员有5个功能。
3.1创建景点信息
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.MouseAdapter; 4 import java.awt.event.MouseEvent; 5 import java.io.*; 6 import java.util.TreeMap; 7 8 public class CreatePoint 9 { 10 private File file; 11 private ObjectInputStream objectInputStream; 12 private ObjectOutputStream objectOutputStream; 13 private TreeMap treeMap; 14 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 15 16 public CreatePoint() 17 { 18 try 19 { 20 file = new File("D://point.obj"); 21 objectInputStream = new ObjectInputStream(new FileInputStream(file)); 22 treeMap = (TreeMap) objectInputStream.readObject(); 23 } catch (IOException e) 24 { 25 treeMap = new TreeMap(); 26 } catch (ClassNotFoundException e) 27 { 28 }finally 29 { 30 frameInit(); 31 } 32 33 } 34 35 public void frameInit() 36 { 37 JSeparator jSeparator = new JSeparator(SwingConstants.HORIZONTAL); 38 JTextArea jTextArea = new JTextArea(15, 30); 39 JTextField jTextField = new JTextField(20); 40 41 JFrame jFrame = new JFrame(); 42 jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 450) / 2, 350, 450); 43 jFrame.setLayout(new FlowLayout()); 44 45 jFrame.add(jTextField); 46 jFrame.add(jSeparator); 47 jFrame.add(jTextArea); 48 49 JButton okayButton = new JButton("确定"); 50 JButton cancelButton = new JButton("取消"); 51 52 cancelButton.addMouseListener(new MouseAdapter() 53 { 54 @Override 55 public void mouseClicked(MouseEvent e) 56 { 57 jFrame.setVisible(false); 58 } 59 }); 60 okayButton.addMouseListener(new MouseAdapter() 61 { 62 @Override 63 public void mouseClicked(MouseEvent e) 64 { 65 treeMap.put(jTextField.getText(), jTextArea.getText()); 66 try 67 { 68 objectOutputStream = new ObjectOutputStream(new FileOutputStream(file)); 69 objectOutputStream.writeObject(treeMap); 70 new mDialog("成功", "数据正常保存", jFrame); 71 jFrame.setVisible(false); 72 } catch (IOException e1) 73 { 74 new mDialog("失败", "数据异常!", jFrame); 75 } 76 } 77 }); 78 jFrame.add(cancelButton); 79 jFrame.add(okayButton); 80 jFrame.setVisible(true); 81 82 83 } 84 85 public static void main(String[] args) 86 { 87 new CreatePoint(); 88 } 89 90 91 }CreatePoint.java
其实可以把两个框里的字体改一下。还有一个,每个框前面其实应该有个提示信息的。我嫌麻烦,后来有点懒得弄了。难度也不是很大,一个JLabel完事儿。
3.2 修改景点信息
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.ItemEvent; 4 import java.awt.event.ItemListener; 5 import java.awt.event.MouseAdapter; 6 import java.awt.event.MouseEvent; 7 import java.io.*; 8 import java.util.TreeMap; 9 import java.util.Iterator; 10 import java.util.Set; 11 12 public class EditPoint 13 { 14 private JComboBox jComboBox; 15 private String key; 16 private ObjectInputStream objectInputStream; 17 private ObjectOutputStream objectOutputStream; 18 private TreeMap treeMap; 19 private SetEditPoint.javaset; 20 private File file; 21 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 22 JFrame jFrame; 23 24 public EditPoint() 25 { 26 try 27 { 28 file = new File("D://point.obj"); 29 jFrame = new JFrame(""); 30 objectInputStream = new ObjectInputStream(new FileInputStream(file)); 31 treeMap = (TreeMap) objectInputStream.readObject(); 32 set = treeMap.keySet(); 33 frameInit(); 34 } catch (IOException e) 35 { 36 new mDialog("错误", "没有文件!", jFrame); 37 e.printStackTrace(); 38 } catch (ClassNotFoundException e) 39 { 40 e.printStackTrace(); 41 } 42 } 43 44 public void frameInit() 45 { 46 47 jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 450) / 2, 350, 450); 48 49 jFrame.setLayout(new FlowLayout()); 50 51 jComboBox = new JComboBox(); 52 jComboBox.setPreferredSize(new Dimension(270, 30)); 53 Iterator iterator = set.iterator(); 54 while (iterator.hasNext()) 55 { 56 jComboBox.addItem((String) iterator.next()); 57 } 58 JTextArea jTextArea = new JTextArea(15, 30); 59 jTextArea.setText((String) treeMap.get(jComboBox.getSelectedItem())); 60 61 jComboBox.addItemListener(new ItemListener() 62 { 63 @Override 64 public void itemStateChanged(ItemEvent e) 65 { 66 jTextArea.setText((String) treeMap.get(jComboBox.getSelectedItem())); 67 } 68 }); 69 JButton okayButton = new JButton("确定"); 70 JButton cancelButton = new JButton("取消"); 71 cancelButton.addMouseListener(new MouseAdapter() 72 { 73 @Override 74 public void mouseClicked(MouseEvent e) 75 { 76 jFrame.setVisible(false); 77 } 78 }); 79 okayButton.addMouseListener(new MouseAdapter() 80 { 81 @Override 82 public void mouseClicked(MouseEvent e) 83 { 84 String string = jTextArea.getText(); 85 treeMap.put((String) jComboBox.getSelectedItem(), string); 86 try 87 { 88 objectOutputStream = new ObjectOutputStream(new FileOutputStream(file)); 89 objectOutputStream.writeObject(treeMap); 90 new mDialog("成功", "数据成功修改", jFrame); 91 jFrame.setVisible(false); 92 } catch (IOException e1) 93 { 94 new mDialog("失败", "数据异常!", jFrame); 95 } 96 97 } 98 }); 99 jFrame.add(jComboBox); 100 jFrame.add(jTextArea); 101 jFrame.add(cancelButton); 102 jFrame.add(okayButton); 103 jFrame.setResizable(false); 104 jFrame.setVisible(true); 105 } 106 107 public static void main(String[] args) 108 { 109 new EditPoint(); 110 } 111 }
3.3 删除景点信息
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.ItemEvent; 4 import java.awt.event.ItemListener; 5 import java.awt.event.MouseAdapter; 6 import java.awt.event.MouseEvent; 7 import java.io.*; 8 import java.util.TreeMap; 9 import java.util.Iterator; 10 import java.util.Set; 11 12 public class DeletePoint 13 { 14 private JComboBox jComboBox; 15 private TreeMap treeMap; 16 private ObjectInputStream objectInputStream; 17 private ObjectOutputStream objectOutputStream; 18 private Set set; 19 private File file; 20 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 21 private JFrame jFrame; 22 23 public DeletePoint() 24 { 25 try 26 { 27 jFrame = new JFrame(); 28 file = new File("D://point.obj"); 29 objectInputStream = new ObjectInputStream(new FileInputStream(file)); 30 treeMap = (TreeMap) objectInputStream.readObject(); 31 frameInit(); 32 } catch (IOException e) 33 { 34 new mDialog("错误", "没有文件!", jFrame); 35 e.printStackTrace(); 36 37 } catch (ClassNotFoundException e) 38 { 39 e.printStackTrace(); 40 } 41 } 42 43 public void frameInit() 44 { 45 jFrame.setLayout(new FlowLayout()); 46 jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 250) / 2, 350, 250); 47 48 jComboBox = new JComboBox(); 49 jComboBox.setPreferredSize(new Dimension(270,30));//设置大小 50 jFrame.add(jComboBox); 51 set = treeMap.keySet(); 52 Iterator iterator = set.iterator(); 53 while (iterator.hasNext()) 54 { 55 jComboBox.addItem((String) iterator.next()); 56 } 57 58 JLabel jLabel = new JLabel(); 59 jLabel.setText((String)treeMap.get(jComboBox.getSelectedItem()));//设置景点的相关信息显示 60 jLabel.setPreferredSize(new Dimension(270,80)); 61 jFrame.add(jLabel); 62 63 JButton cancelButton = new JButton("取消"); 64 JButton okayButton = new JButton("确认"); 65 jFrame.add(cancelButton); 66 jFrame.add(okayButton); 67 68 69 jComboBox.addItemListener(new ItemListener() 70 { 71 @Override 72 public void itemStateChanged(ItemEvent e) 73 { 74 jLabel.setText((String)treeMap.get(jComboBox.getSelectedItem())); 75 } 76 }); 77 78 cancelButton.addMouseListener(new MouseAdapter() 79 { 80 @Override 81 public void mouseClicked(MouseEvent e) 82 { 83 jFrame.setVisible(false); 84 } 85 }); 86 okayButton.addMouseListener(new MouseAdapter() 87 { 88 @Override 89 public void mouseClicked(MouseEvent e) 90 { 91 try 92 { 93 treeMap.remove((String) jComboBox.getSelectedItem()); 94 95 objectOutputStream = new ObjectOutputStream(new FileOutputStream(file)); 96 objectOutputStream.writeObject(treeMap); 97 new mDialog("成功", "删除" + (String) jComboBox.getSelectedItem() + "成功!", jFrame); 98 jLabel.setText(""); 99 jFrame.setVisible(false); 100 } catch (IOException e1) 101 { 102 new mDialog("失败", "数据异常!", jFrame); 103 } catch (NullPointerException e1) 104 { 105 new mDialog("失败", "已经没有景点信息了!", jFrame);//删到最后就变成null了,抛异常就得处理一下 106 jFrame.setVisible(false); 107 } 108 } 109 }); 110 111 jFrame.setResizable(false); 112 jFrame.setVisible(true); 113 } 114 115 public static void main(String[] args) 116 { 117 new DeletePoint(); 118 } 119 }DeletePoint.java
3.4 创建两点间的距离信息
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.ItemEvent; 4 import java.awt.event.ItemListener; 5 import java.awt.event.MouseAdapter; 6 import java.awt.event.MouseEvent; 7 import java.io.*; 8 import java.util.ArrayList; 9 import java.util.Iterator; 10 import java.util.Set; 11 import java.util.TreeMap; 12 13 public class CreateLength 14 { 15 private JComboBox jComboBox1, jComboBox2; 16 private JTextField jTextField; 17 private ObjectInputStream objectInputStream1, objectInputStream2; 18 private ObjectOutputStream objectOutputStream; 19 private File lengthFile; 20 private File pointFile; 21 private double length[][]; 22 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 23 24 private TreeMap treeMap; 25 private Set set; 26 27 private LengthInfo lengthInfo; 28 private ArrayList arrayList; 29 30 public CreateLength(JFrame jFrame) 31 { 32 33 lengthFile = new File("D://length.obj"); 34 pointFile = new File("D://point.obj"); 35 try 36 { 37 objectInputStream1 = new ObjectInputStream(new FileInputStream(pointFile)); 38 } catch (IOException e) 39 { 40 new mDialog("错误", "没有景点信息!", jFrame); 41 } 42 43 44 try 45 { 46 objectInputStream2 = new ObjectInputStream(new FileInputStream(lengthFile)); 47 treeMap = (TreeMap) objectInputStream1.readObject(); 48 arrayList = (ArrayList) objectInputStream2.readObject(); 49 } catch (IOException e) 50 { 51 lengthInfo = new LengthInfo(); 52 lengthInfo.init(); 53 arrayList = new ArrayList(); 54 arrayList.add(lengthInfo); 55 try 56 { 57 objectOutputStream = new ObjectOutputStream(new FileOutputStream(lengthFile)); 58 objectOutputStream.writeObject(arrayList); 59 objectOutputStream.flush(); 60 } catch (IOException e1) 61 { 62 63 } 64 } catch (ClassNotFoundException e) 65 { 66 67 } 68 69 frameInit(); 70 71 72 } 73 74 public void frameInit() 75 { 76 JFrame jFrame = new JFrame(); 77 jFrame.setLayout(new FlowLayout()); 78 jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 200) / 2, 350, 200); 79 80 jTextField = new JTextField(27); 81 jComboBox1 = new JComboBox(); 82 jComboBox1.setPreferredSize(new Dimension(270, 30)); 83 jComboBox2 = new JComboBox(); 84 jComboBox2.setPreferredSize(new Dimension(270, 30)); 85 86 set = treeMap.keySet(); 87 Iterator iterator = set.iterator(); 88 while (iterator.hasNext()) 89 { 90 String string = (String) iterator.next(); 91 jComboBox1.addItem(string); 92 jComboBox2.addItem(string); 93 } 94 95 int from = jComboBox1.getSelectedIndex(); 96 int to = jComboBox2.getSelectedIndex(); 97 98 lengthInfo = (LengthInfo) arrayList.get(0); 99 jTextField.setText(lengthInfo.getLength(from, to) + ""); 100 jComboBox1.addItemListener(new ItemListener() 101 { 102 @Override 103 public void itemStateChanged(ItemEvent e) 104 { 105 jTextField.setText(lengthInfo.getLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex()) + ""); 106 } 107 }); 108 jComboBox2.addItemListener(new ItemListener() 109 { 110 @Override 111 public void itemStateChanged(ItemEvent e) 112 { 113 jTextField.setText(lengthInfo.getLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex()) + ""); 114 } 115 }); 116 117 JButton cancelButton = new JButton("取消"); 118 JButton okayButton = new JButton("确认"); 119 120 121 cancelButton.addMouseListener(new MouseAdapter() 122 { 123 @Override 124 public void mouseClicked(MouseEvent e) 125 { 126 jFrame.setVisible(false); 127 } 128 }); 129 okayButton.addMouseListener(new MouseAdapter() 130 { 131 @Override 132 public void mouseClicked(MouseEvent e) 133 { 134 try 135 { 136 double weight = Double.parseDouble(jTextField.getText().toString()); 137 lengthInfo.editLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex(), weight); 138 objectOutputStream = new ObjectOutputStream(new FileOutputStream(lengthFile)); 139 objectOutputStream.writeObject(arrayList); 140 141 new mDialog("成功", "数据修改成功!", jFrame); 142 jFrame.setVisible(false); 143 } catch (NumberFormatException e1) 144 { 145 e1.printStackTrace(); 146 new mDialog("错误", "请输入正确信息!", jFrame); 147 } catch (IOException e1) 148 { 149 new mDialog("错误", "信息写入失败!", jFrame); 150 } 151 152 153 } 154 }); 155 156 jFrame.add(jComboBox1); 157 jFrame.add(jComboBox2); 158 jFrame.add(jTextField); 159 jFrame.add(cancelButton); 160 jFrame.add(okayButton); 161 jFrame.setVisible(true); 162 jFrame.setResizable(false); 163 } 164 165 public static void main(String[] args) 166 { 167 new CreateLength(new JFrame()); 168 } 169 170 }CreateLength.java
这个就要说明下了,因为当时在写这个模块的时候遇到了不少问题。
第一,存储结构。
既然是选用了迪杰斯特拉算法,那么使用邻接矩阵就是最方便的。我一开始所希望的是一个动态的二维数组,也就是ArrayList<
还有就是两个JCombobox中元素的顺序问题。景点信息是随时可以更改的,所以这个JCombobox中元素的个数与顺序也是个问题。怎么能保证item与邻接矩阵中的位置精确对应?
我采取的做法,全局将景点的信息用TreeMap存储,key为景点的名称,value为景点的详细信息。然后使用.ketSet()来将key存入set。因为TreeMap保存我存入的相对顺序。要是用HashMap顺序就乱了。
既然相对顺序是固定的,那么我就不需要去链接邻接矩阵与jcombobox了。只需要在改变景点信息的时候顺便将邻接矩阵中的数据改一下就行了。这样就可以保证对应关系。
第二,数据的赋值
两点间的距离默认应该是无限大,所以初始化的时候应该是Integer.INT_MAX。自己和自己是没有距离的,也就是0。这些工作都应该在初始化的时候做好。
有两点可以进行优化:一是目前的版本如果第一次输入数据,编辑框会将初始化的值显示在上面。其实这种情况还是留白比较好。二是既然自己跟自己没有距离,那么两个JCombobox就不应该出现一样的值。
3.5 修改两点间的距离
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.ItemEvent; 4 import java.awt.event.ItemListener; 5 import java.awt.event.MouseAdapter; 6 import java.awt.event.MouseEvent; 7 import java.io.*; 8 import java.util.ArrayList; 9 import java.util.Iterator; 10 import java.util.Set; 11 import java.util.TreeMap; 12 13 public class CreateLength 14 { 15 private JComboBox jComboBox1, jComboBox2; 16 private JTextField jTextField; 17 private ObjectInputStream objectInputStream1, objectInputStream2; 18 private ObjectOutputStream objectOutputStream; 19 private File lengthFile; 20 private File pointFile; 21 private double length[][]; 22 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 23 24 private TreeMap treeMap; 25 private Set set; 26 27 private LengthInfo lengthInfo; 28 private ArrayList arrayList; 29 30 public CreateLength(JFrame jFrame) 31 { 32 33 lengthFile = new File("D://length.obj"); 34 pointFile = new File("D://point.obj"); 35 try 36 { 37 objectInputStream1 = new ObjectInputStream(new FileInputStream(pointFile)); 38 } catch (IOException e) 39 { 40 new mDialog("错误", "没有景点信息!", jFrame); 41 } 42 43 try 44 { 45 objectInputStream2 = new ObjectInputStream(new FileInputStream(lengthFile)); 46 treeMap = (TreeMap) objectInputStream1.readObject(); 47 arrayList = (ArrayList) objectInputStream2.readObject(); 48 } catch (IOException e) 49 { 50 lengthInfo = new LengthInfo(); 51 lengthInfo.init(); 52 arrayList = new ArrayList(); 53 arrayList.add(lengthInfo); 54 try 55 { 56 objectOutputStream = new ObjectOutputStream(new FileOutputStream(lengthFile)); 57 objectOutputStream.writeObject(arrayList); 58 objectOutputStream.flush(); 59 } catch (IOException e1) 60 { 61 62 } 63 } catch (ClassNotFoundException e) 64 { 65 66 } 67 68 frameInit(); 69 70 71 } 72 73 public void frameInit() 74 { 75 JFrame jFrame = new JFrame(); 76 jFrame.setLayout(new FlowLayout()); 77 jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 200) / 2, 350, 200); 78 79 jTextField = new JTextField(27); 80 jComboBox1 = new JComboBox(); 81 jComboBox1.setPreferredSize(new Dimension(270, 30)); 82 jComboBox2 = new JComboBox(); 83 jComboBox2.setPreferredSize(new Dimension(270, 30)); 84 85 set = treeMap.keySet(); 86 Iterator iterator = set.iterator(); 87 while (iterator.hasNext()) 88 { 89 String string = (String) iterator.next(); 90 jComboBox1.addItem(string); 91 jComboBox2.addItem(string); 92 } 93 94 int from = jComboBox1.getSelectedIndex(); 95 int to = jComboBox2.getSelectedIndex(); 96 97 lengthInfo = (LengthInfo) arrayList.get(0); 98 jTextField.setText(lengthInfo.getLength(from, to) + ""); 99 jComboBox1.addItemListener(new ItemListener() 100 { 101 @Override 102 public void itemStateChanged(ItemEvent e) 103 { 104 jTextField.setText(lengthInfo.getLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex()) + ""); 105 } 106 }); 107 jComboBox2.addItemListener(new ItemListener() 108 { 109 @Override 110 public void itemStateChanged(ItemEvent e) 111 { 112 jTextField.setText(lengthInfo.getLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex()) + ""); 113 } 114 }); 115 116 JButton cancelButton = new JButton("取消"); 117 JButton okayButton = new JButton("确认"); 118 119 120 cancelButton.addMouseListener(new MouseAdapter() 121 { 122 @Override 123 public void mouseClicked(MouseEvent e) 124 { 125 jFrame.setVisible(false); 126 } 127 }); 128 okayButton.addMouseListener(new MouseAdapter() 129 { 130 @Override 131 public void mouseClicked(MouseEvent e) 132 { 133 try 134 { 135 double weight = Double.parseDouble(jTextField.getText().toString()); 136 lengthInfo.editLength(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex(), weight); 137 objectOutputStream = new ObjectOutputStream(new FileOutputStream(lengthFile)); 138 objectOutputStream.writeObject(arrayList); 139 140 new mDialog("成功", "数据修改成功!", jFrame); 141 jFrame.setVisible(false); 142 } catch (NumberFormatException e1) 143 { 144 e1.printStackTrace(); 145 new mDialog("错误", "请输入正确信息!", jFrame); 146 } catch (IOException e1) 147 { 148 new mDialog("错误", "信息写入失败!", jFrame); 149 } 150 151 152 } 153 }); 154 155 jFrame.add(jComboBox1); 156 jFrame.add(jComboBox2); 157 jFrame.add(jTextField); 158 jFrame.add(cancelButton); 159 jFrame.add(okayButton); 160 jFrame.setVisible(true); 161 jFrame.setResizable(false); 162 } 163 164 public static void main(String[] args) 165 { 166 new CreateLength(new JFrame()); 167 } 168 169 }CreateLength.java
我承认,这个我偷懒了,这个我直接用的是上一个类。不过话说过来,这俩不是差不多嘛(′_`)
4.一般用户的操作菜单
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.MouseAdapter; 4 import java.awt.event.MouseEvent; 5 6 class NormalMenu 7 { 8 9 private JFrame jFrame; 10 private JButton visitButton, searchButton, okayButton; 11 private Font font = new Font("微软雅黑", 1, 20); 12 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 13 14 public NormalMenu() 15 { 16 jFrame = new JFrame("功能菜单"); 17 jFrame.setBounds((toolkit.getScreenSize().width - 250) / 2, (toolkit.getScreenSize().height - 200) / 2, 250, 200); 18 jFrame.setLayout(new FlowLayout()); 19 visitButton = new JButton("1.浏览景点信息"); 20 visitButton.setFont(font); 21 searchButton = new JButton("2.查询最短路径"); 22 searchButton.setFont(font); 23 okayButton = new JButton("关闭"); 24 okayButton.setFont(font); 25 26 27 visitButton.addMouseListener(new MouseAdapter() 28 { 29 @Override 30 public void mouseClicked(MouseEvent e) 31 { 32 new VisitPoint(); 33 } 34 }); 35 36 searchButton.addMouseListener(new MouseAdapter() 37 { 38 @Override 39 public void mouseClicked(MouseEvent e) 40 { 41 new SearchLength(); 42 } 43 }); 44 45 okayButton.addMouseListener(new MouseAdapter() 46 { 47 @Override 48 public void mouseClicked(MouseEvent e) 49 { 50 jFrame.setVisible(false); 51 } 52 }); 53 54 jFrame.add(visitButton); 55 jFrame.add(searchButton); 56 jFrame.add(okayButton); 57 jFrame.setResizable(false); 58 jFrame.setVisible(true); 59 60 } 61 62 }NormalMenu.java
4.1 浏览景点信息
1 import javax.swing.*; 2 import java.awt.*; 3 import java.awt.event.ItemEvent; 4 import java.awt.event.ItemListener; 5 import java.awt.event.MouseAdapter; 6 import java.awt.event.MouseEvent; 7 import java.io.File; 8 import java.io.FileInputStream; 9 import java.io.IOException; 10 import java.io.ObjectInputStream; 11 import java.util.Iterator; 12 import java.util.Set; 13 import java.util.TreeMap; 14 import java.util.TreeSet; 15 16 public class VisitPoint 17 { 18 private JFrame jFrame; 19 private JComboBox jComboBox; 20 private JLabel jLabel; 21 private JButton okayButton; 22 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 23 24 private File file = new File("D://point.obj"); 25 private ObjectInputStream objectInputStream; 26 27 private TreeMap treeMap; 28 private Set set; 29 30 public VisitPoint() 31 { 32 try 33 { 34 objectInputStream = new ObjectInputStream(new FileInputStream(file)); 35 jFrame = new JFrame(); 36 } catch (IOException e) 37 { 38 new mDialog("错误", "无景点信息文件!", jFrame); 39 } 40 frameInit(); 41 } 42 43 public void frameInit() 44 { 45 try 46 { 47 jFrame.setLayout(new BorderLayout()); 48 jFrame.setBounds((toolkit.getScreenSize().width - 350) / 2, (toolkit.getScreenSize().height - 250) / 2, 350, 250); 49 50 } catch (Exception e) 51 { 52 e.printStackTrace(); 53 } 54 55 jComboBox = new JComboBox(); 56 jComboBox.setPreferredSize(new Dimension(270,30)); 57 try 58 { 59 treeMap = (TreeMap) objectInputStream.readObject(); 60 set = treeMap.keySet(); 61 } catch (IOException e) 62 { 63 64 } catch (ClassNotFoundException e) 65 { 66 67 } 68 Iterator iterator = set.iterator(); 69 while (iterator.hasNext()) 70 { 71 jComboBox.addItem((String) iterator.next()); 72 } 73 74 jLabel = new JLabel(); 75 jLabel.setPreferredSize(new Dimension(270,20)); 76 jLabel.setFont(new Font("宋体", 1, 20)); 77 jLabel.setText((String) treeMap.get(jComboBox.getSelectedItem())); 78 79 jComboBox.addItemListener(new ItemListener() 80 { 81 @Override 82 public void itemStateChanged(ItemEvent e) 83 { 84 jLabel.setText((String) treeMap.get(jComboBox.getSelectedItem())); 85 } 86 }); 87 88 okayButton = new JButton("确定"); 89 okayButton.setFont(new Font("微软雅黑", 1, 20)); 90 okayButton.addMouseListener(new MouseAdapter() 91 { 92 93 @Override 94 public void mouseClicked(MouseEvent e) 95 { 96 jFrame.setVisible(false); 97 } 98 }); 99 jFrame.add(jComboBox,BorderLayout.NORTH); 100 jFrame.add(jLabel,BorderLayout.CENTER); 101 jFrame.add(okayButton,BorderLayout.SOUTH); 102 jFrame.setResizable(false); 103 jFrame.setVisible(true); 104 } 105 106 public static void main(String[] args) 107 { 108 new VisitPoint(); 109 } 110 }VisitPoint.java
很简单,想不出啥需要强调的。
4.2 查询任意两点间的最短路径
1 import javax.imageio.event.IIOReadProgressListener; 2 import javax.swing.*; 3 import java.awt.*; 4 import java.awt.event.ItemEvent; 5 import java.awt.event.ItemListener; 6 import java.awt.event.MouseAdapter; 7 import java.awt.event.MouseEvent; 8 import java.io.File; 9 import java.io.FileInputStream; 10 import java.io.IOException; 11 import java.io.ObjectInputStream; 12 import java.util.ArrayList; 13 import java.util.Iterator; 14 import java.util.Set; 15 import java.util.TreeMap; 16 17 public class SearchLength 18 { 19 private JFrame jFrame; 20 private JComboBox jComboBox1, jComboBox2; 21 private JLabel jLabel; 22 private JButton jButton; 23 24 private ObjectInputStream objectInputStream1, objectInputStream2; 25 private File lengthFile, pointFile; 26 27 private TreeMap treeMap; 28 private ArrayList arrayList; 29 private Set set; 30 31 private LengthInfo lengthInfo; 32 33 private Toolkit toolkit = Toolkit.getDefaultToolkit(); 34 35 public SearchLength() 36 { 37 38 jFrame = new JFrame(); 39 try 40 { 41 lengthFile = new File("D://length.obj"); 42 pointFile = new File("D://point.obj"); 43 objectInputStream1 = new ObjectInputStream(new FileInputStream(lengthFile)); 44 objectInputStream2 = new ObjectInputStream(new FileInputStream(pointFile)); 45 arrayList = (ArrayList) objectInputStream1.readObject(); 46 lengthInfo = (LengthInfo) arrayList.get(0); 47 48 treeMap = (TreeMap) objectInputStream2.readObject(); 49 50 51 } catch (IOException e) 52 { 53 new mDialog("错误", "无景点信息!", jFrame); 54 } catch (ClassNotFoundException e) 55 { 56 new mDialog("错误!", "文件信息错误!", jFrame); 57 } 58 59 60 try 61 { 62 set = treeMap.keySet(); 63 } catch (NullPointerException e) 64 { 65 new mDialog("错误", "无道路长度信息!", jFrame); 66 } 67 68 frameInit(); 69 } 70 71 public void frameInit() 72 { 73 jFrame.setLayout(new FlowLayout()); 74 jFrame.setBounds((toolkit.getScreenSize().width - 200) / 2, (toolkit.getScreenSize().height - 200) / 2, 400, 200); 75 76 jComboBox1 = new JComboBox(); 77 jComboBox1.setPreferredSize(new Dimension(180, 30)); 78 jComboBox1.setFont(new Font("微软雅黑", 1, 20)); 79 jComboBox2 = new JComboBox(); 80 jComboBox2.setPreferredSize(new Dimension(180, 30)); 81 jComboBox2.setFont(new Font("微软雅黑", 1, 20)); 82 83 Iterator iterator = set.iterator(); 84 while (iterator.hasNext()) 85 { 86 String string = (String) iterator.next(); 87 jComboBox1.addItem(string); 88 jComboBox2.addItem(string); 89 } 90 jLabel = new JLabel(); 91 jLabel.setPreferredSize(new Dimension(350, 80)); 92 jLabel.setFont(new Font("微软雅黑", 1, 20)); 93 double str1 = lengthInfo.getMin(0, 1, treeMap); 94 jComboBox1.addItemListener(new ItemListener() 95 { 96 @Override 97 public void itemStateChanged(ItemEvent e) 98 { 99 double str1 = lengthInfo.getMin(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex(), treeMap); 100 String str2 = lengthInfo.getStringBuilder(); 101 jLabel.setText("" + "最优路径: " + str2 + "SearchLength.java
" + "里程: " + str1 + "m" + ""); 102 } 103 }); 104 jComboBox2.addItemListener(new ItemListener() 105 { 106 @Override 107 public void itemStateChanged(ItemEvent e) 108 { 109 double str1 = lengthInfo.getMin(jComboBox1.getSelectedIndex(), jComboBox2.getSelectedIndex(), treeMap); 110 String str2 = lengthInfo.getStringBuilder(); 111 jLabel.setText("" + "最优路径: " + str2 + "
" + "里程: " + str1 + "m" + ""); 112 } 113 }); 114 115 jButton = new JButton("确定"); 116 jButton.addMouseListener(new MouseAdapter() 117 { 118 @Override 119 public void mouseClicked(MouseEvent e) 120 { 121 jFrame.setVisible(false); 122 } 123 }); 124 125 jFrame.add(jComboBox1); 126 jFrame.add(jComboBox2); 127 jFrame.add(jLabel); 128 jFrame.add(jButton); 129 jFrame.setResizable(false); 130 jFrame.setVisible(true); 131 } 132 133 134 }
这里面的代码主要就是界面。实质的工作没在这里面。
有个可以优化的:就拿上面那个图来说,这个路径其实是反的,因为算法最后用的是回溯,stringBuilder.append()也就是从后往前拼接的。要是正的就更好了。
还有,在JLabel中居然可以使用html的格式控制,上面的“最优路程”与“里程”的换行就是使用
实现的。
但是这里我有一个疑惑:字符串中的“<”“>”是显示不出来的。一开始想使用“<--”来间隔,最后无奈只能用“---”了。
5.后记
程序不算完美,有很多我已经意识到的bug和可以继续优化的点。但是好歹是自己的一次实践,也是非常有价值的。
idea工程文件:
https://github.com/0-0MrLonely/SourceCode/tree/master/Java/NaviDemo