📄 elevatorsimulator.java
字号:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.util.*;
public class ElevatorSimulator extends JFrame {
Controller c;
//two elevators
Elevator e1;
Elevator e2;
JTextField from;
JTextField to;
JButton go;
JButton reset;
public static void main(String args[]) {
ElevatorSimulator f = new ElevatorSimulator("电梯模拟");
f.pack();
//窗口显示在屏幕中间
Dimension dm = f.getToolkit().getScreenSize();
f.setLocation((int)(dm.getWidth()/2 - f.getWidth()/2),
(int)(dm.getHeight()/2 - f.getHeight()/2));
f.show();
}
ElevatorSimulator(String title) {
this.setTitle(title);
this.setSize(550,550);
c = new Controller(10,10);
e1 = new Elevator(10,10,c,"left");
e2 = new Elevator(10,10,c,"right");
c.addElevator(e1);
c.addElevator(e2);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel jp1 = new JPanel();
jp1.setLayout(new GridLayout(1,3,5,0));
getContentPane().add(jp1,BorderLayout.CENTER);
JPanel jp = new JPanel(new GridLayout(3,2));
go = new JButton("go");
reset = new JButton("reset");
from = new JTextField();
to = new JTextField();
jp.add(new JLabel("From :"));
jp.add(from);
jp.add(new JLabel("To :"));
jp.add(to);
jp.add(go);
jp.add(reset);
go.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
int f = 0;
int t = 0;
try {
f = Integer.parseInt(from.getText());
t = Integer.parseInt(to.getText());
} catch (NumberFormatException e1) {
return ;
}
if (f <0||f > 9||t >9 || t<0||(f==t)) return ;
c.commitRequest(new Request(f,t,80,""));
}
});
reset.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
c.reset();
}
});
JPanel jp2 = new JPanel(new BorderLayout());
jp2.add(jp,"South");
jp1.add(e1);
jp1.add(jp2);
jp1.add(e2);
//getContentPane().add(jp2,BorderLayout.SOUTH);
}
}
/**
* The Controller is the central part of the program. It holds all the requests and controls the
* running of all evalators.
*/
class Controller implements Direction {
private java.util.List requests = new ArrayList();
private java.util.List elevators = new ArrayList();
private int roomHeight;
private int floors;
Controller(int roomHeight,int floors) {
this.roomHeight = roomHeight;
this.floors = floors;
}
/**
* Clear request and reset all elevators.
*/
synchronized void reset() {
for(Iterator it = elevators.iterator(); it.hasNext();) {
Elevator e = (Elevator)it.next();
e.reset();
}
requests.clear();
}
/**
* Add an elevator to the system.
*/
void addElevator(Elevator e) {
elevators.add(e);
}
/**
* Add a request to the system and start up a elevator to process the request.
*/
synchronized void commitRequest(Request r) {
if (r.to < 0 || r.to > floors -1
|| r.from < 0 || r.from > floors - 1
|| r.from == r.to)
throw new IllegalArgumentException("illegal request");
requests.add(r);
Elevator nearest = null;
int min_dist = Integer.MAX_VALUE;
for(Iterator it = elevators.iterator();it.hasNext();) {
Elevator e = (Elevator)it.next();
if (e.isIdle()) {
int f = e.getFloor();
int dist = Math.abs(f - r.from);
if (dist < min_dist ) {
nearest = e;
min_dist = dist;
}
} else {
int pos = e.getPos();
boolean direct = e.getDirection();
if (direct == UP && r.from * roomHeight > pos && r.to > r.from) return;
if (direct == DOWN && r.from * roomHeight < pos && r.to < r.from) return;
}
}
if (nearest != null) {
int f = nearest.getFloor();
if(r.from == f) nearest.startup(r.to > f?UP:DOWN);
else nearest.startup(r.from > f? UP : DOWN);
}
}
/**
* Return true if there are someone need elevator above the specified floor.
*/
synchronized boolean hasRequestAbove(int floor) {
for(Iterator it = requests.iterator();it.hasNext();) {
Request r = (Request)it.next();
if (r.from > floor) return true;
}
return false;
}
/**
* Return true if there are someone need elevator under the specified floor.
*/
synchronized boolean hasRequestUnder(int floor) {
for(Iterator it = requests.iterator();it.hasNext();) {
Request r = (Request)it.next();
if (r.from < floor) return true;
}
return false;
}
/**
* Return true if there are someone waiting for a elevator at specified floor.
*/
synchronized boolean hasRequestOn(int floor,boolean direct) {
for(Iterator it = requests.iterator();it.hasNext();) {
Request r = (Request)it.next();
if (r.from == floor) {
if (direct == UP && r.to > r.from) return true;
if (direct == DOWN && r.to < r.from) return true;
}
}
return false;
}
/**
* Remove the requests.
*/
synchronized Request[] removeRequests(int floor,boolean direct) {
ArrayList a = new ArrayList();
for(Iterator it = requests.iterator();it.hasNext();) {
Request r = (Request)it.next();
if (r.from == floor) {
if (direct == UP && r.to > r.from ||
direct == DOWN && r.to < r.from) {
it.remove();
a.add(r);
}
}
}
return (Request[])a.toArray(new Request[0]);
}
/**
* Return true if there's no request.
*/
synchronized boolean isEmpty() {
return requests.isEmpty();
}
}
/**
* A class presents a elevator. The elevator has it's own thread. When the elevator is created,
* the thread is started and waiting. The elevator class draws it self as a JPanel also.
*/
class Elevator extends JPanel implements Runnable,Direction {
Elevator(int roomHeight,int floors, Controller c,String name) {
idle = true;
pos = 0;
height = 6;
floor = 0;
this.roomHeight = roomHeight;
this.floors = floors;
this.c = c;
this.name = name;
this.setBorder(new LineBorder(Color.white));
Thread t = new Thread(this);
t.start();
}
int getPos() {
return pos;
}
int getFloor() {
return floor;
}
boolean isParking() {
return parking;
}
boolean getDirection() {
return direction;
}
int getPeronNumber() {
return list.size();
}
boolean isIdle() {
return idle;
}
void startup(boolean direct) {
idle = false;
direction = direct;
pickup();
repaint();
synchronized(list) {
list.notify();
}
}
public Dimension getPreferredSize() {
return new Dimension(100, 400);
}
public void paintComponent(Graphics g) {
Dimension size = getSize();
int w = (int)size.getWidth();
int h = (int)size.getHeight();
g.clearRect(0,0,w,h);
h -= 20;
float unit = (float)h / (float)(floors * roomHeight);
for(int i = 0; i < floors; i++) {
int hi = (int)(h - i * unit * roomHeight);
g.drawString((new Integer(i)).toString(),w - 100,hi - 3);
g.drawLine(0,hi,w,hi);
}
g.setColor(Color.blue);
g.drawOval(5, (int)(h - pos * unit - unit * height)
,(int)(unit * height * 2/3+50),(int)(unit * height));
g.drawOval(7, (int)(h - pos * unit - unit * height)
,(int)(unit * height * 2/3+46),(int)(unit * height));
g.setColor(Color.red);
g.drawString(""+list.size(),17,(int)(h - pos * unit - unit * height + 15));
String text = "" + (pos/roomHeight)+ " ";
if (idle) text = text + "空闲";
else text = text + (direction==UP?"上升":"下降");
g.setColor(Color.black);
g.drawString(text,15,h+15);
}
void reset() {
idle = true;
pos = 0;
list.clear();
floor = 0;
repaint();
}
public void run() {
while(true) {
while(!idle) {
if (direction == UP) {
pos = (pos < roomHeight * floors - 1)?pos+1:pos;
} else {
pos = pos > 0? pos - 1:pos;
}
repaint();
synchronized(this) {
try {wait(250);}catch(InterruptedException e){}
}
if ( pos % roomHeight != 0 ) continue;
floor = pos / roomHeight;
schedule();
if (parking) {
removeArrived(floor);
pickup();
synchronized(this) {
try {wait(1000 * 2);}catch(InterruptedException e){}
}
}
if (c.isEmpty()&&list.isEmpty()) {
idle = true;
}
repaint();
}
synchronized(list) {
try {list.wait();}catch(InterruptedException e) {}
}
}
}
private void schedule() {
if (!(hasArrivedAt(floor)
||c.hasRequestOn(floor,direction))
&& ((direction==UP && (c.hasRequestAbove(floor)||hasArrivedAbove(floor)))
||(direction==DOWN && (c.hasRequestUnder(floor)||hasArrivedUnder(floor)))
)
) {
parking = false;
return;
}
if (direction==UP
&& !(c.hasRequestAbove(floor)
||hasArrivedAbove(floor)
||c.hasRequestOn(floor,UP))
||direction==DOWN
&& !(c.hasRequestUnder(floor)
||hasArrivedUnder(floor)
||c.hasRequestOn(floor,DOWN))) {
direction = !direction;
}
parking = true;
}
private boolean hasArrivedAbove(int f) {
for(Iterator it = list.iterator();it.hasNext();) {
Request r = (Request)it.next();
if (r.to > f) return true;
}
return false;
}
private boolean hasArrivedUnder(int f) {
for(Iterator it = list.iterator();it.hasNext();) {
Request r = (Request)it.next();
if (r.to < f) return true;
}
return false;
}
private boolean hasArrivedAt(int f) {
for(Iterator it = list.iterator();it.hasNext();) {
Request r = (Request)it.next();
if (r.to == f) return true;
}
return false;
}
private Request[] removeArrived(int f) {
ArrayList a = new ArrayList();
for(Iterator it = list.iterator();it.hasNext();) {
Request r = (Request)it.next();
if (r.to == f) {
it.remove();
a.add(r);
}
}
return (Request[])a.toArray(new Request[0]);
}
private void pickup() {
Request[] ra;
ra = c.removeRequests(floor,direction);
for(int i = 0; i < ra.length; i++) {
list.add(ra[i]);
}
}
private void debug() {
System.out.println("idle: " + idle);
System.out.println("parking: " + parking);
System.out.println("direction: " + (direction==UP?"UP":"DOWN"));
System.out.println("list: " + list);
}
private final int roomHeight; // height of a room of the building
private final int floors; // how many floors of the building
private volatile int pos; // current position, 0 .. (roomHeight * floors - 1)
private final int height; // height of the elevator
private volatile int floor; //
private volatile boolean parking; // the schedule result. To park at this station or not.
private final String name;
private volatile boolean direction; // whether the elevator is ascending or descending
private volatile boolean idle; // whether the elevator is idle;
private java.util.List list = new ArrayList(); //
private Controller c;
}
interface Direction {
boolean UP = true;
boolean DOWN = false;
}
/**
* A class represents a request of elevator. A request comes when someone need use the elevators.
*/
class Request {
final int from;
final int to;
final int weight;
final String id;
Request(int from,int to,int weight,String id) {
this.from = from;
this.to = to;
this.weight = weight;
this.id = id;
}
public String toString() {
return "From: " + from + " To: " + to + " Weight: " + " Id: " + id;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -