课程设计电梯控制系统

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

A1 系统描述
1.功能描述
本电梯系统用来控制一台运行于一个具有N层的大楼电梯,它具有上升、下降、开门、关门、载客的基本功能。

大楼的每一层都有:
(1)两个指示灯这两个指示灯分别用于指示当前所在的层数和电梯的当前状态(上行、下行或停止);
(2)电梯锁用于将本层的电梯门锁住,并使本楼层的电梯按钮失效,电梯里相应的按钮也失效,使得电梯不能也不可能停在本层;
(3)按钮除了第一层和顶层,每一层都有两个按钮(上行、下行),乘客可以呼叫上楼或下楼,顶楼只有一个下楼按钮,而第一层只有一个上楼按钮。

电梯里面具有:
(1)标示从“1”到“N”的N个按钮,用于让乘客选择所要的层数;
(2)关门按钮当乘客按下此按钮时,电梯门如果开着将关上,否则不执行任何操作;(3)开门按钮当乘客按下此按钮时,电梯如果停在某一层,电梯门将打开,否则不执行任何操作;
(4)超重测试和警报装置电梯的地面有超重感应装置,当电梯载重达到某一个值时,电梯“超重警报铃”发出超重警报,并且不执行关门命令。

2.关键实现方法描述
用“最大距离循环”来说明电梯的运行方式。

也说是说,电梯处于上行状态时就一直上行直到不再有上行任务,电梯处于下行状态时就一直下行直到不再有下行任务。

当电梯正在上行时,如果上行队列的队列头改变时,系统将同时将这个新的队列头发送给电梯作为它的新目的地。

有两种原因引起队列头的改变。

(1)新的请求插入到上行队列头。

(2)电梯到达某个楼层将这个楼层的请求从上行队列的队列头删除,后继的更高楼层号成为对列头。

当电梯正在下行时,如果下行队列的队列头改变时,系统将同时将这个新的队列头发送给电梯作为它的新目的地。

有两种原因引起下行队列头的改变。

(1)新的请求插入到下行队列头。

(2)电梯到达某个楼层将这个楼层的请求从下行队列的队列头删除,后继的更高楼层号成为对列头。

在电梯上行过程中,当上行队列中没有比电梯当前所在的楼层更高的楼层号时,发送电梯目的地的开始从下行队列中取得。

同样,在电梯下行过程中,当下行队列中没有比电梯当前所在的楼层更低的楼层号时,发送电梯目的地的开始从上行队列中取得。

如此反复,当两个队列中都没有数据时,电梯暂停。

当电梯到达某层时,此层的所有请求按钮全部复位(包括楼层和电梯里的按钮),电梯门自动开启,在一段时间内如果乘客没有按下开门或关门的按钮,电梯将自动关门。

为了保证电梯系统的安全,在任何不安全的情况下,紧急制动就会被促发,电梯被强制停止。

A2 用例模型
1.角色识别
根据前面系统的描述,可以确定与该系统交互的两个角色:电梯管理员(elevator
manager)和乘客(passenger),其中乘客是电梯的主要使用者,电梯管理员的责任
是对电梯进行维护(见图A1)。

图A1
2. 用例识别
在角色的基础上,可以确定系统的用例,做法是针对每一个角色考查它要求系统提供的功能,它使用系统的哪些功能,经过分析,可得到如下的用例。

乘客相关的用例:

按下某楼层的上行按钮(go up stair )。

● 按下某楼层的下行按钮(go down stair )。

● 按下某电梯内的某一层楼按钮(go to floor request )。

● 按下关门按钮 (close door )。

● 按下开门按钮(open door)。

● 超重测试(overweight test )。

电梯管理员的用例:
● 锁住某层电梯锁(lock floor )。

● 打开某层电梯锁(open floor )。

用例的描述如下:
用例1 按下某楼层的上行按钮(go up stair )
(1) 乘客按下第M 层的上行按钮。

(2) M 被插入到上行队列的合适位置。

(3) 如果M 被插到上行队列头。

● 如果电梯正处于上行状态。

将M 发送给电梯作为目的地。

● 如果电梯处于停止状态。

将M 发送给电梯作为目的地。

(4)电梯到达此楼层。

(5)电梯自动打开门(用例9)。

(6)乘客进入电梯。

(7)超重测试(用例6)。

用例2 按下某楼层的下行按钮(go down stair )。

(1) 乘客按下第M 层的下行按钮。

(2) M 被插入到下行队列的合适位置。

(3) 如果M 被插到下行队列头。

● 如果电梯正处于下行状态。

将M 发送给电梯作为目的地。

● 如果电梯处于停止状态 将M 发送给电梯作为目的地。

(4) 电梯到达此楼层。

(5)电梯自动打开门(用例9)。

(6)乘客进入电梯。

(7)超重测试(用例9)。

用例3 按下电梯内的某一楼层按钮(go to floor request)
(1)乘客按下电梯内L层的按钮。

(2)如果被按下的楼层号L比电梯当前所在的楼层号高。

●将此楼层号插入到上行队列的合适位置。

●如果L被插入到上行队列头。

如果电梯正处于上行状态。

将L发送给电梯作为电梯的目的地。

(3)如果被按下的层号L比电梯当前所在的楼层低。

●将此楼层号L插入到下行队列的合适位置。

●如果L被插入到下行队列头。

如果电梯正处于下行状态。

将L发送给电梯作为目的地。

(4)电梯到达目的楼层。

(5)电梯自动开门(用例9)。

用例4按下关门按钮(request close door)
(1)如果电梯门关着。

保持电梯门关闭状态。

(2)如果电梯门开着。

关闭电梯门。

用例5 按下开门按钮(request open door)
如果电梯停在某一层。

●如果电梯门关着。

打开电梯门。

●如果电梯门开着。

保持电梯门开状态。

用例6 超重测试(overweight test)
(1)乘客进入电梯。

(2)如果电梯超重感应装置检测到超重。

●电梯发出超重警报,并拒绝关闭电梯门。

●乘客走出电梯。

●电梯解除超重警报,并允许关闭电梯门。

用例7 锁住某层电梯锁(lock floor)
此层的楼层请求按钮和电梯内的楼层按钮失效。

用例8 打开某层电梯锁(open floor)
此层的楼层请求按钮和电梯内的楼层按钮恢复正常。

用例9 自动打开电梯门(auto open door)
(1)电梯到达某楼层。

(2)电梯自动开门。

用例10 自动关闭电梯门(auto close door)
(1)电梯门打开的状态达到设置的时限。

(2)关闭电梯门。

A3 类模型
根据分析,我们可以得到下面这些类。

乘客类(Passenger)、管理员类(Manager)、电梯类(Elevator)、电梯门类(ElevatorDoor)、楼层的上行请求按钮类(Go Up Request)、楼层的下请求按钮类(Go Down Request)、电梯里的楼层按钮类(Go To Floor Request)、楼层锁类(lock)、指示灯类(Indicate Light)、队列类(Queue)、定时器类(Timer)、异常处理类(Expection)。

1
2.管理员类(Manager)
3.电梯类(Elevator)
属性State表示电梯的状态(停止、上行、下行),Position表示电梯所在的楼层(1-N),IsOverWeight标识电梯是否超重,IsNormal用于标识电梯是否正常。

方法StartUp(Floor)表示启动电梯上行到Floor层,StartDown(Floor)表示启动电梯下行到Floor层,Stop表示电梯停下来,Warn()启动电梯超重警报,CancelWarn 取消电梯超重警报。

4.梯门类(ElevatorDoor)
属性State表示电梯门的状态(开或关),方法Open()表示打开电梯门,Close()表示关闭电梯门。

ElevatorDoor
State
Open()
Close
5.楼层的上行请求按钮类(Go Up Request)、楼层的下行请求按钮类(Go Down Request)、电梯里的楼层按钮类(Go To Floor Request)
属性State表示按钮是否已经被按下,Enabled表示按钮是否能用(如果被管理员锁住就不能用),OnFloor表示按钮对应的楼层号,方法Press()表示按下按钮,Reset()表示复位按钮,
6.指示灯类(Indicate Light)
指示灯分为楼层指示灯和电梯状态指示灯,其中State属性表示指示灯的状态(亮或灭)。

楼层指示灯有Show(Floor)方法用于显示电梯所在楼层数,电梯状态指示灯有Show(UporDown)方法用于显示电梯上行或下行。

7.楼层锁类(lock)
属性State表示楼层锁的状态(关或开),OnFloor表示锁所在的楼层数,方法On()表示开锁,Off()表示关锁。

LockFloor
State
OnFloor
On()
Off()
8.队列类(Queue)
队列类用于创建上行和下行队列,IsEmpty属性表示队列是否为空,方法Insert(Elevator)用于插入元素,DeleteHead()方法用于删除队列头元素,
Queue
IsEmpty
Insert(Elevator)
DeleteHead()
Send(HeadElement)
9
Time属性用于设置定时的时间长,StartTimer()方法用于启动计时,当计时结束时执行Doing()
Timer
Time
StartTimer()
Doing()
10
Type属性用语标识发生的异常类型,Source记录异常源,Doing()方法用于当发生异
Exception
Type
Source
Doing()
11.类关系图。

实训内容
实训内容一绘制电梯图形
实训目的
(1)学会使用Java.awt包中的Graphics类控制和显示用户自定义界面成分,如字体、
颜色和图形。

(2)掌握简单的图形动画效果。

实训要求
创建Applet程序,实现土5-1(a)所示简单的电梯二维图形,并当单击“开门“、“关门”按钮时实现图形上的关门、开门动作。

如图5-1(b)就是单击开门后正在开门的过程中。

实训指导
java.awt包提供了控制字体的Font类、控制颜色的Color类。

通过这两个类的属性的设置可以实现对界面上的字体和颜色的控制。

如closeDoor.setFont(new Font(“TimesRoman”,Font.BOLD,12));
这个语句将closeDoor上显示的文字颜色设置成红色。

Java.awt包还提供了用户绘图操作的类Graphics,其中包括了许多绘制文字和图形的相关方法。

使用Graphics类可以绘制线、圆和椭圆、矩形和多边形、显示图像、动画和各种字体。


draeLine(int x1,int y1,int x2,int y2),在坐标(x1,y1)、(x2,y2)之间画一条直线。

drawRect(int x,int y,int width,int height)方法和fillRect(int x,int y,int width,int height)方法分别用当前颜色在指定位置绘制一个矩形框和一个填充的矩形,其中参数x,y分别是矩形的左上角坐标;width,height分别用语指定矩形的宽和高。

DrawOval(int x,int y,int width,int height)方法和fillOval(int x,int y,int width,int height)方法可以在指定的矩形区域内绘制椭圆,其中的参数x、y、width、height分别表示矩形的左上角x、y坐标、宽和高。

要实现以上自定义成分,还要借助于Applet类的paint()方法,由该方法画出实际的图形。

当Applet运行时,将自动创建一个Graphics类的对象g,并把这个对象参数传递给paint()方法。

在paint()方法中,就可以调用Graphics类提供的绘制图形和文字的方法了。

下面是程序的实现部分。

import java.awt.*;
import java.applet.*;
public class Applet1 extends java.applet.Applet {
Button closeDoor=new Button("关门");
Button openDoor=new Button("开门");
int[] yPos={60,50,50,60,60};
int[] xPos={30,40,90,100,30};
int flag=2;
public void init() {
closeDoor.setFont(new Font("TimesRoman",Font.BOLD,12));
closeDoor.setForeground(new Color(255,0,0));
add(closeDoor);
openDoor.setFont(new Font("TimesRoman",Font.BOLD,12));
openDoor.setForeground(new Color(0,255,0));
add(openDoor);
}
public boolean action(Event e,Object o){
if(e.target==closeDoor){
flag=0;
}
else if(e.target==openDoor){
flag=1;
}
repaint();
return true;
}
public void paint(Graphics g){
g.setColor(new Color(150,150,50));
g.fillRect(30,60,70,90);
g.setColor(new Color(20,20,150));
g.fillPolygon(xPos,yPos,4);
g.setColor(new Color(190,150,150));
g.drawRect(30,60,70,2);
g.setColor(new Color(0,0,0));
g.drawOval(105,72,18,18);
g.setColor(new Color(0,0,255));
g.fillArc(101,75,27,27,60,60);
g.setColor(new Color(0,0,0));
g.drawOval(105,100,18,18);
g.setColor(new Color(0,0,255));
g.fillArc(102,88,27,27,-120,60);
if(flag==0){
g.setColor(new Color(150,40,40));
for(int i=0;i<=33;i++){
g.draw3DRect(30,63,1+i,86,true);
g.draw3DRect(99-i,63,1+i,86,true);
}
}
else if(flag==1){
g.setColor(new Color(150,40,50));
g.draw3DRect(30,63,34,86,true);
g.setColor(new Color(150,40,50));
g.draw3DRect(66,63,34,86,true);
g.setColor(new Color(150,150,40));
for(int i=0;i<=33;i++){
g.fillRect(64-i,63,2*i+1,86);
try{
Thread.sleep(100);
}
catch(InterruptedException e){
showStatus(e.toString());
}
}
}
else{
g.setColor(new Color(150,40,50));
g.draw3DRect(30,63,34,86,true);
g.setColor(new Color(150,40,50));
g.draw3DRect(66,63,34,86,true);
}
flag=2;
}
}
实训内容二实现电梯上下运行
实训目的
(1)掌握图像的装卸、显示的方法。

(2)掌握简单动画效果的实现。

实训要求
(1)如图5-2所示,装入一幅图像并显示出来。

(2)当单击“上行“按钮时,图像向上移动,直到上面的横线处停下。

(3)当单击“下行“按钮时图像向下移动,直到下面的横线处停下。

实训指导
要装入并显示一幅图像,需要有以下几个步骤。

①需要定义Image类的对象,如
Image Elevator_Image;
语句就是定义Image类的对象Elevator_Image。

②装载图像,如
Elevator_Image=getImage(getDocumentBase(),”Img01.gif”);
语句就是将图像Img01.gif装入到对象Elevator_Image中,其中getImage方法的第一个参数表示图像所在的目录,getDocumentBase()方法的功能是获取HTML文档所在的URL;第二个参数表示图像的文件名。

③显示图像,如
g.drawImage(Elevator_Image,50,ElePositonPix,this);
语句就是将装在对象Elevator_Image中的图像显示出来,第二个参数和第三个参数分别指示图像显示的左上角横坐标和纵坐标;最后一个参数是图像观察器,即显示该图像的容器对象。

另外,实现图像移动的鲜果是通过循环改变图像显示位置的纵坐标来实现的。

相应的程序如下所示
import java.awt.*;
import java.applet.*;
public class Applet2 extends java.applet.Applet {
Button upB=new Button("▲");
Button dnB=new Button("▼");
int flag=2;
Image Elevator_Image;
int ElePositionPix=80;
public void init() {
add(upB);
add(dnB);
Elevator_Image=getImage(getDocumentBase(),"Img01.gif"); }
public boolean action(Event e ,Object o){
if(e.target==upB)
{
flag=0;
}
else if(e.target==dnB)
{
flag=1;
}
repaint();
return true;
}
public void paint(Graphics g){
g.drawLine(10,40,140,40);
g.drawLine(10,250,140,250);
g.drawImage(Elevator_Image,50,ElePositionPix,this);
if(flag==0)
{
for(;ElePositionPix>=50;ElePositionPix--)
{
g.drawImage(Elevator_Image,50,ElePositionPix,this);
try{
Thread.sleep(100);
}
catch(InterruptedException e){
showStatus(e.toString());
}
}
}
else if(flag==1)
{
for(;ElePositionPix<=200;ElePositionPix++){
g.drawImage(Elevator_Image,50,ElePositionPix,this);
try{
Thread.sleep(100);
}
catch(InterruptedException e){
showStatus(e.toString());
}
}
}
}
}
实训内容三实现电梯控制仿真界面设计
实训目的
(1)学会使用各种容器组建,重点掌握Applet和Panel容器的使用。

(2)学会流式布局、网格布局、边框布局和网格袋布局这4种布局方式的界面设计。

实训要求
为了实现电梯控制的防真,需要设计出与实际电梯运行相似的界面,这个范例就是为实现电梯控制防真而设计一个界面。

如图6-2所示。

将这个界面分成3部分来看,左边部分代表一座楼,颜色深浅分别代表不同的楼层,F1~F6分别表示一楼到六楼,每个楼层都有标识着向上和向下箭头的按钮,分别表示上行和下行按钮;中间部分是电梯通道,绿色的方形图片表示电梯;界面的右边部分包含着“启动电梯”按钮、“关闭电梯”按钮、电梯位置指示、电梯内的楼层按钮板。

实训指导
(1)设置HTML文件中的Applet的显示尺寸wiidth和height为合适的值,如290和400。

方法如下:选择HTML文件,用鼠标右击打开弹出菜单,单击Open菜单选项,在代码编辑窗口中打开HTML文件。

然后选择Source选项卡,此时将看到一块灰色的区域,即Applet 的显示区域,在该区域上用鼠标右击打开弹出菜单,选择Always View AsText菜单项,以文本方式显示该区域的代码,修改width和height参数即可。

(2)回到Java Applet程序,向Applet容器设置成网格袋布局方式,添加3个Panel将界面从左到右分成3部分,并且使得右边和左边的Panel纵横都向外扩充,而中间部分的Panel不扩充。

(3)将左部分的面板设置成网格布局方式,并在这个面板中添加6个子面板,将这6个面板反别设置成不同的颜色,代表6个楼层。

(4)将这6个子面板设置成流式布局方式,并分别向这6个面板添加楼层标示和上行和下行按钮。

(5)将右部分的面板设置成网格布局方式,添加两个子面板将其分成上下两部分并分别设置背景和颜色;将上部分的子面板设置成网格布局方式,向其中添加如
图6-2所示的启动、关闭和状态显示信息;将下部分面板设置成边框布局方式,
并向其中添加相应的控制按钮。

(6)装入电梯模拟图片,在Applet的合适位置显示该图片。

实现此布局的完整程序代码如下:
import java.awt.*;
import java.applet.*;
public class Applet3 extends java.applet.Applet {
Panel Floor_Panel=new Panel();
Panel Elevator_Panel=new Panel();
Panel Indication_Panel=new Panel();
Panel Floor1_Panel=new Panel();
Panel Floor2_Panel=new Panel();
Panel Floor3_Panel=new Panel();
Panel Floor4_Panel=new Panel();
Panel Floor5_Panel=new Panel();
Panel Floor6_Panel=new Panel();
Label FloorLabel1=new Label("F1");
Label FloorLabel2=new Label("F2");
Label FloorLabel3=new Label("F3");
Label FloorLabel4=new Label("F4");
Label FloorLabel5=new Label("F5");
Label FloorLabel6=new Label("F6");
FloorButton UpButton1=new FloorButton(1,true,"∧"); FloorButton DnButton1=new FloorButton(1,false,"∨"); FloorButton UpButton2=new FloorButton(2,true,"∧"); FloorButton DnButton2=new FloorButton(2,false,"∨"); FloorButton UpButton3=new FloorButton(3,true,"∧"); FloorButton DnButton3=new FloorButton(3,false,"∨"); FloorButton UpButton4=new FloorButton(4,true,"∧"); FloorButton DnButton4=new FloorButton(4,false,"∨"); FloorButton UpButton5=new FloorButton(5,true,"∧"); FloorButton DnButton5=new FloorButton(5,false,"∨"); FloorButton UpButton6=new FloorButton(6,true,"∧"); FloorButton DnButton6=new FloorButton(6,false,"∨"); Panel SubInd_Panel1=new Panel();
Panel SubInd_Panel2=new Panel();
Panel SubInd_Panel3=new Panel();
Button Start_Button=new Button("启动电梯");
Button Stop_Button=new Button("关闭电梯");
Label Indication_Prompt=new Label("电梯所在层"); Label State_Prompt=new Label("电梯状态");
Label Indication_Light=new Label("1层");
Label State_Light=new Label("停止");
Label ETitleLabel=new Label("电梯内楼层按钮板"); Label EastLabel=new Label();
Label WestLabel=new Label();
Label SouthLabel=new Label();
DesFlButton DesFl_Button1=new DesFlButton(1,"1"); DesFlButton DesFl_Button2=new DesFlButton(2,"2"); DesFlButton DesFl_Button3=new DesFlButton(3,"3");
DesFlButton DesFl_Button4=new DesFlButton(4,"4"); DesFlButton DesFl_Button5=new DesFlButton(5,"5"); DesFlButton DesFl_Button6=new DesFlButton(6,"6"); Image eImage;
public void init() {
GridBagLayout gbl=new GridBagLayout();
GridBagConstraints gbc=new GridBagConstraints();
setLayout(gbl);
gbc.gridx=0;gbc.gridy=0;
gbc.gridwidth=1;
gbc.gridheight=1;
gbc.fill=GridBagConstraints.BOTH;
gbc.anchor=GridBagConstraints.WEST;
gbc.weightx=1;gbc.weighty=1;
gbc.insets=new Insets(0,0,0,0);
gbl.setConstraints(Floor_Panel,gbc);
add(Floor_Panel);
gbc.gridx=1;gbc.gridy=0;
gbc.gridwidth=1;
gbc.gridheight=1;
gbc.fill=GridBagConstraints.HORIZONTAL;
gbc.anchor=GridBagConstraints.NORTHWEST;
gbc.weightx=1;gbc.weighty=1;
gbc.insets=new Insets(0,0,0,0);
gbl.setConstraints(Elevator_Panel,gbc);
add(Elevator_Panel);
gbc.gridx=2;gbc.gridy=0;
gbc.gridwidth=1;
gbc.gridheight=1;
gbc.fill=GridBagConstraints.BOTH;
gbc.anchor=GridBagConstraints.EAST;
……………………………………….
SubInd_Panel3.add(DesFl_Button1);
SubInd_Panel3.add(DesFl_Button2);
SubInd_Panel3.add(DesFl_Button3);
SubInd_Panel3.add(DesFl_Button4);
SubInd_Panel3.add(DesFl_Button5);
SubInd_Panel3.add(DesFl_Button6);
eImage=getImage(getDocumentBase(),"Img02.gif");
}
public void paint(Graphics g){
g.drawImage(eImage,300,366,this);
}
}
class FloorButton extends Button
{
int Floor;
boolean IsUp;
FloorButton(int VFloor,boolean VIsUp,String VLabel){
super(VLabel);
Floor=VFloor;
IsUp=VIsUp;
}
public int getFloor(){
return Floor;
}
}
class DesFlButton extends Button{
int Floor;
DesFlButton(int VFloor,String VLabel)
{
super(VLabel);
Floor=VFloor;
}
public int getFloor(){
return Floor;
}
}
实训内容四电梯控制模拟系统的异常定义和处理
实训目的
(1)理解异常的工作方式。

(2)学会创建异常类、对异常的捕获和处理。

实训要求
(1)创建电梯超重的异常类、电梯在楼层间(层与层之间)停止运行的异常类和非停止状态下开门的异常类。

(2)在程序中实现上述异常的捕获和处理。

实训指导
在电梯控制系统中,异常处理极其重要,因为这关系到人身安全的问题。

大体上电梯的异常电梯超重、电梯在楼层之间(层与层之间)停止运行和非停止状态下开门有3种;当电梯出现以上这些异常时,需要进行异常处理,如报警。

为了简化程序,这里把电梯运行控制的程序省略了。

我们创建3个按钮,单击这3
个按纽时分别产生以上3类异常(模仿电梯产生这3类异常),并对产生的异常进行处理。

首先需要定义异常类,异常类的定义形式如下:
class 自定义异常类名extends Exception
{
自定义异常的构造方法
其他方法
}
自定义异常类必须作为Exception类的子类被定义。

当系统处于某种情况即说明系统发生了异常,这时需要使用如下方法抛出异常。

If(某种条件成立)
{
throw(new z自定义异常构造方法);
}
系统抛出异常后,还需要对异常进行捕获,并对异常作出处理,如下是异常的捕获和处理方法。

try
{
可能抛出异常的语句组;
}
catch(异常类名异常对象名参数)
{
异常处理语句组;
}
下面给出了电梯超重的异常定义及异常处理捕获的程序,关于电梯的停止和开门的异常定义及捕获与此相类似。

import java.awt.*;
import java.applet.*;
public class Applet4 extends java.applet.Applet {
Button OverW_B=new Button("运行");
TextField Weight_T=new TextField(8);
Button ExcepStop_B=new Button("停止");
Button ExcepOpen_B=new Button("开门");
TextField Prompt_T=new TextField(50);
public void init() {
add(OverW_B);
add(Weight_T);
add(ExcepStop_B);
add(ExcepOpen_B);
Prompt_T.setEditable(false);
add(Prompt_T);
}
public boolean action(Event e,Object o){
if(e.target==OverW_B)
{
try{
start_El();
}
catch(OverWeightExpception Obl){
Prompt_T.setText(Obl.toString());
}
}
return true;
}
public void start_El() throws OverWeightExpception
{
if(Integer.parseInt(Weight_T.getText())>3000)
{
throw(new
OverWeightExpception(Integer.parseInt(Weight_T.getText())));
}
else
{
Prompt_T.setText("电梯正常启动");
}
}
}
class OverWeightExpception extends Exception
{
private int Weight=0;
OverWeightExpception()
{
super("电梯超重,不能正常运行!");
}
OverWeightExpception(int TmpWeight)
{
Weight=TmpWeight;
}
public String toString()
{
String TmpStr;
if(Weight>0)
TmpStr="电梯当前的承重为"+Integer.toString(Weight)+"Kg,超过了电梯的最大载重3000Kg";
else
TmpStr="电梯超重!";
return TmpStr;
}
}
实训内容五完成电梯的控制运行功能
实训目的
(1)掌握多线程编程思维。

(2)学会控制多线程的运行,并进一步加强较复杂程序的编写。

实训要求
在第6章中的实训范例一中,我们完成了电梯控制界面的程序编写。

现在要在这个界面色基础上实现真正的电梯控制功能,既当单击某一层楼的按钮时,电梯模拟图片实现上下运动。

实训指导
电梯的运行程序控制实际上由两部分组成:
(1)电梯的任务管理程序;
(2)电梯的任务监控程序。

这两部分程序通过对两个队列(上行队列和下行队列)的读写来实现数据通信。

任务管理程序在负责管理操作界面,如按下按钮时按钮变成红色、电梯到达某层时相应的按钮复位;另外,当按钮被按下时,任务管理程序负责将数据插入到队列中的合适位置。

任务监控程序时刻监控着上行和下行队列,负责读取队列中的数据作为电梯的目的楼层,并且还负责电梯的实际运行过程,如什么时候该上行、什么时候该下行、什么时候要改变电梯的状态等。

上行队列和下行分别存放电梯的上行任务和下行任务,所谓的上行任务表示需要电梯向上运行的任务,下行任务表示需要电梯向下运行的任务。

为了使监控程序一直处于运行状态,我们在run()方法中用while(true)的永真循环来实现。

另外,几个常用的线程类方法需要熟练使用。

●public void start():启动线程。

●public void suspend():将线程挂起。

●public void resume():将线程从挂起状态恢复成就绪状态。

●public void stop():使线程进入死亡状态。

下面是参考程序:
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class Applet5 extends java.applet.Applet implements ActionListener,Runnable{ Panel Floor_Panel=new Panel();
Panel Elevator_Panel=new Panel();
Panel Indication_Panel=new Panel();
Panel Floor1_Panel=new Panel();
Panel Floor2_Panel=new Panel();
Panel Floor3_Panel=new Panel();
Panel Floor4_Panel=new Panel();
Panel Floor5_Panel=new Panel();
Panel Floor6_Panel=new Panel();
Label FloorLabel1=new Label("F1");
Label FloorLabel2=new Label("F2");
Label FloorLabel3=new Label("F3");
Label FloorLabel4=new Label("F4");
Label FloorLabel5=new Label("F5");
Label FloorLabel6=new Label("F6");
FloorButton UpButton1=new FloorButton(1,true,"∧");
FloorButton DnButton1=new FloorButton(1,false,"∨");
FloorButton UpButton2=new FloorButton(2,true,"∧");
FloorButton DnButton2=new FloorButton(2,false,"∨");
FloorButton UpButton3=new FloorButton(3,true,"∧");
FloorButton DnButton3=new FloorButton(3,false,"∨");
FloorButton UpButton4=new FloorButton(4,true,"∧");
FloorButton DnButton4=new FloorButton(4,false,"∨");
FloorButton UpButton5=new FloorButton(5,true,"∧");
FloorButton DnButton5=new FloorButton(5,false,"∨");
FloorButton UpButton6=new FloorButton(6,true,"∧");
FloorButton DnButton6=new FloorButton(6,false,"∨");
Panel SubInd_Panel1=new Panel();
Panel SubInd_Panel2=new Panel();
Panel SubInd_Panel3=new Panel();
Button Start_Button=new Button("启动电梯");
Button Stop_Button=new Button("关闭电梯");
Label Indication_Prompt=new Label("电梯所在层");
Label State_Prompt=new Label("电梯状态");
……………………………………………………………………
Elevator_Image=getImage(getDocumentBase(),"Img02.gif");
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource() instanceof FloorButton)
{
FloorButton vfb=(FloorButton)(e.getSource());
if(vfb.IsUp)
if((theElevator.getPosition()>=vfb.Floor)&&(theElevator.getState()==1))
EUpQueue.InsertData(vfb.Floor,false);
else
EUpQueue.InsertData(vfb.Floor,true);
else
if((theElevator.getPosition()<=vfb.Floor)&&(theElevator.getState()==-1))
EDnQueue.InsertData(vfb.Floor,false);
else
EDnQueue.InsertData(vfb.Floor,true);
vfb.setBackground(Color.red);
}
else if(e.getSource() instanceof DesFlButton)
{
DesFlButton vfb=(DesFlButton)(e.getSource());
if(vfb.Floor>theElevator.Position)
EUpQueue.InsertData(vfb.Floor,true);
else if(vfb.Floor<theElevator.Position)
EDnQueue.InsertData(vfb.Floor,true);
else
if(vfb.Floor==theElevator.Position)
{
if(theElevator.getState()==-1)
EUpQueue.InsertData(vfb.Floor,true);
}
vfb.setBackground(Color.red);
}
else if(e.getSource()==Start_Button)
{
Start_Button.setBackground(Color.red);
Start_Button.setEnabled(false);
Stop_Button.setBackground(Color.lightGray);
Start_Button.setEnabled(true);
resume();
}
else if(e.getSource()==Stop_Button)
{
Start_Button.setBackground(Color.lightGray);
Stop_Button.setBackground(Color.red);
Start_Button.setEnabled(false);
suspend1();
}
}
public void start()
{
isSuspend=false;
t2.start();
}
public void suspend1()
{
isSuspend=true;
EUpQueue.ClearQueue();
EDnQueue.ClearQueue();
ResetState();
if((366-ElePositionPix)!=0)
EUpQueue.InsertData(1,true);
else
{
Start_Button.setEnabled(true);
suspend();
}
}
public void suspend()
{
try{
t2.suspend();
}catch(SecurityException e){}
}
public void resume()
{
isSuspend=false;
EnabledState();
t2.resume();
}
public void stop()
{
if(t2.isAlive())
t2.stop();
}
void ResetState()
{
UpButton1.setBackground(Color.lightGray);
UpButton2.setBackground(Color.lightGray);
UpButton3.setBackground(Color.lightGray);
UpButton4.setBackground(Color.lightGray);
UpButton5.setBackground(Color.lightGray);
DnButton2.setBackground(Color.lightGray);
DnButton3.setBackground(Color.lightGray);
DnButton4.setBackground(Color.lightGray);
DnButton5.setBackground(Color.lightGray);
DnButton6.setBackground(Color.lightGray);
DesFl_Button1.setBackground(Color.lightGray);
DesFl_Button2.setBackground(Color.lightGray);
DesFl_Button3.setBackground(Color.lightGray);
DesFl_Button4.setBackground(Color.lightGray);
DesFl_Button5.setBackground(Color.lightGray);
DesFl_Button6.setBackground(Color.lightGray);
UpButton1.setEnabled(false);
UpButton2.setEnabled(false);
UpButton3.setEnabled(false);
UpButton4.setEnabled(false);
UpButton5.setEnabled(false);
DnButton2.setEnabled(false);
DnButton3.setEnabled(false);
DnButton4.setEnabled(false);
DnButton5.setEnabled(false);
DnButton6.setEnabled(false);
DesFl_Button1.setEnabled(false);
DesFl_Button2.setEnabled(false);
DesFl_Button3.setEnabled(false);
DesFl_Button4.setEnabled(false);
DesFl_Button5.setEnabled(false);
DesFl_Button6.setEnabled(false);
}
………………………………………………………………. class FloorButton extends Button
{
int Floor;
boolean IsUp;
FloorButton(int VFloor,boolean VIsUp,String VLabel){ super(VLabel);
Floor=VFloor;
IsUp=VIsUp;
}
public int getFloor(){
return Floor;
}
}
class DesFlButton extends Button{
int Floor;
DesFlButton(int VFloor,String VLabel)
{
super(VLabel);
Floor=VFloor;
}
public int getFloor(){
return Floor;
}
}
abstract class TQueue
{
int EndPointer;
int EndPrePointer;
int StackArray[]=new int[100];
TQueue()
{
for(int i=0;i<=99;i++)
{
StackArray[i]=0;
}
EndPointer=-1;
EndPrePointer=-1;
}
public int GetEndPointer()
{
return EndPointer;
}
public int GetEndPrePointer()
{
return EndPrePointer;
}
public void SetEndPointer(int VPointer)
{
EndPointer=VPointer;
}
public void SetEndPrePointer(int VPrePointer)
{
EndPrePointer=VPrePointer;
}
public abstract boolean InsertData(int Data,boolean VPre);
public boolean DeleteData(int VPointer)
{
if( EndPointer!=-1)
{
if((VPointer>EndPointer)||(VPointer<0))
return false;
for(int i=VPointer;i<=EndPointer;i++)
StackArray[i]=StackArray[i+1];
EndPointer--;
if(VPointer<=EndPrePointer)
{
EndPrePointer--;
}
}
return true;
}
public boolean ClearQueue()
{
for(int i=0;i<=99;i++)
{
StackArray[i]=0;
}
EndPointer=-1;
EndPrePointer=-1;
return true;
}
public int GetData(int VPointer)
{
if((VPointer>EndPointer)||(VPointer<0))
return -1;
return StackArray[VPointer];
}
}
实训小结(不少于400字)。

相关文档
最新文档