@

写在前面

只是我的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. 2021牛客暑期多校训练营3 J 思维

    传送门 J-Counting Triangles_2021牛客暑期多校训练营3 (nowcoder.com) 题目 Goodeat finds an undirected complete graph ...

  2. Hyperledger Fabric 部署在多个主机上

    前言 在实验Hyperledger Fabric无排序组织以Raft协议启动多个Orderer服务.TLS组织运行维护Orderer服务中,我们已经完成了使用提供 TLS-CA 服务的 council ...

  3. 论文翻译:2020_TinyLSTMs: Efficient Neural Speech Enhancement for Hearing Aids

    论文地址:TinyLSTMs:助听器的高效神经语音增强 音频地址:https://github.com/Bose/efficient-neural-speech-enhancement 引用格式:Fe ...

  4. python学习-Day23

    目录 今日内容详细 logging模块(续集) 日志模块的主要组成部分 配置字典 配置字典在项目中的使用 第三方模块 如何利用工具下载第三方模块 查看当前解释器下载的第三方模块 下载第三方模块 直接使 ...

  5. pycharm 打包py程序为exe

    传送门 在终端输入 pyinstaller -F xxx.py -n 新名字 --noconsole --noconsole 去掉cmd命令窗口 -F 打包成一个文件 -D 打包成一个文件夹 -i 加 ...

  6. C# 核心

    C# 核心 面向对象编程概念 面向过程编程是一种以过程为中心的编程思想,分析出解决问题所需要的步骤,然后有函数把步骤一步一步实现,使用的时候一个一个依次调用. 面向对象是一种对现实世界理解和抽象的编程 ...

  7. Linux-交互式转化批处理工具expect

    expect 是由Don Libes基于 Tcl( Tool Command Language )语言开发的,主要应用于自动化交互式 操作的场景,借助 expect 处理交互的命令,可以将交互过程如: ...

  8. 不使用比较和条件判断实现min函数的一种方法

    不使用比较和条件判断实现min函数,参数为两个32位无符号int. 面试的时候遇到的题目,感觉很有意思. 搜了一下多数现有的解法都是仅有两种限制之一,即要么仅要求不能使用比较,要么仅要求不能使用条件判 ...

  9. 中间件漏洞之Apache

    中间件之Apache漏洞 我们常见的中间件有IIS.Apache.Nginx,其中Apache中间件有什么漏洞呢? Apache 解析漏洞: 漏洞原因:该解析漏洞属于用户配置问题(mime.types ...

  10. nodejs + typescript + koa + eslint + typescript eslint + prettier + webstorm

    ESLint 安装 yarn add -D eslint 生成配置文件 yarn eslint --init cli 选项 How would you like to use ESLint? To c ...