JAVA期末大作业电梯系统(含GUI界面、附源码、程序流程图)
码字不易,能不能点个赞和关注。wwww~~~~~~~
基本需求:
某栋大楼(楼层1-10楼)安装了1部电梯系统,该电梯系统运行规律如下:
1.如果一个在n楼(1<n<10)的乘客按了下行损钮,那么正在向下走(下行状态)的电梯到了n楼必须停下接收乘客。上行亦然
2.如果电梯里已经没有乘客了,电梯应该留在原位置直到再次投入使用。
3.在将乘客送到目的地以前电梯不允许反向运动。也就是电梯比如把乘客从9楼带到楼下,如果在走到4楼的时候5楼有人要下,电梯不能从4楼回5楼去,而要把乘客带到楼下再回来)。
4.满载的电梯不再收人。
5.电梯里有个按钮面版,里面有10个楼层的按钮。按下按钮表示该楼层变成一个目的地,按钮会发光,到达以后按钮不再发光
6.建筑物2-9楼层有一个按钮面版,上面两个按钮分别是向上和向下。1楼只有向上,10楼只有向下。
7.电梯有一个控制中心来自动控制,不用人手干预。
项目设计思想:
- Elevator:表示电梯,实现了电梯内部的逻辑功能
- ElevatorConst:定义了一系列常量
- ElevatorController:核心控制类(Controller),继承自Thread类,重写run(),多线程运行
- ElevatorGUI:主要负责主界面的布局,并将它代理给ElevatorController,使得某些监听事件的逻辑添加可以写在ElevatorController中。
- Main:主函数调用各部分实现完整的电梯系统。
1、ElevatorGUI:
public class ElevatorGUI extends JFrame
这个类主要负责主界面的布局,并将它代理给ElevatorController,使得某些监听事件的逻辑添加可以写在ElevatorController中。其中的函数方法都用于UI设置。
//ElevatorGUI代码:package os.view;import java.awt.*;import java.awt.event.*;import javax.swing.*;import os.controller.ElevatorController;import os.model.*;public class ElevatorGUI extends JFrame { // Member Variable private static final long serialVersionUID = 1L; // Delegation public ElevatorController delegate; // Contractor public ElevatorGUI(ElevatorController delegate) throws HeadlessException { super(); // Set delegate this.delegate = delegate; } // Private Methods for UI // Configure JFrame private void configureJFrame() { this.setTitle("Elevator Simulator");// Set title this.setSize(800, 600);// Set size of window this.setResizable(false);// Can't change the size this.setLocationRelativeTo(null);// Set the position of the window - // Screen's Center } // Configure Menu Bar private void configureMenuBar() { // Components JMenuBar menuBar; JMenu elevatorMenu; JMenu helpMenu; JMenuItem elevatorMenuItem; JMenuItem helpMenuItem; // Create the Menu Bar menuBar = new JMenuBar(); // Build Elevator Menu elevatorMenu = new JMenu("Elevator"); elevatorMenu.setMnemonic(KeyEvent.VK_E); // Add Menu Items to Menu "Elevator" elevatorMenuItem = new JMenuItem("Quit", KeyEvent.VK_Q); elevatorMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK)); elevatorMenuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.exit(EXIT_ON_CLOSE); } }); elevatorMenu.add(elevatorMenuItem); // Build About Menu helpMenu = new JMenu("Help"); helpMenu.setMnemonic(KeyEvent.VK_H); // Add Menu Items to Menu "About" helpMenuItem = new JMenuItem("About", KeyEvent.VK_A); helpMenu.add(helpMenuItem); helpMenuItem = new JMenuItem("Help", KeyEvent.VK_H); helpMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, ActionEvent.CTRL_MASK)); helpMenu.add(helpMenuItem); // Add Menus "File" and "Help" to Menu Bar menuBar.add(elevatorMenu); menuBar.add(helpMenu); // Add Components this.setJMenuBar(menuBar); } // Delegate Methods // Configure Header Title// private void configureHeaderTitle() {// this.delegate.addTitle();// } // Configure Floor Buttons Panel private void configureFloorButtonsPanel() { this.delegate.addFloorButtons(); } // Configure Elevator Buttons Panel private void configureElevatorButtonsPanel() { this.delegate.addElevator(); } // Show View public void showFrame() { // UI Methods this.setLayout(new GridLayout(1, ElevatorConst.TOTAL_ELEVATOR + 1)); this.configureMenuBar(); // Delegate Methods// this.configureHeaderTitle(); this.configureFloorButtonsPanel(); this.configureElevatorButtonsPanel(); this.configureJFrame(); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }}
2、ElevatorController:
public class ElevatorController extends Thread
这个类是核心控制类(Controller),继承自Thread类,重写run(),多线程运行。
view: controller对应的view
elevators: 用于储存电梯的数组
upButtons: 储存向上按键的数组,便于在controller中添加数据
downButtons: 储存向下按键的数组
upStatus: 记录对应的向上按键是否被按下
downStatus: 记录对应的向下按键是否被按下
showView(): 显示view
run(): 重写Thread中run()
addFloorButtons(): 添加主界面左侧控制中心的所有按钮
addElevator(): 添加电梯
findProperUpElevator(int floorNum): 按下向上按键后寻找最优的电梯
findProperDownElevator(int floorNum): 按下向下按键后寻找最优的电梯
//ElevatorControllerd代码:package os.controller;import java.awt.GridLayout;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import javax.swing.JButton;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.SwingConstants;import os.model.Elevator;import os.model.ElevatorConst;import os.view.ElevatorGUI;public class ElevatorController extends Thread { // Member Variable private ElevatorGUI view; private Elevator[] elevators; private JButton[] upButtons; private JButton[] downButtons; private boolean[] upStatus; private boolean[] downStatus; // Constructor public ElevatorController() { super(); // init Member Variables this.elevators = new Elevator[ElevatorConst.TOTAL_ELEVATOR]; this.upButtons = new JButton[ElevatorConst.TOTAL_FLOOR]; this.downButtons = new JButton[ElevatorConst.TOTAL_FLOOR]; this.upStatus = new boolean[ElevatorConst.TOTAL_FLOOR]; this.downStatus = new boolean[ElevatorConst.TOTAL_FLOOR]; for (int i = 0; i < ElevatorConst.TOTAL_FLOOR; i++) { this.upStatus[i] = false; this.downStatus[i] = false; } this.view = new ElevatorGUI(this);// With delegate } // Getter and Setter public void showView() { this.view.showFrame(); } // Delegate Methods// public void addTitle() {// this.view.add(new JLabel());// for (int i = 0; i < ElevatorConst.TOTAL_ELEVATOR; i++) {// this.view.add(new JLabel(String.valueOf(i) + "号电梯", SwingConstants.CENTER));// }// } public void addFloorButtons() { // Components JPanel floorButtonsPanel = new JPanel(); // Set FloorButtonsPanel Style floorButtonsPanel.setLayout(new GridLayout(ElevatorConst.TOTAL_FLOOR + 1, 3));// floorButtonsPanel.setBorder(BorderFactory.createEmptyBorder(15, 20, 5, 20)); floorButtonsPanel.add(new JLabel("楼层", SwingConstants.CENTER)); floorButtonsPanel.add(new JLabel("上", SwingConstants.CENTER)); floorButtonsPanel.add(new JLabel("下", SwingConstants.CENTER)); // Set Button Listener MouseListener upButtonListener = new UpButtonAction(); MouseListener downButtonListener = new DownButtonAction(); for (int i = 0; i < ElevatorConst.TOTAL_FLOOR; i++) { floorButtonsPanel.add(new JLabel(String.valueOf(20 - i), SwingConstants.CENTER)); if (1 == (20 - i)) { this.upButtons[19 - i] = new JButton("上"); this.upButtons[19 - i].addMouseListener(upButtonListener); this.downButtons[19 - i] = new JButton(); this.downButtons[19 - i].setEnabled(false); this.downButtons[19 - i].setBorder(null); } else if (ElevatorConst.TOTAL_FLOOR == (20 - i)) { this.upButtons[19 - i] = new JButton(); this.upButtons[19 - i].setEnabled(false); this.upButtons[19 - i].setBorder(null); this.downButtons[19 - i] = new JButton("下"); this.downButtons[19 - i].addMouseListener(downButtonListener); } else { this.upButtons[19 - i] = new JButton("上"); this.upButtons[19 - i].addMouseListener(upButtonListener); this.downButtons[19 - i] = new JButton("下"); this.downButtons[19 - i].addMouseListener(downButtonListener); } floorButtonsPanel.add(this.upButtons[19 - i]); floorButtonsPanel.add(this.downButtons[19 - i]); } // Add to JFrame this.view.add(floorButtonsPanel); } public void addElevator() { for (int i = 0; i < ElevatorConst.TOTAL_ELEVATOR; i++) { this.elevators[i] = new Elevator(); this.view.add(this.elevators[i]); this.elevators[i].getThread().start(); } } // Thread @Override public void run() { while (true) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } // Up Buttons for (int i = 0; i < this.upStatus.length - 1; i++) { if (this.upStatus[i]) { // 找一个合适的电梯 this.findProperUpElevator(i); } } // Down Buttons for (int i = 1; i < this.downStatus.length; i++) { if (this.downStatus[i]) { // 找一个合适的电梯 this.findProperDownElevator(i); } } } } // private int findProperElevator(int s, int floorNum) {// int result = -1;// int time = 100;// for (int i = 0; i = t) {// time = t;// result = i;// }// }// return result;// } private void findProperUpElevator(int floorNum) { int distance = 40; int index = -1; for (int i = 0; i < this.elevators.length; i++) { int currentFloor = this.elevators[i].getCurrentFloor(); if (this.elevators[i].getDirection() == ElevatorConst.STATUS_UP && currentFloor (floorNum - currentFloor)) { distance = floorNum - currentFloor; index = i; } } else if (this.elevators[i].getDirection() == ElevatorConst.STATUS_IDEL) { if (distance > Math.abs(floorNum - currentFloor)) { distance = Math.abs(floorNum - currentFloor); index = i; } } } if (index != -1) { this.elevators[index].addTargetFloor(floorNum); this.upStatus[floorNum] = false; this.upButtons[floorNum].setEnabled(true); } } private void findProperDownElevator(int floorNum) { int distance = 40; int index = -1; for (int i = 0; i = floorNum) { if (distance > (currentFloor - floorNum)) { distance = floorNum - currentFloor; index = i; } } else if (this.elevators[i].getDirection() == ElevatorConst.STATUS_IDEL) { if (distance > Math.abs(floorNum - currentFloor)) { distance = Math.abs(floorNum - currentFloor); index = i; } } } if (index != -1) { this.elevators[index].addTargetFloor(floorNum); this.downStatus[floorNum] = false; this.downButtons[floorNum].setEnabled(true); } } // Action Listener class UpButtonAction extends MouseAdapter implements MouseListener { @Override public void mousePressed(MouseEvent e) { for (int i = 0; i < upButtons.length; i++) { if (e.getSource() == upButtons[i]) { upStatus[i] = true; } } } } // Action Listener class DownButtonAction extends MouseAdapter implements MouseListener { @Override public void mousePressed(MouseEvent e) { for (int i = 0; i < downButtons.length; i++) { if (e.getSource() == downButtons[i]) { downStatus[i] = true; downButtons[i].setEnabled(false); } } } }}
3、Elevator:
public class Elevator extends JPanel implements Runnable
这个类表示电梯,实现了电梯内部的逻辑功能
currentFloor, targetFloor: 分别记录电梯当前楼层以及目标楼层
direction: 记录电梯的运行状态
floorStatus: 记录对应楼层的按钮是否被按下
statusLabel: 显示当前电梯的所在楼层及状态
floorNumButtons: 电梯内部的楼层按钮
floorButtons: 单个电梯界面右侧一列的按钮,显示电梯的运动,不可点击
addTargetFloor(int t): 为电梯添加目标楼层
getThread(): 获取当前电梯对应的线程
getCurrentFloor(): 获取当前楼层
getTargetFloor(): 获取目标楼层
getDirection(): 获取电梯运行状态
moveUpFloor(): 电梯向上运动
moveDownFloor(): 电梯向下运动
openDoor(): 开门
getMaxPressedButton(): 获取所按按钮对应的最高楼层
getMinPressedButton(): 获取所按按钮对应的最低楼层
//Elevator代码:package os.model;import java.awt.Color;import java.awt.GridLayout;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import javax.swing.JButton;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.SwingConstants;import javax.swing.border.MatteBorder;public class Elevator extends JPanel implements Runnable {// Member Variableprivate static final long serialVersionUID = 2L;private Thread thread;private int currentFloor;private int targetFloor;private int direction;private boolean[] floorStatus;private JLabel statusLabel;private JButton[] floorNumButtons;private JButton[] floorButtons;// Constructorpublic Elevator() {super();// init Member Variablesthis.direction = ElevatorConst.STATUS_IDEL;this.currentFloor = 0;this.targetFloor = 0;this.thread = new Thread(this);this.floorStatus = new boolean[ElevatorConst.TOTAL_FLOOR];for (int i = 0; i < this.floorStatus.length; i++) {this.floorStatus[i] = false;}// init Button Arraythis.floorNumButtons = new JButton[ElevatorConst.TOTAL_FLOOR];this.floorButtons = new JButton[ElevatorConst.TOTAL_FLOOR];// UI Methodsthis.configureElevator();}// UI Methodsprivate void configureElevator() {this.setLayout((new GridLayout(ElevatorConst.TOTAL_FLOOR + 1, 2)));this.setBorder(new MatteBorder(0, 2, 0, 0, Color.orange));this.add(new JLabel("楼层号", SwingConstants.CENTER));this.statusLabel = new JLabel(String.valueOf(this.currentFloor + 1),SwingConstants.CENTER);this.statusLabel.setForeground(Color.RED);this.add(this.statusLabel);MouseListener numListener = new NumButtonAction();for (int i = 0; i < ElevatorConst.TOTAL_FLOOR; i++) {this.floorNumButtons[19 - i] = new JButton(String.valueOf(20 - i));this.add(this.floorNumButtons[19 - i]);this.floorNumButtons[19 - i].addMouseListener(numListener);this.floorButtons[19 - i] = new JButton();this.floorButtons[19 - i].setEnabled(false);this.floorButtons[19 - i].setOpaque(true);this.floorButtons[19 - i].setBorderPainted(false);this.floorButtons[19 - i].setBackground(Color.yellow);this.add(this.floorButtons[19 - i]);}this.floorButtons[this.currentFloor].setBackground(Color.red);}class NumButtonAction extends MouseAdapter implements MouseListener {public void mousePressed(MouseEvent e) {for (int i = 0; i this.currentFloor) {this.direction = ElevatorConst.STATUS_UP;this.moveUpFloor();this.direction = ElevatorConst.STATUS_IDEL;this.statusLabel.setText(String.valueOf(this.targetFloor + 1));} else if (this.targetFloor < this.currentFloor) {this.direction = ElevatorConst.STATUS_DOWN;this.statusLabel.setText(String.valueOf(this.currentFloor + 1)+ "下");this.moveDownFloor();this.direction = ElevatorConst.STATUS_IDEL;this.statusLabel.setText(String.valueOf(this.targetFloor + 1));} else if (this.targetFloor == this.currentFloor&& this.floorStatus[this.targetFloor]) {this.direction = ElevatorConst.STATUS_IDEL;this.openDoor();this.statusLabel.setText(String.valueOf(this.targetFloor + 1));}}}private void moveUpFloor() {// i -- current floor index, i + 1 -- next floor index, index + 1 =// floor numberfor (int i = this.currentFloor; i <= this.targetFloor; i++) {this.currentFloor = i;try {this.statusLabel.setText(String.valueOf(i + 1) + "上");Thread.sleep(600);if (this.floorStatus[i]) {this.floorStatus[i] = false;this.floorButtons[i].setBackground(Color.green);this.statusLabel.setText(String.valueOf(i + 1) + "开门");Thread.sleep(1000);this.floorButtons[i].setBackground(Color.red);this.statusLabel.setText(String.valueOf(i + 1) + "关门");Thread.sleep(1000);}if (i + 1 = this.targetFloor; i--) {this.currentFloor = i;try {this.statusLabel.setText(String.valueOf(i + 1) + "下");Thread.sleep(600);if (this.floorStatus[i]) {this.floorStatus[i] = false;this.floorButtons[i].setBackground(Color.green);this.statusLabel.setText(String.valueOf(i + 1) + "开门");Thread.sleep(1000);this.floorButtons[i].setBackground(Color.red);this.statusLabel.setText(String.valueOf(i + 1) + "关门");Thread.sleep(1000);}if (i - 1 >= this.targetFloor) {this.floorButtons[i].setBackground(Color.yellow);this.statusLabel.setText(String.valueOf(i) + "下");this.floorButtons[i - 1].setBackground(Color.red);}} catch (InterruptedException e) {e.printStackTrace();}}this.statusLabel.setText(String.valueOf(this.currentFloor + 1));}private void openDoor() {try {if (this.floorStatus[this.currentFloor]) {this.floorStatus[this.currentFloor] = false;this.floorButtons[this.currentFloor].setBackground(Color.green);this.statusLabel.setText(String.valueOf(this.currentFloor + 1)+ "开门");Thread.sleep(1000);this.floorButtons[this.currentFloor].setBackground(Color.red);this.statusLabel.setText(String.valueOf(this.currentFloor + 1)+ "关门");Thread.sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}this.statusLabel.setText(String.valueOf(this.currentFloor + 1));}private int getMaxPressedButton() {int max = 0;for (int i = floorStatus.length - 1; i >= 0; i--) {if (floorStatus[i]) {max = i;break;}}return max;}private int getMinPressedButton() {int min = 0;for (int i = 0; i = this.targetFloor) {this.targetFloor = t;this.floorStatus[t] = true;} else if (t >= this.currentFloor) {this.floorStatus[t] = true;} else {}} else if (this.direction == ElevatorConst.STATUS_DOWN) {if (t <= this.targetFloor) {this.targetFloor = t;this.floorStatus[t] = true;} else if (t this.targetFloor) {//result = a - this.currentFloor;//} else if (a > this.currentFloor) {//result = a - this.currentFloor;//} else {//result = (this.targetFloor - this.currentFloor)//+ (this.targetFloor - a);//}//} else if (this.direction == ElevatorConst.STATUS_DOWN) {//if (a < this.targetFloor) {//result = this.currentFloor - a;//} else if (a < this.currentFloor) {//result = this.currentFloor - a;//} else {//result = (this.currentFloor - this.targetFloor)//+ (a - this.targetFloor);//}//}//return result;//}// Getter and Setterpublic Thread getThread() {return thread;}public int getCurrentFloor() {return currentFloor;}public int getTargetFloor() {return targetFloor;}public int getDirection() {return direction;}}
4、ElevatorConst:
该类中定义了一系列常量
总楼层 TOTAL_FLOOR
电梯数量 TOTAL_ELEVATOR
上行状态 STATUS_UP
下行状态 STATUS_DOWN
空闲状态 STATUS_IDEL
(常量值看代码)
//ElevatorConst代码:package os.model;public class ElevatorConst {public static final int TOTAL_FLOOR = 20;public static final int TOTAL_ELEVATOR = 5;public static final int STATUS_UP = 1;public static final int STATUS_DOWN = -1;public static final int STATUS_IDEL = 0;}
如果觉得有帮助的小伙伴,可以点个赞,走波关注嘛?谢谢~~~~~~~~~
开发者涨薪指南 48位大咖的思考法则、工作方式、逻辑体系