📄 modoul.java
字号:
/** 程序主模块
Modoul 类为Applet子类
实现ActionListener接口,以响应用户点击目的楼层按扭
实现Runnable接口,将Modoul 的实例变量appletThread作为主线程
为NewPerson提供当前楼层与目的楼层参数
为Elevatorse提供当前楼层,并设置它的目的楼层,从而控制电梯的运作
为TestImage提供平移图片的起始点坐标,Modoul 的实例,以及当前层
其中appletThread 与 elevatorThread同步进行
实现者:谢黎明
*/
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Button;
import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Image;
public class Modoul extends Applet implements ActionListener,Runnable{
Image myImage[] = new Image[5]; // 绘出等待电梯的人,有5个备选图片
int xPos;
int yPos =0;
// 5个图片
String[] bizGif = {"myPic\\biz01.jpg","myPic\\biz02.jpg",
"myPic\\biz03.jpg","myPic\\biz04.jpg","myPic\\biz05.jpg"};
Button button1;
Button[] button = new Button[4]; // 目的层选择按钮
Button[] light = new Button[4]; // 作召唤灯之用
private int allFloors = 0; // 楼层总数
private int incrFloor = 0; // 楼层之间的高度
int currentFloor=0;
int destination;
int oldElevator = 1; // 电梯上一次的位置
int numberOfPerson = 0; // 当前产生的人号
int currentPerson = 0; // 当前处理的人
final int MAX_MAN = 4; // 最大人数限制
NewPerson[] newPerson = new NewPerson[4]; // 产生新人后,入此数组
Elevatorse elevatorThread; // 声明电梯类的对象
private Thread appletThread = null;
public int[] atCurrent = new int[4]; //记录有人的层。数组每一项与对应层等待人数对应
public int[] goDestination = new int[4]; //记录目的层。数组每一项与去对应层的人数对应
public void init(){
allFloors = 4; // 设置总层数为4
setLayout(null); // 布局器设为空
button1 = new Button("New Person");
add(button1);
button1.addActionListener(this); // 添加监听器
button1.setBounds(20,20,120,20); // 设置范围
button1.setBackground(Color.green); // 设置背景色
for(int i=1;i<=allFloors;++i){ // 初始化操作
button[i-1] = new Button(String.valueOf(i)); // 创建目的楼层按扭
add(button[i-1]);
button[i-1].addActionListener(this); // 添加监听器
button[i-1].setBounds(650,100+(5-i)*50,50,50);// 设置范围
button[i-1].setBackground(Color.orange); // 设置背景色
light[i-1] = new Button(); // 创建召唤按扭。只作召唤灯,并没有添加监听器
add(light[i-1]);
light[i-1].setBounds(250,i*135-80,40,40);
light[i-1].setBackground(Color.lightGray);
atCurrent[i-1] = 0;
goDestination[i-1] = 0;
Same.floorDraw[i-1] = false;
}
for(int i=0;i<bizGif.length;++i){
myImage[i]= getImage(getCodeBase(),bizGif[i]);
System.out.println("myImage");
}
setBackground(Color.white); // 设置屏幕背景色为白色
}
public void start (){
elevatorThread = new Elevatorse();
elevatorThread.start(); // 启动电梯线程
if(appletThread == null){
appletThread = new Thread(this,"Applet");
appletThread.start(); // 启动主线程
}
}
public void run() {
elevatorThread.goal = 1; // 电梯的目的楼层,初始为1。即电梯停在一楼
Thread newThread = Thread.currentThread();
while(appletThread == newThread){
if( atCurrent[elevatorThread.elevatorCurrentFloor -1] != 0){
elevatorThread.upOrDown = 0; // 让电梯线程等待
repaint();
continue;
}
while(elevatorThread.upOrDown != 0){ //与电梯线程实现同步,
//elevatorThread.upOrDown不为0时,转电梯线程
try{
//wait(); // 不在同一类的实例中,故不可用wait,notifyAll
Thread.sleep(1000);
} catch (InterruptedException e){
}
}
for(int i=0;i<allFloors;++i){ // 确定电梯的目的楼层
if(newPerson[i] != null && newPerson[i].getDestination() ==0){
elevatorThread.goal = newPerson[i].currentFloor;
break;
}
else if(newPerson[i] != null && newPerson[i].getDestination() !=0){
elevatorThread.goal = newPerson[i].getDestination();
break;
}
if( i==3){ // 电梯空闲
elevatorThread.goal = 1;
}
}
if(elevatorThread.goal > elevatorThread.elevatorCurrentFloor) {
elevatorThread.upOrDown = 1; // 电梯运动方向--向上
}
else if( elevatorThread.goal < elevatorThread.elevatorCurrentFloor){
elevatorThread.upOrDown = -1; // 电梯运动方向--向下
}
repaint();
}
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==button1){ //press the NewPerson buton
currentFloor = (int)(Math.random()*10+1);
while(currentFloor > allFloors || newPerson[4-currentFloor] != null){
currentFloor = (int)(Math.random()*10+1);
} // 加入循环 重复使用数组
for(int i=0;i<allFloors;++i){
if(newPerson[i] == null){
newPerson[i] = new NewPerson(currentFloor,incrFloor,allFloors);
// 创建动画线程
/* TestImage()函数中参数说明:
0: 表示起始点横坐标
getSize().height-595+incrFloor*(4-currentFloor) : 表示纵坐标
130 :表示终点横坐标
this :Modoul的当前实例
currentFloor : 当前层
*/
(new TestImage(0,getSize().height-595+incrFloor*(4-currentFloor),130,this,currentFloor)).start();
try{
Thread.sleep(500);
} catch (InterruptedException ex){
}
light[4-currentFloor].setBackground(Color.red); // 召唤灯亮
atCurrent[currentFloor-1]++; // 记录当前层等待人数
break;
}
}
}
if( e.getSource() == button[0] && elevatorThread.elevatorCurrentFloor != 1){
// 按下目的楼层按扭'1'
dealActionPerform(0);
}
if(e.getSource() == button[1] && elevatorThread.elevatorCurrentFloor != 2 ){
// 按下目的楼层按扭'2'
dealActionPerform(1);
}
if(e.getSource() == button[2] && elevatorThread.elevatorCurrentFloor != 3 ){
// 按下目的楼层按扭'3'
dealActionPerform(2);
}
if(e.getSource() == button[3] && elevatorThread.elevatorCurrentFloor != 4 ){
// 按下目的楼层按扭'4'
dealActionPerform(3);
}
repaint();
}
private void dealActionPerform( int buttonNumber){ // buttonNumber 表示目的楼层
for(int i=0;i<allFloors;++i){
if(newPerson[i] != null && newPerson[i].currentFloor == elevatorThread.elevatorCurrentFloor){
if(newPerson[i].getDestination() != 0){
continue;
}
newPerson[i].setDestination(buttonNumber+1); // 设置newPerson 的目的楼层
// newPerson[i].inOrOut = true;
button[buttonNumber].setBackground(Color.red);// 目的楼层按扭变亮
atCurrent[newPerson[i].currentFloor - 1]--; // 选一次目的楼层后,当前层人数减1
goDestination[buttonNumber]++; // 选一次目的楼层后,目的层人数加1
int j;
for(j=i+1;j<allFloors;++j){
if(newPerson[j] != null&&newPerson[i].currentFloor == newPerson[j].currentFloor){
break;
}
}
if( j==allFloors || atCurrent[newPerson[i].currentFloor -1] ==0){
light[4-newPerson[i].currentFloor].setBackground(Color.lightGray);//召唤灯恢复
}
break;
}
}
}
public void paint(Graphics g){
int i,j;
System.out.println(currentFloor);
incrFloor=540/allFloors; // 计算楼层间的高度
g.drawString("请在此处选择目的层",620,120); // 输出提示信息
for(i=0;i<allFloors;++i){
if(atCurrent[i] == 0){
Same.floorDraw[i] = false;
light[3-i].setBackground(Color.lightGray); // light up to down 0->3
g.clearRect(0,getSize().height-600+incrFloor*(3-i)+5,300,incrFloor-5);
}
else if(Same.floorDraw[i] == true){ // 绘出等待的人
g.drawImage(myImage[0],150,incrFloor*(3-i)+50,myImage[0].getWidth(this),myImage[0].getHeight(this),this);
}
}
g.drawRect(300,getSize().height-600,getSize().width-500,getSize().height-100);
for(i=0,j=getSize().height-600+incrFloor;i<allFloors;++i){ // 绘制楼层
g.drawLine(0,j,getSize().width-200,j);
j+=incrFloor;
}
for(i=0;i<MAX_MAN;++i){
if(newPerson[i] != null){
if( newPerson[i].getDestination() == elevatorThread.elevatorCurrentFloor){
// 到达目的楼层时,恢复目的楼层按扭状态
button[newPerson[i].getDestination()-1].setBackground(Color.orange);
for( int w=0;w<goDestination[newPerson[i].getDestination()-1];++w){
// 出电梯动画线程启动
/* TestImage()函数中参数说明:
130: 表示起始点横坐标
getSize().height-595+incrFloor*(4-newPerson[i].getDestination()) : 表示纵坐标
0 :表示终点横坐标
this :Modoul的当前实例
newPerson[i].getDestination() : 当前层
*/
(new TestImage(130,getSize().height-595+incrFloor*(4-newPerson[i].getDestination()),0,this,newPerson[i].getDestination())).start();
try{
Thread.sleep(150);
} catch (InterruptedException e){
}
}
goDestination[newPerson[i].getDestination()-1] = 0;
newPerson[i] = null; // 完成此人请求后,将此人所占资源回收
}
}
}
/*若电梯运动,擦除原先的图形*/
if(oldElevator != elevatorThread.elevatorCurrentFloor){
// elevatorLight[ oldElevator -1].setBackground(Color.white);
g.setColor(Color.white);
g.fillRect(301,getSize().height-600+(4-oldElevator)*incrFloor+1,getSize().width-501,incrFloor-1);
}
// elevatorLight[elevatorThread.elevatorCurrentFloor-1].setBackground(Color.red);
g.setColor(Color.gray); /*重新绘制电梯*/
g.fillRect(301,getSize().height-600+(4-elevatorThread.elevatorCurrentFloor)*incrFloor+1,getSize().width-501,incrFloor-1);
oldElevator = elevatorThread.elevatorCurrentFloor;
for(i =0;i<allFloors;++i){
if(atCurrent[i] == 0 ){
g.clearRect(10,incrFloor*(3-i)+50,60,incrFloor-15); // 刷新楼层外区域
}
}
}
public void update(Graphics g) {
paint(g);
}
public void stop() {
Elevatorse.stopThread = true; // 结束电梯线程
appletThread = null; // 结束主线程
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -