@

写在前面

只是我的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界面中基本上是八股文代码,如下所示(仅供演示)

//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

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

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

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

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);
} @Override
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); } @Override
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); } } @Override
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;
} } @Override
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;
}
} @SuppressWarnings("unused")
@Override
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表示不需要停车 } @Override
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);
} @Override
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); } @Override
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); }
} @Override
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;
}
} @Override
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;
}
} @SuppressWarnings("unused")
@Override
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表示不需要停车
} @Override
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

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

最后

感兴趣的可以关注我的微信公众号,第一时间收到动态

Java模拟西宝高速公路的更多相关文章

  1. java模拟post请求发送json

    java模拟post请求发送json,用两种方式实现,第一种是HttpURLConnection发送post请求,第二种是使用httpclient模拟post请求, 方法一: package main ...

  2. php单点登录之模拟淘宝天猫同步登录

    说到单点登录大家都很了解,一个站点登录其他域会自动登录. 单点登录SSO(Single Sign On)的方法有很多,比如:p3p.共享session.共享cookice.第三方OAuth认证. 这里 ...

  3. java 模拟qq源码

    java 模拟qq源码: http://files.cnblogs.com/files/hujunzheng/QQ--hjzgg.zip

  4. java模拟开锁

    java模拟开锁 service qq:928900200 Introduction to Computer Science II: CSCI142Fall 2014Lab #1Instructor: ...

  5. Jsoup实现java模拟登陆

    Jsoup实现java模拟登陆 2013-10-29 14:52:05|  分类: web开发|举报|字号 订阅     下载LOFTER我的照片书  |     1:如何获取cookies. 1.1 ...

  6. [Java] 模拟HTTP的Get和Post请求

    在之前,写了篇Java模拟HTTP的Get和Post请求的文章,这篇文章起源与和一个朋友砍飞信诈骗网站的问题,于是动用了Apache的comments-net包,也实现了get和post的http请求 ...

  7. Java模拟登录系统抓取内容【转载】

    没有看考勤的习惯,导致我的一天班白上了,都是钱啊,系统也不发个邮件通知下....     为了避免以后还有类似状况特别写了个java模拟登录抓取考勤内容的方法(部分代码来自网络),希望有人修改后也可以 ...

  8. Java模拟登陆02【转载】

    在使用java访问URL时,如果该URL需要身份验证,那么就不能够直接访问,因为没有登陆.那么,如何解决这个问题呢?     方法是使用java模拟登陆,登陆后记录下cookie信息,在下次发起请求时 ...

  9. java模拟浏览器包selenium整合了htmlunit,火狐浏览器,IE浏览器,opare浏览器驱

    //如果网页源码中有些内容是js渲染过来的,那你通过HttpClient直接取肯定取不到,但是这些数据一般都是通过异步请求传过来的(一般都是通过ajax的get或者post方式).那么你可以通过火狐浏 ...

随机推荐

  1. 1903021116—吉琛—Java第六周作业—类的定义

    项目 内容 课程班级博客链接 19信计班 这个作业要求链接 第六周作业链接 java面向对象的概念和定义 博客名称 学号-姓名-Java第六周作业-题目自拟 要求 每道题要有题目,代码(使用插入代码, ...

  2. HCIE笔记-第六节-CIDR与ICMP

    项目部 58人 地址:194.2.3.128 /26 研发部 100人 地址: 194.2.3.0/25 市场部 27人 地址: 194.2.3.192/27 财务部 15人 地址:194.2.3.2 ...

  3. Java语言学习day23--7月29日

    今日内容介绍1.构造方法2.this关键字3.super关键字4.综合案例 ###01构造方法引入 * A:构造方法的引入 在开发中经常需要在创建对象的同时明确对象的属性值,比如员工入职公司就要明确他 ...

  4. 安全开发运维必备,如何进行Nginx代理Web服务器性能优化与安全加固配置,看这篇指南就够了

    本章目录 1.引言 1.1 目的 1.2 目标范围 1.3 读者对象 2.参考说明 2.1 帮助参考 2.2 参数说明 3.3 模块说明 3.服务优化 3.1 系统内核 3.2 编译优化 3.3 性能 ...

  5. 在django中使用orm来操作MySQL数据库的建表,增删改

    多张表之间的三种关系:一对一,一对多,多对多 创建表 一对一 xx = models.OneToOneField(to='表明',to_field='字段名',on_delete=models.CAS ...

  6. 深入了解 TiDB SQL 优化器

    分享嘉宾:张建 PingCAP TiDB优化器与执行引擎技术负责人 编辑整理:Druid中国用户组第6次大数据MeetUp 出品平台:DataFunTalk 导读: 本次报告张老师主要从原理上带大家深 ...

  7. [STL] queue 队列 priority_queue 优先队列

  8. Java 效率工具, 大幅度提高开发效率

    你是否有遇到过这样的情况,在开发过程中需要比较两列数据,但使用文本比对工具的话他是按行基准比对的,我还得对每列数据先进行排序,但排序又去哪里排, 想到 excel 可以排序 , 折腾下来,特别麻烦, ...

  9. axios源码解析 - 请求拦截器

    axios请求拦截器,也就是在请求发送之前执行自定义的函数. axios源码版本 - ^0.27.2 (源码是精简版) 平时在业务中会这样去写请求拦截器,代码如下: // 创建一个新的实例 var s ...

  10. Sentinel Dashboard 规则 持久化到Nacos

    本篇文章基于sentinel1.8.4版本进行改造的.本篇主要记录改造步骤 1.下载源码 https://github.com/alibaba/Sentinel 2.打开下载的sentinel,到se ...