首页 > 代码库 > 电梯调度 结对开发项目

电梯调度 结对开发项目

电梯调度模拟程序

二:项目参与人员:

周其范 胡宝月

三:项目开发语言和工具:

Java语言和eclipse,涉及内容:面向对象技术、基于Swing的图形化用户界面、多线程启动和休眠

四:问题陈述:

1、电梯要正常运行,能响应内部、外部按钮

2、要怎样选择哪部电梯电梯,使乘坐者和电梯的距离更近,已达到更省电、更快、更经济。

3、同一部电梯可以响应多位乘客的请求

五:任务需求:

1、要模拟一栋6层楼中两部电梯的调度,模拟乘坐电梯的过程.

2、乘坐者在最低层楼:只能乘坐电梯上楼,在电梯内部按下要去的楼层。

3、乘坐者在中间层:可以乘坐电梯上楼和下楼,在电梯内部按下要去的楼层。

4、乘坐者在最上层:只能乘坐电梯下楼,在电梯内部按下要去的楼层。

5、在同一部电梯内部中,乘坐者的目的地不同。例如,有人要上5楼,有的人要上6楼。

6、在界面中要显示电梯的状态:所在楼层和上楼还是下楼。

7、电梯开门3秒,电梯运行速度1.5秒每层,电梯到达目的楼层时,开门3秒后才关门,当乘客发出请求后1秒,电梯才运行

六:任务描述:

1、根据2部电梯的运行状态,寻找离当前楼层最近,并和请求同方向的电梯,给予响应,将任务分配给此电梯。

2、每个电梯如果在它的上层或者下层没有相应请求的情况下,则在原地保持不动。所有电梯的初始状态都在第一层。

3、每个电梯内部均有数字键、关门键、开门键、所在楼层显示及运行状态显示。

4、 每部电梯都有所在楼层显示及运行状态显示。

5、电梯外部要显示电梯所在楼层和运行状态,每层楼的电梯门处要显示所在楼层和上、下键按钮

 ---------------- 下面介绍一下我们的程序主要界面---------------

程序开始界面

 

左侧是电梯外部界面,

例如,如果在四楼要下,则在四楼按下

如果在四楼下,则按下

开门键:

关门键

此界面显示电梯状态的初始状态:显示楼层按钮

显示运行状态的按钮为

程序运行界面:

表示目的地楼层;

表示正在开门;

表示电梯内部显示电梯运行状态和显示楼层

 表示电梯和电梯外部运行状态和显示楼层。

 

主要类和方法介绍:

 

class Found extends Thread //任务分配线程

实现了寻找哪部电梯最省的功能,主要成员如下:

public void addTask(int i, boolean flag)//添加任务

      将任务添加到任务列表中

class Task//任务:要到几楼,上去还是下去 

内部类,包括目标楼层、要上楼还是下楼

public void run()//线程体

实现了寻找哪部电梯最省的功能

如果上楼,并且电梯的状态是暂停的或者电梯正在从下往上运行,则计算目标楼层与电梯当前楼层之间的距离,判断这个距离是否比另一个电梯与目标楼层的距离小。如果是,则将线程分配给这个电梯,然后等此线程运行完毕后(调用),将此任务从目的地列表里移除。否则,将线程分配给另一个电梯。

 

线程休眠一秒才运行,1秒后才执行任务,意思是乘坐者请求任务后,1秒钟后,电梯才开始运行

 

class Elevator extends Thread //电梯主类

 

此类继承了thread类,其构造方法构造2部楼梯的界面,主要成员如下:

 

public void addFloor(int i) //响应外部按钮

 

此方法响应乘坐者在电梯外部请求,将分配到此电梯的任务加入到目的地列表destinations中。

 

public void wantToFloor(int i) //响应内部按钮

 

此方法响应乘坐着在电梯内部的请求,将符合当前运行状态的楼层加入到目的地列表destinations中,不符合的不予处理。

 

public void setStateB() //设置运行状态按钮

 

此方法实现了显示电梯外部、电梯、电梯内部的运行状态按钮。电梯在上时显示“上”,否则显示“下”,初始状态是“---

 

public void run()

 

run()方法是线程体,根据当前电梯运行状态state,决定电梯的运行处理,通过对界面中楼层颜色的改变来表示电梯的运行状态此方法通过sleep()休眠线程,来设置开门时间,电梯速度。此方法完成了电梯外部、电梯、电梯内部显示楼层功能。

 

class CanvasOuter extends JPanel //显示外部按钮的画布类,位于左

 

 

 

电梯外部界面显示,将其设置在总界面的左侧。其中有上行按钮监听器(class UpAction implements ActionListener)和下行按钮监听器(class DownAction implements ActionListener)。  

 

class CanvasInner extends JPanel //显示内部按钮的画布,位于右侧

 

电梯内部部界面显示,将其设置在总界面的右侧。其中有要去楼层数字键按钮监听器(class goFloor implements ActionListener)、开门键监听器(class OpenAction implements ActionListener)、关门键监听器(class CloseAction implements ActionListener)。

 

 

 

 

 

 

-----------下面是完成设计的时间安排------------

 

时间日期 周其范 胡宝月
3.4 春晖楼体验电梯 春晖楼体验电梯
3.6 分析题目,确定用java完成 分析题目,确定用java完成
3.8 设计界面 构建类成员和具体方法
3.10—3.15 完成界面和代码连接 类的具体实现
3.16——3.19 完善整个程序,并对设计中存在的问题进行修改 完善整个程序,并对设计中存在的问题进行修改
3.21 确认完成,整个项目完成 确认完成,整个项目完成

 

--------下面是实验代码--------

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;

public class TestElevator
{
    public static void main(String[] args)
    {
        SimpleFrame frame = new SimpleFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //退出模式,退出应用程序后的默认窗口关闭操作
        frame.setLocation(40, 40);    //窗口位置坐标
        frame.show();
    }
}

class SimpleFrame extends JFrame
{
    public SimpleFrame()
    {
        setSize(690, 510);
        setTitle("电梯模拟");
        SimplePanel panel = new SimplePanel();
        this.add(panel);
    }
}

class SimplePanel extends JPanel
{
    private CanvasOuter myCanvasOuter;//显示外部按钮的画布类,位于左侧
    private CanvasInner myCanvasInner;//显示内部按钮的画布类,位于右侧

    private Elevator[] s;//电梯数组
    private Found foundThread = new Found();//任务分配线程

    public final static int NUM = 2; //电梯数
    public final static int FLOOR = 6; //楼层
    
    final int UP = 0; //电梯状态初始化
    final int DOWN = 1;
    final int PAUSE = 2;
    final int OPEN = 3;
    final int CLOSE = 4;

    public SimplePanel()
    {
        setLayout(null);
        myCanvasOuter = new CanvasOuter();
        myCanvasInner = new CanvasInner();
        add(myCanvasOuter);
        add(myCanvasInner);

        s = new Elevator[NUM];
        for (int i = 0; i < s.length; i++)
        {
            s[i] = new Elevator(i);
        }
        for (int i = 0; i < s.length; i++)
        {
            s[i].start();//线程启动
        }
        foundThread.start();//线程启动
    }

    class Found extends Thread //任务分配线程
    {
        private ArrayList tasks;
        private Task task;
        public Found()
        {
            tasks = new ArrayList();
        }
        public void addTask(int i, boolean flag)//添加任务
        {
            tasks.add(new Task(i, flag));
        }
        public void run()//线程体
        {
            while (true)
            {
                if (!tasks.isEmpty())
                {
                    task = (Task) (tasks.get(0));
                    int i = task.floor;
                    int minFloor = FLOOR;//
                    int id = 0;
                    boolean f = task.isUp;
                    boolean isFound = false;
                    if (f)//要上楼
                    {
                        for (int j = 0; j < NUM; j++)//电梯数
                        {
                            if ((s[j].state == PAUSE) || (s[j].current < i && s[j].state == UP))//停或者电梯正在从下往上
                            {
                                int distance = Math.abs(i - s[j].current);
                                if (distance < minFloor)
                                {
                                    id = j;
                                    minFloor = distance;
                                    isFound = true;
                                }
                            }
                        }
                    }
                    else//下楼
                    {
                        for (int j = 0; j < NUM; j++)
                        {
                            if ((s[j].state == PAUSE) || (s[j].current > i && s[j].state == DOWN))//停或正在从上往下
                            {
                                int distance = Math.abs(i - s[j].current);
                                if (distance < minFloor)
                                {
                                    id = j;
                                    minFloor = distance;
                                    isFound = true;
                                }
                            }

                        }
                    }
                    if (isFound)
                    {
                        s[id].addFloor(i);
                        tasks.remove(0);
                    }
                }
                try
                {
                    sleep(1000);
                }
                catch (InterruptedException e)
                {
                    System.out.println("Interrupted");
                }
            }
        }
        class Task//任务:要到几楼,上去还是下去
        {
            private int floor;
            private boolean isUp;
            public Task(int i, boolean flag)
            {
                floor = i;
                isUp = flag;
            }
        }
    }
    
    public void resetOuterB(int floor) //设置外部的按钮
    {
        myCanvasOuter.bUp[floor].setEnabled(true);
        myCanvasOuter.bDown[floor].setEnabled(true);
        myCanvasOuter.bUp[floor].setForeground(null);
        myCanvasOuter.bDown[floor].setForeground(null);
    }

    public void drawButtons(int id)//设置内部按钮
    {
        for (int i = 0; i < FLOOR; i++)
        {
            if (s[id].destinations.contains(new Integer(i)))
            {
                myCanvasInner.interPanels[id].interB[i].setBackground(Color.YELLOW);
            }
            else
            {
                myCanvasInner.interPanels[id].interB[i].setBackground(null);
            }
        }
    }

    class Elevator extends Thread //电梯主类
    { 
        private int id; //电梯标识号 
        private int floor = FLOOR; //总层数
        private JPanel myPanel = new JPanel();
        private JPanel myPanel1 = new JPanel();
        private JButton numB;
        private JButton stateB = new JButton("---");
        private JButton[] buttons; //电梯组成
        public int current = 1; //所在楼层
        public int state = PAUSE; //上下行标志
        private JButton floorB = new JButton("1");

        private ArrayList destinations; //目的地链表

        public Elevator(int x)
        {
            id = x;
            myPanel1.setLayout(new GridLayout());
            numB = new JButton("第"+(x+1)+"号电梯");
            myPanel1.add(numB);
            myPanel.setLayout(new GridLayout(floor + 2, 1));
            floorB.setBackground(Color.WHITE);
            myPanel.add(floorB);
            myPanel.add(stateB);

            buttons = new JButton[FLOOR];
            for (int i = buttons.length - 1; i >= 0; i--)
            {
                buttons[i] = new JButton();
                buttons[i].setBackground(Color.LIGHT_GRAY);
                myPanel.add(buttons[i]);
            }
            buttons[0].setBackground(Color.RED);
            myPanel1.setBounds(100 * id + 250, 10, 100, 50);
            myPanel.setBounds(100 * id + 250, 60, 100, 400);
            add(myPanel1);
            add(myPanel);
            
            destinations = new ArrayList();
        }

        public void addFloor(int i) //响应外部按钮
        {
            if (destinations.contains(new Integer(i)))
                return;
            if (state == PAUSE)
            {
                destinations.add(new Integer(i));
                buttons[i].setBackground(Color.YELLOW);
                if (current > i)
                {
                    state = DOWN;
                }
                else
                {
                    state = UP;
                }
                return;
            }

            if (state == UP)
            {
                for (int j = 0; j < destinations.size(); j++)
                {
                    if (i < ((Integer) (destinations.get(j))).intValue())
                    {
                        destinations.add(j, new Integer(i));
                        buttons[i].setBackground(Color.YELLOW);
                    }
                }
            }

            if (state == DOWN)
            {
                for (int j = 0; j < destinations.size(); j++)
                {
                    if (i > ((Integer) (destinations.get(j))).intValue())
                    {
                        destinations.add(j, new Integer(i));
                        buttons[i].setBackground(Color.YELLOW);
                    }
                }
            }
            destinations.add(new Integer(i));
            buttons[i].setBackground(Color.YELLOW);
        }

        public void wantToFloor(int i) //响应内部按钮
        {
            if (destinations.contains(new Integer(i)))
                return;
            if (state == PAUSE)
            {
                destinations.add(new Integer(i));
                buttons[i].setBackground(Color.YELLOW);
                if (current > i + 1)
                {
                    state = DOWN;
                }
                else
                {
                    state = UP;
                }
                return;
            }

            if (state == UP)
            {
                if (current > i + 1)
                    return;
                for (int j = 0; j < destinations.size(); j++)
                {
                    if (i < ((Integer) (destinations.get(j))).intValue())
                    {
                        destinations.add(j, new Integer(i));
                        buttons[i].setBackground(Color.YELLOW);
                        return;
                    }
                }
            }
            if (state == DOWN)
            {
                if (current < i)
                    return;
                for (int j = 0; j < destinations.size(); j++)
                {
                    if (i > ((Integer) (destinations.get(j))).intValue())
                    {
                        destinations.add(j, new Integer(i));
                        buttons[i].setBackground(Color.YELLOW);
                        return;
                    }
                }
            }
            destinations.add(new Integer(i));
            buttons[i].setBackground(Color.YELLOW);
        }

        public void setStateB() //设置运行状态按钮
        {
            if (state == PAUSE)
            {
                stateB.setText("---");
                stateB.setForeground(null);
                
                myCanvasInner.interPanels[id].stateB.setText("---");
                myCanvasInner.interPanels[id].stateB.setForeground(null);
                
                myCanvasOuter.stateB1.setText("---");
                myCanvasOuter.stateB1.setForeground(null);
                
                myCanvasOuter.stateB2.setText("---");
                myCanvasOuter.stateB2.setForeground(null);
            }
            else if (state == UP)
            {
                stateB.setText("上");
                stateB.setForeground(Color.RED);
                
                myCanvasInner.interPanels[id].stateB.setText("上");
                myCanvasInner.interPanels[id].stateB.setForeground(Color.RED);
                
                if(id==0)
                {
                    myCanvasOuter.stateB1.setText("上");
                    myCanvasOuter.stateB1.setForeground(Color.RED);
                }
                if(id==1)
                {
                    myCanvasOuter.stateB2.setText("上");
                    myCanvasOuter.stateB2.setForeground(Color.RED);
                }
            }
            else
            {
                stateB.setText("下");
                stateB.setForeground(Color.RED);
                
                myCanvasInner.interPanels[id].stateB.setText("下");
                myCanvasInner.interPanels[id].stateB.setForeground(Color.RED);
                
                if(id==0)
                {
                    myCanvasOuter.stateB1.setText("下");
                    myCanvasOuter.stateB1.setForeground(Color.RED);
                }
                if(id==1)
                {
                    myCanvasOuter.stateB2.setText("下");
                    myCanvasOuter.stateB2.setForeground(Color.RED);
                }
            }
        }

        public void run()
        {
            while (true)
            {
                if (state != PAUSE)       //运行中
                {
                    if (state == OPEN)//开门建对应
                    {
                        buttons[(current + FLOOR - 1) % FLOOR].setBackground(Color.BLACK);//开门状态中
                        try
                        {
                            sleep(3000);
                        }
                        catch (InterruptedException e)
                        {
                            System.out.println("Interrupted");
                        }
                        buttons[(current + FLOOR - 1) % FLOOR].setBackground(Color.RED);//关门状态中
                        state = PAUSE;
                    }
                    else
                    {
                        int i =((Integer) (destinations.get(0))).intValue() + 1;
                        //当前所在楼层
                        if (current == i)  //到达一个楼层
                        {
                            destinations.remove(0);
                            if (destinations.isEmpty())
                            {
                                state = PAUSE;
                            }
                            setStateB();

                            drawButtons(id);
                            buttons[(current + FLOOR - 1) % FLOOR].setBackground(Color.BLACK);//到达目的地时开门状态中
                            try
                            {
                                sleep(3000);//休眠3秒
                            }
                            catch (InterruptedException e)
                            {
                                System.out.println("Interrupted");
                            }
                            buttons[(current + FLOOR - 1) % FLOOR].setBackground(Color.RED);
                            resetOuterB(current - 1);
                        }
                        else
                        {
                            int follow = current; //运行前的楼层
                            if (state == UP)
                            {
                                current++;
                            }
                            else
                            {
                                current--;
                            }
                            floorB.setText(Integer.toString(current));
                            floorB.setForeground(Color.green);
                            myCanvasInner.interPanels[id].floorB.setText(Integer.toString(current));
                            myCanvasInner.interPanels[id].floorB.setForeground(Color.green);
                            
                            if(id==0)
                            {
                                myCanvasOuter.floorB1.setText(Integer.toString(current));
                                myCanvasOuter.floorB1.setForeground(Color.green);
                            }
                            if(id==1)
                            {
                                myCanvasOuter.floorB2.setText(Integer.toString(current));
                                myCanvasOuter.floorB2.setForeground(Color.green);
                            }
                            
                            buttons[(current + FLOOR - 1) % FLOOR].setBackground(Color.RED);
                            buttons[(follow + FLOOR - 1) % FLOOR].setBackground(Color.LIGHT_GRAY);
                            setStateB();
                        }
                    }
                }
                try
                {
                    sleep(1500);
                }
                catch (InterruptedException e)
                {
                    System.out.println("Interrupted");
                }
            }
        }
    }

    class CanvasOuter extends JPanel //显示外部按钮的画布类,位于左侧
    {
        private JPanel[] oneFloor;//楼层画布
        private int num = SimplePanel.FLOOR;
        private JButton[] bFloor; //楼层
        private JPanel jp;
        
        private JPanel[] updownpanel;//显示上下按钮
        private JButton[] bUp; //上行按钮
        private JButton[] bDown; //下行按钮
        private JPanel outp;//显示“电梯外部”

        private JPanel statePanel1;//显示1号和2号电梯的状态
        private JPanel statePanel2;
        private JButton state1;
        private JButton state2;
        private JButton floorB1;//显示1号电梯楼层按钮
        private JButton stateB1;//显示1号电梯上、下按钮
        private JButton floorB2;//显示2号电梯楼层按钮
        private JButton stateB2;//显示2号电梯上、下按钮
        CanvasOuter()
        {
            setLayout(null);
            
            jp = new JPanel(new GridLayout(8,1));
            jp.setBounds(20,160,225,400);
            
            outp=new JPanel(new GridLayout());
            JButton out = new JButton("电梯外部");
            outp.setBounds(20, 10, 225, 60);
            outp.add(out);
            
            bFloor = new JButton[num];//定义数组长度
            bUp = new JButton[num];
            bDown = new JButton[num];
            oneFloor = new JPanel[num];
            updownpanel = new JPanel[num];
            
            statePanel1 = new JPanel(new GridLayout(3,1));
            statePanel1.setBounds(20, 70, 110, 90);
            state1 = new JButton("一号电梯");
            floorB1 = new JButton("1");//显示1号电梯楼层按钮
            stateB1 = new JButton("---");//显示1号电梯上、下按钮
            floorB1.setBackground(Color.WHITE);
            statePanel2 = new JPanel(new GridLayout(3,1));
            statePanel2.setBounds(134, 70, 110, 90);
            state2 = new JButton("二号电梯");
            floorB2 = new JButton("1");//显示2号电梯楼层按钮
            stateB2 = new JButton("---");//显示2号电梯上、下按钮
            floorB2.setBackground(Color.WHITE);
            
            statePanel1.add(state1);
            statePanel1.add(floorB1);
            statePanel1.add(stateB1);
            statePanel2.add(state2);
            statePanel2.add(floorB2);
            statePanel2.add(stateB2);
            
            for(int i=num-1;i>=0;i--)
            {
                updownpanel[i] = new JPanel(new GridLayout(2,1));
                bFloor[i] = new JButton(i+1+"楼");
                bUp[i] = new JButton();
                if (i != num - 1)
                {
                    bUp[i].setText("▲");
                    bUp[i].addActionListener(new UpAction(i));
                }
                bDown[i] = new JButton();
                if (i != 0)
                {
                    bDown[i].setText("▼");
                    bDown[i].addActionListener(new UpAction(i));
                }
        
                updownpanel[i].add(bUp[i]);
                updownpanel[i].add(bDown[i]);
                oneFloor[i]= new JPanel(new GridLayout(1,2));//
                oneFloor[i].add(bFloor[i]);
                oneFloor[i].add(updownpanel[i]);
                
                jp.add(oneFloor[i]);
            }
            add(jp);
            add(statePanel1);
            add(statePanel2);
            add(outp);
            this.setBounds(0, 0, 250, 550);
            }
        
        class DownAction implements ActionListener
        {
            private int floor;
            public DownAction(int i)
            {
                floor = i;
            }
            public void actionPerformed(ActionEvent e)
            {
                foundThread.addTask(floor, true);
            }
        }

        class UpAction implements ActionListener
        {
            private int floor;
            public UpAction(int i)
            {
                floor = i;
            }
            public void actionPerformed(ActionEvent e)
            {
                foundThread.addTask(floor, true);
            }
        }
        
    }

    class CanvasInner extends JPanel //显示内部按钮的画布,位于右侧
    {
        private int num = NUM;
        private InterButton[] interPanels;
        public final static int WIDTH = 200;
        private JPanel panel2 = new JPanel();
        private JButton inviewB = new JButton("电梯内部");
        public CanvasInner()
        {
            this.setLayout(null);
            interPanels = new InterButton[num];

            panel2.setLayout(new GridLayout());
            panel2.add(inviewB);
            panel2.setBounds(0, 0, 200, 60);
            add(panel2);
            
            for (int i = 0; i < num; i++)
            {
                interPanels[i] = new InterButton(i);
                add(interPanels[i]);
            }
            setBounds(455, 10, WIDTH, 450);
        }

        class InterButton extends JPanel //表示每部电梯内部按钮的类
        {
            private int id; //电梯标识号
            private JPanel panel = new JPanel();
            private JPanel panel1 = new JPanel();
            private JButton numB;
            private JButton floorB = new JButton("1");
            private JButton stateB = new JButton("---");
            private JButton openB = new JButton("<>");
            private JButton closeB = new JButton("><");
            private JButton[] interB; //内部按钮数组

            public InterButton(int j)
            {
                id = j;
                this.setLayout(null);
                numB = new JButton("第"+(j+1)+"号电梯");
                int width = CanvasInner.WIDTH;
                floorB.setBackground(Color.WHITE);
                
                panel1.setLayout(new GridLayout());
                panel1.add(numB);
                panel1.setBounds(0, 60, width, 40);
                
                panel.setLayout(new GridLayout(5, 2));
                panel.add(stateB);
                panel.add(floorB);
                panel.setBounds(0, 100, width, 150);
                
                interB = new JButton[FLOOR];
                for (int i = 0; i < FLOOR; i++)
                {
                    interB[i] = new JButton();
                    interB[i].setText(i+1+"楼");
                    panel.add(interB[i]);
                    interB[i].addActionListener(new goFloor(i));
                }
                
                panel.add(openB);
                panel.add(closeB);
                openB.addActionListener(new OpenAction());
                closeB.addActionListener(new CloseAction());
                
                this.add(panel);
                this.add(panel1);
                this.setBounds(0, j * 200, width, 260);
            }

            class goFloor implements ActionListener
            {
                private int floor;    //目的地楼层
                public goFloor(int i)
                {
                    floor = i;
                }
                public void actionPerformed(ActionEvent e)
                {
                    interB[floor].setBackground(Color.YELLOW);
                    s[id].wantToFloor(floor);
                }
            }
            
            class OpenAction implements ActionListener  //开门键对应监听器
            {
                public void actionPerformed(ActionEvent e)
                {
                    if (s[id].state == PAUSE)
                    {
                        s[id].state = OPEN;
                    }
                }
            }
            
            class CloseAction implements ActionListener //关门键对应监听器
            {
                public void actionPerformed(ActionEvent e)
                {
                    int i = s[id].current - 1;
                    s[id].buttons[i].setBackground(Color.RED);
                }
            }
        }
    }
}