电梯调度程序的界面和运行时的一些动作实现在上一次的初级测试时完成了。
接下来的一段时间进行的就是把我们的算法和功能实现加入到我们的界面中,在这个过程中
我们换用了java语言进行设计,可以找到最近的电梯进行调度但是还没实现对乘客的体重进行
判断和控制。
下面是一些运行的效果:
一些重要的程序代码:
public class ListThread extends JPanel implements Runnable
{
private final int UP = 1, DN = -1, ABORT = 0; //电梯的状态
private static int floorNum; //楼层数
private int direction; //电梯运行的方向或停止
private int curPos; //电梯目前处于的楼层位置
private boolean[] numState; //电梯内部数字键的状态
private int tarPos; //电梯到达的目标位置
private Thread thread; //自身线程
private Color numColor0 = new Color(192, 160, 190), numColor1 = Color.green;
private Color floorColor0 = new Color(100, 100, 100),
floorColor1 = Color.blue;
JButton[] listButton; //代表电梯的数组
JButton[] numButton; //电梯内部数字按钮
JLabel dispState, dispFloor;
public ListThread()
{
floorNum = ListFrame.getFloorNum();
direction = ABORT;
curPos = 0;
tarPos = 0;
//对电梯内部的数字键进行状态初始化
numState = new boolean[floorNum];
for (int i = 0; i < numState.length; i++)
{
numState[i] = false;
}
//产生自身线程
thread = new Thread(this);
//面板布局
setLayout(new GridLayout(floorNum+1, 2));
this.setBorder(new MatteBorder(2, 2, 2, 2, Color.orange));
listButton = new JButton[floorNum];
numButton = new JButton[floorNum];
dispFloor = new JLabel("楼层号", SwingConstants.CENTER);
//dispFloor.setForeground(new Color(217, 123, 2));
dispState = new JLabel("停止", SwingConstants.CENTER);
dispState.setForeground(new Color(217, 123, 2));
this.add(dispFloor);
this.add(dispState);
MouseListener numListener = new NumButtonAction();
//设置属性
for (int i = listButton.length - 1; i >= 0; i--)
{
numButton[i] = new JButton(String.valueOf(i + 1));
numButton[i].addMouseListener(numListener);
//numButton[i].setForeground(numColor0);
numButton[i].setBackground(numColor0);
listButton[i] = new JButton();
listButton[i].setEnabled(false);
listButton[i].setBackground(floorColor0);
this.add(numButton[i]);
this.add(listButton[i]);
}
listButton[curPos].setBackground(floorColor1);
}
//电梯内部数字键的监听器类
class NumButtonAction extends MouseAdapter implements MouseListener
{
public void mousePressed(MouseEvent e)
{
for (int i = 0; i < numButton.length; i++)
{
if (e.getSource() == numButton[i])
{
numState[i] = true;
numButton[i].setBackground(numColor1);
if (direction == ABORT)
{
tarPos = i;
}
if (direction == UP)
{
tarPos = getMaxPressedNum();
}
if (direction == DN)
{
tarPos = getMinPressedNum();
}
}
}
}
}
//电梯线程的run()方法
public void run()
{
while (true)
{
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
if (direction == UP || direction == DN)
{
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
direction = ABORT;
//System.out.println("if (direction == UP || direction == DN)");
}
if (tarPos > curPos)
{
direction = UP;
dispState.setText("上行");
moveUp();
direction = ABORT;
dispState.setText("停止");
} else if (tarPos < curPos)
{
direction = DN;
dispState.setText("下行");
moveDn();
direction = ABORT;
dispState.setText("停止");
}
}
}
//电梯向上运行
public void moveUp()
{
int oldPos = curPos;
for (int i = curPos + 1; i <= tarPos; i++)
{
try
{
dispState.setText("上行");
Thread.sleep(600);
listButton[i].setBackground(floorColor1);
if (i > oldPos)
{
listButton[i - 1].setBackground(floorColor0);
}
if (numState[i])
{
dispState.setText("开门");
Thread.sleep(1000);
dispState.setText("关门");
numButton[i].setBackground(numColor0);
Thread.sleep(1000);
}
curPos = i;
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
clearState();
}
// 电梯向下运行
public void moveDn()
{
int oldPos = curPos;
for (int i = curPos - 1; i >= tarPos; i--)
{
try
{
Thread.sleep(600);
listButton[i].setBackground(Color.blue);
if (i < oldPos)
{
listButton[i + 1].setBackground(floorColor0);
}
if (numState[i])
{
dispState.setText("开门");
Thread.sleep(2000);
dispState.setText("关门");
numButton[i].setBackground(numColor0);
Thread.sleep(800);
}
curPos = i;
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
clearState();
}
public Thread getThread()
{
return thread;
}
private int getMinPressedNum()
{
int min = 0;
for (int i = 0; i < numState.length; i++)
{
if (numState[i])
{
min = i;
break;
}
}
return min;
}
private int getMaxPressedNum()
{
int max = 0;
for (int i = numState.length - 1; i >= 0; i--)
{
if (numState[i])
{
max = i;
break;
}
}
return max;
}
private void clearState()
{
for (int i = 0; i < numState.length; i++)
{
if (numState[i])
{
numState[i] = false;
numButton[i].setBackground(numColor0);
}
}
}
public int getDirection()
{
return direction;
}
public int getTarPos()
{
return tarPos;
}
public void setDirection(int i)
{
direction = i;
}
public void setTarPos(int i)
{
if (direction == ABORT)
{
tarPos = i;
numState[i] = true;
if (curPos > tarPos)
{
direction = DN;
}
if (curPos < tarPos)
{
direction = UP;
}
}
if (direction == UP && i > tarPos)
{
tarPos = i;
numState[i] = true;
}
if (direction == DN && i < tarPos)
{
tarPos = i;
numState[i] = true;
}
}
public boolean isUp()
{
return direction == UP;
}
public boolean isDown()
{
return direction == DN;
}
public boolean isAbort()
{
return direction == ABORT;
}
public int getCurPos()
{
return curPos;
}
public void setDirectionUp()
{
direction = UP;
}
public void setDirectionDn()
{
direction = DN;
}
public void setDirectionAbort()
{
direction = ABORT;
}
}
public class ListFrame extends JFrame implements Runnable
{
private static int floorNum = 20; //楼层数
private static int listNum = 5; //电梯数
private ListThread[] listThread; //对应电梯的线程数组
Container cp;
JPanel floorPanel = new JPanel(); //用来显示每一楼层的楼层号和上下键的面板
JButton[] floorButton; //楼层号
BasicArrowButton[] upButton; //向上键
BasicArrowButton[] downButton; //向下键
JButton dispUp, dispDown, dispFloor;
Color pressedUpDownColor = Color.RED;
Color unPressedUpDownColor = new Color(170, 170, 200);
int[] upState; //用来记录向上键的状态
int[] downState; //用来记录向下键的状态
private JMenuBar menuBar;
private JMenu menu;
private JMenuItem chooses[] = {
//new JMenuItem("电梯数(N)"),
//new JMenuItem("楼层数(N)"),
new JMenuItem("退出(X)")};
public ListFrame()
{
cp = this.getContentPane();
cp.setLayout(new GridLayout(1, listNum + 1));
floorPanel.setLayout(new GridLayout(floorNum + 1, 3));
floorPanel.setBorder(new MatteBorder(2, 4, 2, 2, Color.yellow));
floorButton = new JButton[floorNum];
upButton = new BasicArrowButton[floorNum];
downButton = new BasicArrowButton[floorNum];
dispFloor = new JButton("层");
dispFloor.setEnabled(false);
dispUp = new JButton("上");
dispUp.setEnabled(false);
dispDown = new JButton("下");
dispDown.setEnabled(false);
floorPanel.add(dispFloor);
floorPanel.add(dispUp);
floorPanel.add(dispDown);
MouseListener upListener = new UpButtonAction(); //向上键的Listener
//设置属性
for (int i = floorButton.length - 1; i >= 0; i--)
{
floorButton[i] = new JButton(String.valueOf(i + 1));
floorButton[i].setForeground(Color.green);
floorButton[i].setForeground(Color.green);
floorButton[i].setFont(new Font("Serif", Font.BOLD, 13));
floorButton[i].setEnabled(false);
upButton[i] = new BasicArrowButton(BasicArrowButton.NORTH);
upButton[i].addMouseListener(upListener);
upButton[i].setBackground(unPressedUpDownColor);
downButton[i] = new BasicArrowButton(BasicArrowButton.SOUTH);
downButton[i].addMouseListener(upListener);
downButton[i].setBackground(unPressedUpDownColor);
floorPanel.add(floorButton[i]);
floorPanel.add(upButton[i]);
floorPanel.add(downButton[i]);
}
cp.add(floorPanel);
// 设置菜单
menuBar = new JMenuBar();
menu = new JMenu("菜单(M)");
menu.setFont(new Font("Serif", Font.BOLD, 14));
menu.setForeground(Color.darkGray);
menu.setMnemonic(KeyEvent.VK_M);
for (int i = 0; i < chooses.length; i++)
{
menu.add(chooses[i]);
if (i < chooses.length - 1)
{
menu.addSeparator();
}
chooses[i].setForeground(Color.darkGray);
chooses[i].setFont(new Font("Serif", Font.BOLD, 14));
}
chooses[0].addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
System.exit(0);
}
});
menuBar.add(menu);
setJMenuBar(menuBar);
listThread = new ListThread[listNum];
//创建电梯线程
for (int i = 0; i < listNum; i++)
{
ListThread list = new ListThread();
cp.add(list);
list.getThread().start();
listThread[i] = list;
}
upState = new int[floorNum];
downState = new int[floorNum];
//初始化方向键状态
for (int i = 0; i < upState.length; i++)
{
upState[i] = 0;
downState[i] = 0;
}
Thread manageThread = new Thread(this);
manageThread.start(); //启动调度线程
}
// 向上键的Listener
class UpButtonAction extends MouseAdapter implements MouseListener
{
public void mousePressed(MouseEvent e)
{
for (int i = 0; i < upButton.length; i++)
{
if (e.getSource() == upButton[i])
{
upButton[i].setBackground(pressedUpDownColor);
upState[i] = 1;
}
if (e.getSource() == downButton[i])
{
downButton[i].setBackground(pressedUpDownColor);
downState[i] = 1;
}
}
}
}
public static int getFloorNum()
{
return floorNum;
}
//调度线程run()方法
public void run()
{
while (true)
{
try
{
Thread.sleep(100);
} catch (InterruptedException e)
{
e.printStackTrace();
}
//处理向上键
for (int i = 0; i < upState.length; i++)
{
if (upState[i] == 1)
{
upLookForList(i);
}
if (upState[i] >= 5)
{
if (i == listThread[upState[i] - 5].getCurPos())
{
upState[i] = 0;
upButton[i].setBackground(unPressedUpDownColor);
//System.out.println("unPressedUpDownColor");
}
}
}
//处理向下键
for (int i = 0; i < downState.length; i++)
{
if (downState[i] == 1)
{
downLookForList(i);
}
if (downState[i] >= 5)
{
if (i == listThread[downState[i] - 5].getCurPos())
{
downState[i] = 0;
downButton[i].setBackground(unPressedUpDownColor);
}
}
}
}
}
// 寻找响应向上键最近的电梯
private boolean upLookForList(int floor)
{
int whichList = 0;
int distance = floorNum;
for (int j = 0; j < listThread.length; j++)
{
if (listThread[j].isAbort()
|| (listThread[j].isUp() && floor >= listThread[j].getCurPos()))
{
int temp = Math.abs(floor - listThread[j].getCurPos());
if (temp < distance)
{
whichList = j;
distance = Math.abs(floor - listThread[j].getCurPos());
}
}
}
if (distance != floorNum)
{
upState[floor] = 5 + whichList;
listThread[whichList].setTarPos(floor);
return true;
} else
{
return false;
}
}
// 寻找响应向下键最近的电梯
private boolean downLookForList(int floor)
{
int whichList = 0;
int distance = floorNum;
for (int j = 0; j < listThread.length; j++)
{
if (listThread[j].isAbort()
|| (listThread[j].isDown() && floor <= listThread[j].getCurPos()))
{
int temp = Math.abs(floor - listThread[j].getCurPos());
if (temp < distance)
{
whichList = j;
distance = Math.abs(floor - listThread[j].getCurPos());
}
}
}
if (distance != floorNum)
{
downState[floor] = 5 + whichList;
listThread[whichList].setTarPos(floor);
return true;
} else
{
return false;
}
}
}