電梯調度 結對開發項目


一:項目名稱:

電梯調度模擬程序

二:項目參與人員:

周其范 胡寶月

三:項目開發語言和工具:

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

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM