@
目录
写在前面
只是我的Java课程的一个大作业,仅供参考。使用到的Java特性有:封装、继承、多态、包、GUI、Swing、集合类。耗时一周,一千行左右。

一、仿真模拟的具体要求

二、类的设计
考虑到程序仿真比较复杂,优先思考类与类之间的关联,下面用类图来描述。
2.1 抽象父类PubVehicles

PubVehicles作为抽象父类,有俩个子类分别是Iveco和Volvo,基本的成员变量在右侧,抽象方法在左侧。
2.2 Expressway类

Expressway类,放置在Expressway.java文件中,包含需要使用的变量,以及main方法和initialization方法。
2.3 Passenger类

Passenger类,有构造方法、上车等方法。右侧是成员变量,分别是是否在宝鸡站和目的地。
2.4 Timer类

Timer类,用于记录时间,以及刷新GUI界面,从而实现运动的画面。左侧是相关的方法,右侧是一些基本成员变量。
2.5 DisplayToolkit类

DisplayToolkit类主要运用GUI和Swing的组件,创建可视化用户界面。
三、图像显示
这里主要是让小车运动起来的实现,小车的PNG图片如下(背景透明)

images文件夹与src文件夹放置在同一目录下即可。
具体放置到GUI界面中基本上是八股文代码,如下所示(仅供演示)
复制代码
java
//right变量 图片路径 public Image right=Toolkit.getDefaultToolkit().createImage("images/Iveco_Right.png"); //lb和ii,将图片放置到JLabel上 JLabel lb=new JLabel(); ImageIcon ii=new ImageIcon(right); //设置 ii.setImage(ii.getImage().getScaledInstance(80, 80, Image.SCALE_DEFAULT));//缩放到80x80 lb.setToolTipText("Iveco "+this.number);//鼠标移到上面有信息显示 lb.setVisible(true); lb.setIcon(ii); Expressway.panel_cars.add(lb);
四、代码实现
完整代码、PNG素材、类图设计,请在公众号私信回复 [西宝高速公路] 获取,下面超长,最好不要翻阅。
4.1 Expressway.java
复制代码
java
package Expressway; import java.util.*; import java.awt.*; public class Expressway { //专门查看汽车运动状态的面板 980x720 路长设定为870像素(174千米) public static DisplayPanel panel_cars=new DisplayPanel(0,0,980,100,new Color(255,250,250)); //专门放置公路的面板980x100 public static DisplayPanel panel_road=new DisplayPanel(0,100,980,100,new Color(255,250,250)); //专门给自己设置的面板300x100 private static DisplayPanel panelformyself=new DisplayPanel(980,100,300,100,new Color(35,35,35)); private static Label personalinfo=null; //日志面板 //西安和宝鸡站点的车辆和乘客数目信息版 public static DisplayDialogPanel panel_xian_station=new DisplayDialogPanel(965,200,300,520,new Color(255,250,250)); public static DisplayDialog XNStation=new DisplayDialog("Xi'An Station",50,50,0,0,300,520); public static DisplayDialogPanel panel_baoji_station=new DisplayDialogPanel(665,200,300,520,new Color(255,250,250)); public static DisplayDialog BJStation=new DisplayDialog("BaoJi Station",50,50,0,0,300,520); //在高速路上的车辆的信息 public static DisplayDialogPanel panel_on_way=new DisplayDialogPanel(315,200,350,520,new Color(255,250,250)); public static DisplayDialog OntheWayInfo=new DisplayDialog("On The Expressway",50,50,0,0,350,520); //Console终端,记录发车,产生乘客等信息 public static DisplayDialogPanel panel_console=new DisplayDialogPanel(0,200,315,520,new Color(255,250,250)); public static DisplayDialog console=new DisplayDialog("Console",50,50,0,0,315,520); //创建Frame public static DisplayFrame display=new DisplayFrame("Expressway"); //用于计时的面板 和 标签 public static DisplayPanel panel_timer=new DisplayPanel(980,0,300,100,new Color(35,35,35)); public static Label timer=null; //XN和BJ在仿真开始时拥有的客车数量XNW、XNY、BJW和BJY。可先按XNW=5,XNY=12,BJW=4,BJY=15进行 public static int XN_Volvo = 5; public static int XN_Iveco = 12; public static int BJ_Volvo = 4; public static int BJ_Iveco = 15; //这里新建公共汽车 public static Iveco ivecos[]=new Iveco[XN_Iveco+BJ_Iveco];//包含了在西安点的,在宝鸡点的 public static Volvo volvos[]=new Volvo[XN_Volvo+BJ_Volvo]; //这里是到达终点站后即将反转的车辆队列,队列FIFO,排队按照规则发车 public static Queue<Volvo> BjVolvoQ=new LinkedList<Volvo>(); public static Queue<Volvo> XnVolvoQ=new LinkedList<Volvo>(); public static Queue<Iveco> BjIvecoQ=new LinkedList<Iveco>(); public static Queue<Iveco> XnIvecoQ=new LinkedList<Iveco>(); //在路上的车辆 public static LinkedList<Iveco> ivecosOnRoad=new LinkedList<Iveco>(); public static LinkedList<Volvo> volvosOnRoad=new LinkedList<Volvo>(); //用于记录在路上车辆的数目 public static int ivecosOnRoadNum=0; public static int volvosOnRoadNum=0; //乘客相关的数据 //分别在西安站和宝鸡站等车的乘客队列 public static Queue<Passenger> XnPassengerQ=new LinkedList<Passenger>(); public static Queue<Passenger> BjPassengerQ=new LinkedList<Passenger>(); //每分钟到达乘客的人数上限 public static int Pn=2; public static void initialization() { //初始化 for(int i=0;i<ivecos.length;i++) {//编号就按照宝鸡优先编号了 if(i < BJ_Iveco) { //宝鸡站出发的一共有BJ_Iveco个,也就是向右行驶 ivecos[i]=new Iveco(true,i,7,21,20); BjIvecoQ.add(ivecos[i]); }else { //西安站出发的一共有XN_Iveco个,也就是向左行驶 ivecos[i]=new Iveco(false,i,7,21,20); XnIvecoQ.add(ivecos[i]); } } for(int i=0;i<volvos.length;i++) { if(i<BJ_Volvo) { volvos[i]=new Volvo(true,i,10,40,60); BjVolvoQ.add(volvos[i]); }else { volvos[i]=new Volvo(false,i,10,40,60); XnVolvoQ.add(volvos[i]); } } //面板放置到display frame display.add(panel_cars); display.add(panel_timer); display.add(panelformyself); display.add(panel_road); display.add(panel_xian_station); display.add(panel_baoji_station); display.add(panel_on_way); display.add(panel_console); //创建时间显示揭界面 timer=new Label(); timer.setText(Timer.getTime()); timer.setFont(new Font(null,Font.PLAIN,25)); timer.setBounds(0,0,300,100); timer.setForeground(new Color(255,255,255)); panel_timer.add(timer); timer.setVisible(true); //创建作者信息 personalinfo=new Label(); personalinfo.setText("Iamnotphage"); personalinfo.setFont(new Font(null,Font.PLAIN,25)); personalinfo.setBounds(0,0,300,100); personalinfo.setForeground(new Color(255,255,255)); panelformyself.add(personalinfo); personalinfo.setVisible(true); //日志部分 panel_xian_station.setViewportView(XNStation); panel_baoji_station.setViewportView(BJStation); panel_on_way.setViewportView(OntheWayInfo); console.setFont(new Font("黑体",Font.BOLD,15)); panel_console.setViewportView(console); //铺路 //这里取60 原因:汽车最左边的左上角x坐标为20 汽车图片长80,取汽车几何中心为质点,也就是40的长度,这样起点就是20+40=60 RoadButton BJ_GZ=new RoadButton("BaoJi to GaoZhen",60,0,120);//长120像素 RoadButton GZ_CP=new RoadButton("GaoZhen to CaijiaPo",180,0,105);//长105像素 RoadButton CP_WG=new RoadButton("CaijiaPo to WuGong",285,0,310);//长310像素 RoadButton WG_XP=new RoadButton("WuGong to XingPin",595,0,105);; RoadButton XP_XY=new RoadButton("XingPin to Xianyang",700,0,120); RoadButton XY_XN=new RoadButton("XianYang to XiAn",820,0,110); panel_road.add(BJ_GZ); panel_road.add(GZ_CP); panel_road.add(CP_WG); panel_road.add(WG_XP); panel_road.add(XP_XY); panel_road.add(XY_XN); //面板刷新一下 以解决初次运行程序需要拖动Frame才能正常显示面板的问题 panel_cars.setVisible(false); panel_cars.setVisible(true); panel_road.setVisible(false); panel_road.setVisible(true); panel_xian_station.setVisible(false); panel_xian_station.setVisible(true); panel_baoji_station.setVisible(false); panel_baoji_station.setVisible(true); } public static void main(String[] args) { initialization(); //主循环 while(true) { Timer.FreshTime(timer);//调用Timer类里面的FreshTime进行时间刷新 } } }
折叠
4.2 Timer.java
复制代码
java
package Expressway; import java.awt.Label; import java.util.Random; //Timer类,用于记录虚拟的时间,机器时间1秒等于虚拟时间1分钟 //一切都是由时间变化引起的变化 public class Timer { public static int day=0; public static int hour=7; public static int min=25; public static final int period=1000; public static String getTime() { if(min==60) { hour++; min=0; } if(hour==20 && min==15) {//由于工作时间是7:30到18:00,这里设置可见时间为7:15至18:15 hour=7; min=15; day++; Expressway.XnPassengerQ.clear(); Expressway.BjPassengerQ.clear(); } String str=new String("Now: Day "+day+" Time: "+hour+" : "+min+" "); return str; } public static void FreshTime(Label timer) {//刷新时间的同时,刷新汽车运动状态 min++; timer.setText(getTime());//设置时间显示 //延迟1秒后刷新状态 //需要刷新的有: 各个车辆的位置 面板信息 乘客行为 try { //产生乘客 ProducePassengerstoBaoJi(); ProducePassengerstoXiAn(); //发车前 LetPassengersAboardVolvo(); LetPassengersAboardIveco(); for(int i=0;i<Expressway.ivecosOnRoad.size();i++) { Expressway.ivecosOnRoad.get(i).Stop(Expressway.ivecosOnRoad.get(i).CheckStop()); } for(int i=0;i<Expressway.volvosOnRoad.size();i++) { Expressway.volvosOnRoad.get(i).Stop(Expressway.volvosOnRoad.get(i).CheckStop()); } //发车&车辆移动 CarMovingWithTime(); //刷新面板信息 FreshStationInfo(); FreshOnTheWayInfo(); Thread.sleep(period); } catch (InterruptedException e) { e.printStackTrace(); } } public static void CarMovingWithTime() { //依维柯发车 if(Expressway.BjIvecoQ.peek()!=null) {//宝鸡的依维柯发车 Expressway.BjIvecoQ.peek().launch(); if(Expressway.BjIvecoQ.peek().isLaunched) { Expressway.ivecosOnRoad.add(Expressway.BjIvecoQ.poll()); Expressway.console.append("\n["+hour+":"+min+"]Iveco "+Expressway.ivecosOnRoad.get(Expressway.ivecosOnRoadNum).number+" Launched from BaoJi"); Expressway.ivecosOnRoad.get(Expressway.ivecosOnRoadNum).lb.setVisible(true); Expressway.ivecosOnRoadNum++; } } if(Expressway.XnIvecoQ.peek()!=null) {//西安的依维柯发车 Expressway.XnIvecoQ.peek().launch(); if(Expressway.XnIvecoQ.peek().isLaunched) { Expressway.ivecosOnRoad.add(Expressway.XnIvecoQ.poll()); Expressway.console.append("\n["+hour+":"+min+"]Iveco "+Expressway.ivecosOnRoad.get(Expressway.ivecosOnRoadNum).number+" Launched from Xi'An"); Expressway.ivecosOnRoad.get(Expressway.ivecosOnRoadNum).lb.setVisible(true); Expressway.ivecosOnRoadNum++; } } for(int i=0;i<Expressway.ivecosOnRoadNum;i++) {//遍历路上车辆,移动 if(Expressway.ivecosOnRoad.get(i).isLaunched) { Expressway.ivecosOnRoad.get(i).CarMoving(); } } //沃尔沃发车 if(Expressway.BjVolvoQ.peek()!=null) {//宝鸡的沃尔沃发车 Expressway.BjVolvoQ.peek().launch(); if(Expressway.BjVolvoQ.peek().isLaunched) { Expressway.volvosOnRoad.add(Expressway.BjVolvoQ.poll()); Expressway.console.append("\n["+hour+":"+min+"]Volvo "+Expressway.volvosOnRoad.get(Expressway.volvosOnRoadNum).number+" Launched from BaoJi"); Expressway.volvosOnRoad.get(Expressway.volvosOnRoadNum).lb.setVisible(true); Expressway.volvosOnRoadNum++; } } if(Expressway.XnVolvoQ.peek()!=null) {//西安的沃尔沃发车 Expressway.XnVolvoQ.peek().launch(); if(Expressway.XnVolvoQ.peek().isLaunched) { Expressway.volvosOnRoad.add(Expressway.XnVolvoQ.poll()); Expressway.console.append("\n["+hour+":"+min+"]Volvo "+Expressway.volvosOnRoad.get(Expressway.volvosOnRoadNum).number+" Launched from Xi'An"); Expressway.volvosOnRoad.get(Expressway.volvosOnRoadNum).lb.setVisible(true); Expressway.volvosOnRoadNum++; } } for(int i=0;i<Expressway.volvosOnRoadNum;i++) {//遍历路上车辆,移动 if(Expressway.volvosOnRoad.get(i).isLaunched) { Expressway.volvosOnRoad.get(i).CarMoving(); } } } public static void FreshStationInfo() { //西安站面板的信息显示 Expressway.XNStation.setText("Xi'An Station"); for(Volvo i:Expressway.XnVolvoQ) { Expressway.XNStation.append("\n Volvo: "+i.number); } for(Iveco i:Expressway.XnIvecoQ) { Expressway.XNStation.append("\n Iveco: "+i.number); } Expressway.XNStation.append("\n候车乘客数: "+Expressway.XnPassengerQ.size()); //宝鸡站面板的信息显示 Expressway.BJStation.setText("BaoJi Station"); for(Volvo i:Expressway.BjVolvoQ) { Expressway.BJStation.append("\n Volvo: "+i.number); } for(Iveco i:Expressway.BjIvecoQ) { Expressway.BJStation.append("\n Iveco: "+i.number); } Expressway.BJStation.append("\n候车乘客数: "+Expressway.BjPassengerQ.size()); } public static void FreshOnTheWayInfo() { Expressway.OntheWayInfo.setText("On The Expressway"); for(Volvo i:Expressway.volvosOnRoad) { Expressway.OntheWayInfo.append("\n Volvo: "+i.number+"乘客人数: "+i.ps.size()); } for(Iveco i:Expressway.ivecosOnRoad) { Expressway.OntheWayInfo.append("\n Iveco: "+i.number+"乘客人数: "+i.ps.size()); } } //生成 在西安站 前往宝鸡站的乘客 public static void ProducePassengerstoBaoJi() { //上午7点30到下午17点59 才产生乘客 if(hour*60+min<450 || hour*60+min >1079) { return; } Random r=new Random(); //每分钟随机生成0~Pn个乘客 [0,Pn] int PassengerNum=r.nextInt(Expressway.Pn+1); //用均匀分布产生不同终点[0,5] //也就是[0,6) 012345 for(int i=0;i<PassengerNum;i++) { Expressway.XnPassengerQ.add(new Passenger(false,(int)(Math.random()*6))); } if(PassengerNum!=0) { //Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+PassengerNum+"Passengers "+"Wait at Xi'An Station"); } } //生成 在宝鸡站 前往西安站的乘客 public static void ProducePassengerstoXiAn() { //上午7点30到下午17点59 才产生乘客 if(hour*60+min<450 || hour*60+min >1079) { return; } Random r=new Random(); //每分钟随机生成0~Pn个乘客 [0,Pn] int PassengerNum=r.nextInt(Expressway.Pn+1); //用均匀分布产生不同终点[1,6] //[1,7) 也就是123456 for(int i=0;i<PassengerNum;i++) { Expressway.BjPassengerQ.add(new Passenger(true,(int)(Math.random()*6+1))); } if(PassengerNum!=0) { //Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+PassengerNum+"Passengers "+"Wait at BaoJi Station"); } } //安排乘客上Iveco车,即遍历乘客队列 public static void LetPassengersAboardIveco() { //宝鸡站 for(int i=0;i<Expressway.BjPassengerQ.size();i++) { if(Expressway.BjPassengerQ.peek()!=null) { if(Expressway.BjPassengerQ.peek().AboardIveco()) { Expressway.BjPassengerQ.poll(); }else { //队首上车失败直接break break; } } } //西安站 for(int i=0;i<Expressway.XnPassengerQ.size();i++) { if(Expressway.XnPassengerQ.peek()!=null) { if(Expressway.XnPassengerQ.peek().AboardIveco()) { Expressway.XnPassengerQ.poll(); }else { break; } } } } public static void LetPassengersAboardVolvo() { //宝鸡站 for(int i=0;i<Expressway.BjPassengerQ.size();i++) { if(Expressway.BjPassengerQ.peek()!=null) { if(Expressway.BjPassengerQ.peek().AboardVolvo()) { Expressway.BjPassengerQ.poll(); }else { break; } } } //西安站 for(int i=0;i<Expressway.XnPassengerQ.size();i++) { if(Expressway.XnPassengerQ.peek()!=null) { if(Expressway.XnPassengerQ.peek().AboardVolvo()) { Expressway.XnPassengerQ.poll(); }else { break; } } } } }
折叠
4.3 DisplayToolkit.java
复制代码
java
package Expressway; import java.awt.Button; import java.awt.Color; import java.awt.Font; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; //显示界面 class DisplayFrame extends JFrame{ //自动生成的序列版本号 private static final long serialVersionUID = 1L; //窗口属性区域 private static final int WIDTH=1280; private static final int HEIGHT=720; DisplayFrame(String title){ super(title); this.setSize(WIDTH,HEIGHT); this.setBackground(new Color(51,51,51)); this.setResizable(false); this.setLayout(null);//不使用布局管理器 this.setLocationRelativeTo(null); this.setVisible(true); //关闭窗口的事件 this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } } //显示面板 class DisplayPanel extends JPanel{ //自动生成的序列版本号 private static final long serialVersionUID = 1L; DisplayPanel(int x,int y,int width,int height,Color c){ super(null); this.setBounds(x,y,width,height); this.setBackground(c); } } //显示公路 class RoadButton extends Button{ //默认序列号 private static final long serialVersionUID = 1L; public RoadButton(String str,int x,int y,int w) { super(str); this.setBackground(Color.black); this.setForeground(new Color(255,255,255)); this.setBounds(x,y,w,50); } } class DisplayRoad extends JPanel{ private static final long serialVersionUID = 1L; //公路长 870像素,即174千米 DisplayRoad(int x,int y,int width,int height,Color c){ super(null); this.setBounds(x,y,width,height); this.setBackground(c); } } class DisplayDialogPanel extends JScrollPane{ private static final long serialVersionUID = 1L; DisplayDialogPanel(int x,int y,int width,int height,Color c){ super(null); this.setBounds(x,y,width,height); this.setBackground(c); } } class DisplayDialog extends JTextArea{ //默认序列号 private static final long serialVersionUID = 1L; DisplayDialog(String str,int row,int col,int x,int y,int w,int h){ super(str,row,col); this.setBounds(x,y,w,h); this.setBackground(new Color(15,15,15)); this.setForeground(new Color(0,255,0)); this.setFont(new Font("黑体",Font.BOLD,20)); } } public class DisplayToolkit { }
折叠
4.4 Vehicles.java
复制代码
java
package Expressway; import java.awt.*; import java.util.LinkedList; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; abstract class PubVehicles{ public static final int LEFT_BOUND=20;//车的运动边界,x方向上 20~890 高速公路长870像素 public static final int RIGHT_BOUND=890; protected boolean isRight;//是否向右行驶 protected boolean isLaunched=false;//是否发车了 protected int currentP;//当前的位置 protected int number;//公交车的编号 protected int speed;//车速 protected int capacity;//容量 protected LinkedList<Passenger> ps=new LinkedList<Passenger>();//乘客链表,记录车上的各个乘客信息 到终点站记得清空 protected int duration;//发车的间隔 protected JLabel lb;//用于存图的JLabel protected ImageIcon ii;//图片 PubVehicles(boolean isRight,int number,int speed,int capacity,int duration){ this.isRight=isRight; this.number=number; this.speed=speed; this.capacity=capacity; this.duration=duration; } abstract protected void headReverse();//到达终点站调头 abstract protected void display(int x,int y);//显示在panel_car面板上 abstract protected void launch();//每隔一段时间发车 abstract protected void CarMoving();//车辆移动 abstract protected int CheckStop();//检查车上是否有乘客即将到站 如果没有,返回-1,如果有,返回当前站点的编号0,1,2,3,4,5,6 abstract protected void Stop(int index);//靠index站停车,等待乘客下车 } //依维柯 速度是7像素每秒,也就是1.4公里每分钟 容量21 //上午8:00开始,每20分钟一班,最后一班为下午6:00 class Iveco extends PubVehicles{ private int temp=0;//用于停2分钟的临时变量 public Image right=Toolkit.getDefaultToolkit().createImage("images/Iveco_Right.png"); public Image left=Toolkit.getDefaultToolkit().createImage("images/Iveco_Left.png"); //初始化 Iveco(boolean isRight,int number, int speed, int capacity,int duration) { super(isRight,number, speed,capacity,duration); lb=new JLabel(); ii=null; //选择车头朝向 if(isRight) {//如果车头向右 ii=new ImageIcon(this.right); this.currentP=LEFT_BOUND; }else { ii=new ImageIcon(this.left); this.currentP=RIGHT_BOUND; } ii.setImage(ii.getImage().getScaledInstance(80, 80, Image.SCALE_DEFAULT));//缩放到80x80 lb.setToolTipText("Iveco "+this.number);//鼠标移到上面有信息显示 lb.setVisible(true); lb.setIcon(ii); Expressway.panel_cars.add(lb); } protected void display(int x, int y) { //显示在panel_cars if( (this.isRight && x>=RIGHT_BOUND) || (!this.isRight && x<=LEFT_BOUND)) { if(this.isRight) {//到达终点后,终点队列的尾部中添加该车,路上的车链表删除该车,并减少在路上车辆的计数器 Expressway.XnIvecoQ.add(this); Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]Iveco "+this.number+" Arrived at Xi'An"); }else{ Expressway.BjIvecoQ.add(this); Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]Iveco "+this.number+" Arrived at BaoJi"); } for(int i=0;i<Expressway.ivecosOnRoadNum;i++) { if(this.number==Expressway.ivecosOnRoad.get(i).number) { Expressway.ivecosOnRoad.remove(i); Expressway.ivecosOnRoadNum--; this.isLaunched=false; this.lb.setVisible(isLaunched); break; } } this.headReverse(); } lb.setBounds(x,y,80,80); } protected void headReverse() { // TODO Auto-generated method stub //掉头之前清空乘客链表ps this.ps.clear(); this.isRight=!this.isRight; if(this.isRight){ ii=new ImageIcon(this.right); ii.setImage(ii.getImage().getScaledInstance(80, 80, Image.SCALE_DEFAULT));//缩放到80x80 lb.setIcon(ii); Expressway.panel_cars.add(lb); }else{ ii=new ImageIcon(this.left); ii.setImage(ii.getImage().getScaledInstance(80, 80, Image.SCALE_DEFAULT));//缩放到80x80 lb.setIcon(ii); Expressway.panel_cars.add(lb); } } protected void launch() { if( (Timer.hour>=8 && Timer.hour<=17 && Timer.min%20==0) || (Timer.hour==18&&Timer.min==0)) {//8点整第一班 每20分钟发一次 18点最后一班 this.isLaunched=true; return; }else { return; } } protected void CarMoving() {//要伴随着Timer使用,每min移动一次 // TODO Auto-generated method stub this.display(this.currentP,0); if(this.isRight) { this.currentP += this.speed; }else { this.currentP -= this.speed; } } protected int CheckStop() {//检查乘客是否即将到站 // TODO Auto-generated method stub //只有快到站才检查,否则浪费时间 int index=-1; if(this.isRight) { //前往西安方向各坐标近似取20 139 244 552 657 783 889 if(this.currentP==139||this.currentP==244||this.currentP==552||this.currentP==657||this.currentP==783||this.currentP==889) { for(int i=0;i<this.ps.size();i++) { if(this.ps.get(i).destination==1&&this.currentP==139) { index=1; return index; }else if(this.ps.get(i).destination==2&&this.currentP==244) { index=2; return index; }else if(this.ps.get(i).destination==3&&this.currentP==552) { index=3; return index; }else if(this.ps.get(i).destination==4&&this.currentP==657) { index=4; return index; }else if(this.ps.get(i).destination==5&&this.currentP==783) { index=5; return index; }else if(this.ps.get(i).destination==6&&this.currentP==889) { index=6; return index; }else { return -1; } } }else { return -1; } }else { //前往宝鸡方向的各个坐标近似取22 141 246 554 659 778 890 if(this.currentP==22||this.currentP==141||this.currentP==246||this.currentP==554||this.currentP==659||this.currentP==778) { for(int i=0;i<this.ps.size();i++) { if(this.ps.get(i).destination==0&&this.currentP==22) { index=0; return index; }else if(this.ps.get(i).destination==1&&this.currentP==141) { index=1; return index; }else if(this.ps.get(i).destination==2&&this.currentP==246) { index=2; return index; }else if(this.ps.get(i).destination==3&&this.currentP==554) { index=3; return index; }else if(this.ps.get(i).destination==4&&this.currentP==659) { index=4; return index; }else if(this.ps.get(i).destination==5&&this.currentP==778) { index=5; return index; }else { return -1; } } }else { return -1; } } return index;//如果是-1表示不需要停车 } protected void Stop(int index) {//CheckStop返回index不是-1,就执行Stop,在index站点等待两分钟,并且让乘客下车 // TODO Auto-generated method stub //停2分钟的部分 if(index==-1&&this.temp==0) {//如果没有执行过stop并且index是-1,说明不需要停车 return;//第一次执行stop后,ps链表中已经没有需要下车的乘客了,下一分钟再执行checkstop后返回-1,但此时temp已经是1,所以函数不会返回 } this.isLaunched=false; Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+"Iveco"+this.number+" Stops"); this.temp++; if(this.temp==2) { this.temp=0; this.isLaunched=true;//isLaunched来控制汽车是否移动 Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+"Iveco"+this.number+" ReLauched!"); return; } //利用index来判断ps链表中哪些乘客需要下车 int count=0;//用来计数下车的乘客,最终输出到console中避免繁琐 //这里直接遍历ps链表,注意size会减少的情况 for(int i=0;i<this.ps.size();i++) { if(this.ps.get(i).destination==index) { this.ps.remove(i--);//必须减减,否则size()变小,遍历不全 count++; } } //根据index输出 switch(index) { case 0: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at BaoJi Station"); break; case 1: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at GaoZhen Station"); break; case 2: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at CaijiaPo Station"); break; case 3: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at WuGong Station"); break; case 4: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at XingPin Station"); break; case 5: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at XianYang Station"); break; case 6: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at Xi'An Station"); break; } } } //沃尔沃 速度是10像素每分钟,也就是2公里每分钟 容量40 //上午8:30开始,每小时一班,最后一班为下午5:30 class Volvo extends PubVehicles{ private int temp=0; public Image right=Toolkit.getDefaultToolkit().createImage("images/Volvo_Right.png"); public Image left=Toolkit.getDefaultToolkit().createImage("images/Volvo_Left.png"); Volvo(boolean isRight,int number, int speed, int capacity,int duration) { super(isRight,number, speed,capacity,duration); lb=new JLabel(); ImageIcon ii=null; //选择车头朝向 if(isRight) {//如果车头向右 ii=new ImageIcon(this.right); this.currentP=LEFT_BOUND; }else { ii=new ImageIcon(this.left); this.currentP=RIGHT_BOUND; } ii.setImage(ii.getImage().getScaledInstance(80, 80, Image.SCALE_DEFAULT));//缩放到80x80 lb.setToolTipText("Volvo "+this.number);//鼠标移到上面有信息显示 lb.setVisible(true); lb.setIcon(ii); Expressway.panel_cars.add(lb); } protected void display(int x, int y) { //显示在panel_cars if( (this.isRight && x>=RIGHT_BOUND) || (!this.isRight && x<=LEFT_BOUND)) { if(this.isRight) {//到达终点后,终点队列的尾部中添加该车,路上的车链表删除该车,并减少在路上车辆的计数器 Expressway.XnVolvoQ.add(this); Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]Volvo "+this.number+" Arrived at Xi'An"); }else{ Expressway.BjVolvoQ.add(this); Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]Volvo "+this.number+" Arrived at BaoJi"); } for(int i=0;i<Expressway.volvosOnRoadNum;i++) { if(this.number==Expressway.volvosOnRoad.get(i).number) { Expressway.volvosOnRoad.remove(i); Expressway.volvosOnRoadNum--; this.isLaunched=false; this.lb.setVisible(false); break; } } this.headReverse(); } lb.setBounds(x,y,80,80); } protected void headReverse() { // TODO Auto-generated method stub //掉头之前清空ps链表 this.ps.clear(); this.isRight=!this.isRight; if(this.isRight){ ii=new ImageIcon(this.right); ii.setImage(ii.getImage().getScaledInstance(80, 80, Image.SCALE_DEFAULT));//缩放到80x80 lb.setIcon(ii); Expressway.panel_cars.add(lb); }else{ ii=new ImageIcon(this.left); ii.setImage(ii.getImage().getScaledInstance(80, 80, Image.SCALE_DEFAULT));//缩放到80x80 lb.setIcon(ii); Expressway.panel_cars.add(lb); } } protected void launch() { // TODO Auto-generated method stub if(Timer.min==30 && Timer.hour>=8 && Timer.hour<=17) {//8点30第一班,每小时一班,最后一班17点30 this.isLaunched=true; return; }else { return; } } protected void CarMoving() {//要伴随着Timer使用,每min移动一次 // TODO Auto-generated method stub this.display(this.currentP,0); if(this.isRight) { this.currentP += this.speed; }else { this.currentP -= this.speed; } } protected int CheckStop() { // TODO Auto-generated method stub //只有快到站才检查,否则浪费时间 int index=-1; if(this.isRight) { //前往西安方向各坐标近似取20 140 (240,250) (550,560) 660 780 890 if(this.currentP==140||this.currentP==240||this.currentP==550||this.currentP==660||this.currentP==780||this.currentP==890) { for(int i=0;i<this.ps.size();i++) { if(this.ps.get(i).destination==1&&this.currentP==140) { index=1; return index; }else if(this.ps.get(i).destination==2&&this.currentP==240) { index=2; return index; }else if(this.ps.get(i).destination==3&&this.currentP==550) { index=3; return index; }else if(this.ps.get(i).destination==4&&this.currentP==660) { index=4; return index; }else if(this.ps.get(i).destination==5&&this.currentP==780) { index=5; return index; }else if(this.ps.get(i).destination==6&&this.currentP==890) { index=6; return index; }else { return -1; } } }else { return -1; } }else { //前往宝鸡方向的各个坐标近似取20 140 (240,250) (550,560) 660 780 890 if(this.currentP==20||this.currentP==140||this.currentP==250||this.currentP==560||this.currentP==660||this.currentP==780) { for(int i=0;i<this.ps.size();i++) { if(this.ps.get(i).destination==0&&this.currentP==20) { index=0; return index; }else if(this.ps.get(i).destination==1&&this.currentP==140) { index=1; return index; }else if(this.ps.get(i).destination==2&&this.currentP==250) { index=2; return index; }else if(this.ps.get(i).destination==3&&this.currentP==560) { index=3; return index; }else if(this.ps.get(i).destination==4&&this.currentP==660) { index=4; return index; }else if(this.ps.get(i).destination==5&&this.currentP==780) { index=5; return index; }else { return -1; } } }else { return -1; } } return index;//如果是-1表示不需要停车 } protected void Stop(int index) { // TODO Auto-generated method stub //停2分钟的部分 if(index==-1&&this.temp==0) {//如果没有执行过stop并且index是-1,说明不需要停车 return;//第一次执行stop后,ps链表中已经没有需要下车的乘客了,下一分钟再执行checkstop后返回-1,但此时temp已经是1,所以函数不会返回 } this.isLaunched=false; Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+"Volvo"+this.number+" Stops"); this.temp++; if(this.temp==2) { this.temp=0; this.isLaunched=true;//isLaunched来控制汽车是否移动 Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+"Volvo"+this.number+" ReLauched!"); return; } //利用index来判断ps链表中哪些乘客需要下车 int count=0;//用来计数下车的乘客,最终输出到console中避免繁琐 //这里直接遍历ps链表,注意size会减少的情况 for(int i=0;i<this.ps.size();i++) { if(this.ps.get(i).destination==index) { this.ps.remove(i--);//必须减减,否则size()变小,遍历不全 count++; } } //根据index输出 switch(index) { case 0: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at BaoJi Station"); break; case 1: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at GaoZhen Station"); break; case 2: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at CaijiaPo Station"); break; case 3: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at WuGong Station"); break; case 4: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at XingPin Station"); break; case 5: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at XianYang Station"); break; case 6: Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]"+count+"Passengers"+" Arrived at Xi'An Station"); break; } } } public class Vehicles extends JPanel{ /** * 默认生成的序列号 */ private static final long serialVersionUID = 1L; }
折叠
4.5 Passenger.java
复制代码
java
package Expressway; public class Passenger { public boolean isBaoJi;//根据要求,只能在西安站或者宝鸡站等车 public int destination;//目的地,可以取一些离散的值 站点在Frame上坐标,分别是 /*20 140 245 555 660 780 890 *由于车辆速度不一,而且只能取整数 *对于Volvo:10像素每分钟,各个站点的坐标近似是 *20 140 (240,250) (550,560) 660 780 890 *对于Iveco: 7像素每分钟,各个站点的坐标近似是 *20 (139,146) (244,251) (552,559) (657,664) (776,783) (889,896) *890 (785,778) (666,659) (561,554) (246,239) (141,134) (22,15) * *于是前往西安方向的各站点坐标近似取 *20 139 244 552 657 783 889 *前往宝鸡方向的个站点坐标近似取 *22 141 246 554 659 778 890 * * * destination取值规定为Random类产生[0,6]的整数,分别代表宝鸡...西安 * */ public Passenger(boolean isBaoji,int destination){ this.isBaoJi=isBaoji; this.destination=destination; System.out.println("["+Timer.hour+":"+Timer.min+"]"+"乘客创建成功 是否在宝鸡站:"+this.isBaoJi+" 目的地: "+this.destination); } public boolean AboardIveco() {//成功上车返回true //如果是在宝鸡站 if(this.isBaoJi) { //上车的步骤,在发车前的瞬间上车 //在该站发车的车辆队列 中检查队首的车的 ps链表是否满,如果没有就上车,如果有就暂不执行 if((Timer.hour>=8 && Timer.hour<=17 && Timer.min%20==0) || (Timer.hour==18&&Timer.min==0)) {//Iveco发车时间,在执行launch之前执行该方法 if(Expressway.BjIvecoQ.peek()!=null) {//非空,避免异常 if(Expressway.BjIvecoQ.peek().ps.size() < Expressway.BjIvecoQ.peek().capacity) {//车上乘客数小于容量 Expressway.BjIvecoQ.peek().ps.add(this); //System.out.println("size()"+Expressway.BjIvecoQ.peek().ps.size()); //Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]Passenger Aboard the Iveco"+Expressway.BjIvecoQ.peek().number+"in BaoJi"); return true; } } } }else { if((Timer.hour>=8 && Timer.hour<=17 && Timer.min%20==0) || (Timer.hour==18&&Timer.min==0)) {//Iveco发车时间,在执行launch之前执行该方法 if(Expressway.XnIvecoQ.peek()!=null) { if(Expressway.XnIvecoQ.peek().ps.size() < Expressway.XnIvecoQ.peek().capacity) {//车上乘客数小于容量 Expressway.XnIvecoQ.peek().ps.add(this); //Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]Passenger Aboard the Iveco"+Expressway.XnIvecoQ.peek().number+"in Xi'An"); return true; } } } } return false; } public boolean AboardVolvo() {//成功上车返回true //如果是在宝鸡站 if(this.isBaoJi) { //上车的步骤,在发车前的瞬间上车 //在该站发车的车辆队列 中检查队首的车的 ps链表是否满,如果没有就上车,如果有就暂不执行 if(Timer.min==30 && Timer.hour>=8 && Timer.hour<=17) {//Volvo发车时间,在执行launch之前执行该方法 if(Expressway.BjVolvoQ.peek()!=null) { if(Expressway.BjVolvoQ.peek().ps.size() < Expressway.BjVolvoQ.peek().capacity) {//车上乘客数小于容量 Expressway.BjVolvoQ.peek().ps.add(this); //Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]Passenger Aboard the Volvo"+Expressway.BjVolvoQ.peek().number+"in BaoJi"); return true; } } } }else { if(Timer.min==30 && Timer.hour>=8 && Timer.hour<=17) {//Iveco发车时间,在执行launch之前执行该方法 if(Expressway.XnVolvoQ.peek()!=null) { if(Expressway.XnVolvoQ.peek().ps.size() < Expressway.XnVolvoQ.peek().capacity) {//车上乘客数小于容量 Expressway.XnVolvoQ.peek().ps.add(this); //Expressway.console.append("\n["+Timer.hour+":"+Timer.min+"]Passenger Aboard the Volvo"+Expressway.XnVolvoQ.peek().number+"in Xi'An"); return true; } } } } return false; } }
折叠
最后
感兴趣的可以关注我的微信公众号,第一时间收到动态
