425 lines
9.0 KiB
Java
425 lines
9.0 KiB
Java
// PART OF THE MACHINE SIMULATION. DO NOT CHANGE.
|
|
|
|
package nachos.machine;
|
|
|
|
import java.awt.Frame;
|
|
import java.awt.Container;
|
|
import java.awt.Dimension;
|
|
import java.awt.Panel;
|
|
import java.awt.ScrollPane;
|
|
import java.awt.Canvas;
|
|
|
|
import java.awt.GridLayout;
|
|
import java.awt.FlowLayout;
|
|
import java.awt.Insets;
|
|
|
|
import java.awt.Rectangle;
|
|
import java.awt.Graphics;
|
|
import java.awt.Color;
|
|
|
|
/**
|
|
* A graphical visualization for the <tt>ElevatorBank</tt> class.
|
|
*/
|
|
public final class ElevatorGui extends Frame {
|
|
private final static int w=90, h=75;
|
|
|
|
private int numFloors, numElevators;
|
|
|
|
private ElevatorShaft[] elevators;
|
|
private Floor[] floors;
|
|
|
|
private int totalWidth, totalHeight;
|
|
|
|
ElevatorGui(int numFloors, int numElevators, int[] numRidersPerFloor) {
|
|
this.numFloors = numFloors;
|
|
this.numElevators = numElevators;
|
|
|
|
totalWidth = w*(numElevators+1);
|
|
totalHeight = h*numFloors;
|
|
|
|
setTitle("Elevator Bank");
|
|
|
|
Panel floorPanel = new Panel(new GridLayout(numFloors, 1, 0, 0));
|
|
|
|
floors = new Floor[numFloors];
|
|
for (int i=numFloors-1; i>=0; i--) {
|
|
floors[i] = new Floor(i, numRidersPerFloor[i]);
|
|
floorPanel.add(floors[i]);
|
|
}
|
|
|
|
Panel panel = new Panel(new GridLayout(1, numElevators+1, 0, 0));
|
|
|
|
panel.add(floorPanel);
|
|
|
|
elevators = new ElevatorShaft[numElevators];
|
|
for (int i=0; i<numElevators; i++) {
|
|
elevators[i] = new ElevatorShaft(i);
|
|
panel.add(elevators[i]);
|
|
}
|
|
|
|
add(panel);
|
|
pack();
|
|
|
|
setVisible(true);
|
|
|
|
repaint();
|
|
}
|
|
|
|
void openDoors(int elevator) {
|
|
elevators[elevator].openDoors();
|
|
}
|
|
|
|
void closeDoors(int elevator) {
|
|
elevators[elevator].closeDoors();
|
|
}
|
|
|
|
void setDirectionDisplay(int elevator, int direction) {
|
|
elevators[elevator].setDirectionDisplay(direction);
|
|
}
|
|
|
|
void pressUpButton(int floor) {
|
|
floors[floor].pressUpButton();
|
|
}
|
|
|
|
void clearUpButton(int floor) {
|
|
floors[floor].clearUpButton();
|
|
}
|
|
|
|
void pressDownButton(int floor) {
|
|
floors[floor].pressDownButton();
|
|
}
|
|
|
|
void clearDownButton(int floor) {
|
|
floors[floor].clearDownButton();
|
|
}
|
|
|
|
void enterElevator(int floor, int elevator) {
|
|
floors[floor].removeRider();
|
|
elevators[elevator].addRider();
|
|
}
|
|
|
|
void pressFloorButton(int floor, int elevator) {
|
|
elevators[elevator].pressFloorButton(floor);
|
|
}
|
|
|
|
void exitElevator(int floor, int elevator) {
|
|
elevators[elevator].removeRider();
|
|
floors[floor].addRider();
|
|
}
|
|
|
|
void elevatorMoved(int floor, int elevator) {
|
|
elevators[elevator].elevatorMoved(floor);
|
|
}
|
|
|
|
private void paintRider(Graphics g, int x, int y, int r) {
|
|
g.setColor(Color.yellow);
|
|
|
|
g.fillOval(x-r, y-r, 2*r, 2*r);
|
|
|
|
g.setColor(Color.black);
|
|
|
|
g.fillOval(x-r/2, y-r/2, r/3, r/3);
|
|
g.fillOval(x+r/4, y-r/2, r/3, r/3);
|
|
|
|
g.drawArc(x-r/2, y-r/2, r, r, 210, 120);
|
|
}
|
|
|
|
private void paintRiders(Graphics g, int x, int y, int w, int h, int n) {
|
|
int r = 8, t = 20;
|
|
|
|
int xn = w/t;
|
|
int yn = h/t;
|
|
|
|
int x0 = x + (w-xn*t)/2 + t/2;
|
|
int y0 = y + h - t/2;
|
|
|
|
for (int j=0; j<yn; j++) {
|
|
for (int i=0; i<xn; i++) {
|
|
if (n-- > 0)
|
|
paintRider(g, x0 + i*t, y0 - j*t, r);
|
|
}
|
|
}
|
|
}
|
|
|
|
private class Floor extends Canvas {
|
|
int floor, numRiders;
|
|
|
|
boolean upSet = false;
|
|
boolean downSet = false;
|
|
|
|
Floor(int floor, int numRiders) {
|
|
this.floor = floor;
|
|
this.numRiders = numRiders;
|
|
|
|
setBackground(Color.black);
|
|
}
|
|
|
|
public Dimension getPreferredSize() {
|
|
return new Dimension(w, h);
|
|
}
|
|
|
|
public Dimension getMinimumSize() {
|
|
return getPreferredSize();
|
|
}
|
|
|
|
public Dimension getMaximumSize() {
|
|
return getPreferredSize();
|
|
}
|
|
|
|
public void repaint() {
|
|
super.repaint();
|
|
|
|
if (TCB.isNachosThread()) {
|
|
try {
|
|
Thread.sleep(100);
|
|
}
|
|
catch (InterruptedException e) {
|
|
}
|
|
}
|
|
}
|
|
|
|
void pressUpButton() {
|
|
if (!upSet) {
|
|
upSet = true;
|
|
repaint();
|
|
}
|
|
}
|
|
|
|
void pressDownButton() {
|
|
if (!downSet) {
|
|
downSet = true;
|
|
repaint();
|
|
}
|
|
}
|
|
|
|
void clearUpButton() {
|
|
if (upSet) {
|
|
upSet = false;
|
|
repaint();
|
|
}
|
|
}
|
|
|
|
void clearDownButton() {
|
|
if (downSet) {
|
|
downSet = false;
|
|
repaint();
|
|
}
|
|
}
|
|
|
|
void addRider() {
|
|
numRiders++;
|
|
|
|
repaint();
|
|
}
|
|
|
|
void removeRider() {
|
|
numRiders--;
|
|
|
|
repaint();
|
|
}
|
|
|
|
public void paint(Graphics g) {
|
|
g.setColor(Color.lightGray);
|
|
g.drawLine(0, 0, w, 0);
|
|
|
|
paintRiders(g, 0, 5, 3*w/4, h-10, numRiders);
|
|
|
|
paintButtons(g);
|
|
}
|
|
|
|
private void paintButtons(Graphics g) {
|
|
int s = 3*w/4;
|
|
|
|
int x1 = s+w/32;
|
|
int x2 = w-w/32;
|
|
int y1 = h/8;
|
|
int y2 = h-h/8;
|
|
|
|
g.setColor(Color.darkGray);
|
|
g.drawRect(x1, y1, x2-x1, y2-y1);
|
|
g.setColor(Color.lightGray);
|
|
g.fillRect(x1+1, y1+1, x2-x1-2, y2-y1-2);
|
|
|
|
int r = Math.min((x2-x1)/3, (y2-y1)/6);
|
|
int xc = (x1+x2)/2;
|
|
int yc1 = (y1+y2)/2 - (3*r/2);
|
|
int yc2 = (y1+y2)/2 + (3*r/2);
|
|
|
|
g.setColor(Color.red);
|
|
|
|
if (floor < numFloors-1) {
|
|
if (upSet)
|
|
g.fillOval(xc-r, yc1-r, 2*r, 2*r);
|
|
else
|
|
g.drawOval(xc-r, yc1-r, 2*r, 2*r);
|
|
}
|
|
|
|
if (floor > 0) {
|
|
if (downSet)
|
|
g.fillOval(xc-r, yc2-r, 2*r, 2*r);
|
|
else
|
|
g.drawOval(xc-r, yc2-r, 2*r, 2*r);
|
|
}
|
|
}
|
|
}
|
|
|
|
private class ElevatorShaft extends Canvas {
|
|
ElevatorShaft(int elevator) {
|
|
this.elevator = elevator;
|
|
|
|
floorsSet = new boolean[numFloors];
|
|
for (int i=0; i<numFloors; i++)
|
|
floorsSet[i] = false;
|
|
|
|
setBackground(Color.black);
|
|
}
|
|
|
|
public Dimension getPreferredSize() {
|
|
return new Dimension(w, h*numFloors);
|
|
}
|
|
|
|
public Dimension getMinimumSize() {
|
|
return getPreferredSize();
|
|
}
|
|
|
|
public Dimension getMaximumSize() {
|
|
return getPreferredSize();
|
|
}
|
|
|
|
private void repaintElevator() {
|
|
repaint(s, h*(numFloors-1-Math.max(floor, prevFloor)), w-2*s, h*2);
|
|
|
|
try {
|
|
Thread.sleep(100);
|
|
}
|
|
catch (InterruptedException e) {
|
|
}
|
|
}
|
|
|
|
void openDoors() {
|
|
doorsOpen = true;
|
|
|
|
repaintElevator();
|
|
}
|
|
|
|
void closeDoors() {
|
|
doorsOpen = false;
|
|
|
|
repaintElevator();
|
|
}
|
|
|
|
void setDirectionDisplay(int direction) {
|
|
this.direction = direction;
|
|
|
|
repaintElevator();
|
|
}
|
|
|
|
void pressFloorButton(int floor) {
|
|
if (!floorsSet[floor]) {
|
|
floorsSet[floor] = true;
|
|
|
|
repaintElevator();
|
|
}
|
|
}
|
|
|
|
void elevatorMoved(int floor) {
|
|
prevFloor = this.floor;
|
|
this.floor = floor;
|
|
|
|
floorsSet[floor] = false;
|
|
|
|
repaintElevator();
|
|
}
|
|
|
|
void addRider() {
|
|
numRiders++;
|
|
|
|
repaintElevator();
|
|
}
|
|
|
|
void removeRider() {
|
|
numRiders--;
|
|
|
|
repaintElevator();
|
|
}
|
|
|
|
public void paint(Graphics g) {
|
|
g.setColor(Color.lightGray);
|
|
|
|
if (g.hitClip(0, 0, s, h*numFloors)) {
|
|
g.drawLine(0, 0, 0, h*numFloors);
|
|
g.drawLine(s-1, 0, s-1, h*numFloors);
|
|
for (int y=0; y<h*numFloors-s; y+=s)
|
|
g.drawLine(0, y, s-1, y+s-1);
|
|
}
|
|
|
|
if (g.hitClip(w-s, 0, s, h*numFloors)) {
|
|
g.drawLine(w-s, 0, w-s, h*numFloors);
|
|
g.drawLine(w-1, 0, w-1, h*numFloors);
|
|
for (int y=0; y<h*numFloors-s; y+=s)
|
|
g.drawLine(w-s, y, w-1, y+s-1);
|
|
}
|
|
|
|
// rectangle containing direction display area
|
|
Rectangle d = new Rectangle(s*3/2, h*(numFloors-1-floor),
|
|
w-3*s, w/3-s);
|
|
|
|
// unit of measurement in direction rect (12ux4u)
|
|
int u = d.width/12;
|
|
|
|
// draw elevator, fill riders
|
|
Rectangle e = new Rectangle(d.x, d.y+d.height,
|
|
d.width, h-d.height-u);
|
|
g.drawRect(e.x, e.y, e.width, e.height);
|
|
paintRiders(g, e.x, e.y, e.width, e.height, numRiders);
|
|
|
|
g.setColor(Color.lightGray);
|
|
|
|
// draw doors...
|
|
if (doorsOpen) {
|
|
g.drawLine(e.x+2*s, e.y, e.x+2*s, e.y+e.height);
|
|
for (int y=0; y<e.height-2*s; y+=2*s)
|
|
g.drawLine(e.x, e.y+y, e.x+2*s, e.y+y+2*s);
|
|
|
|
g.drawLine(e.x+e.width-2*s, e.y,
|
|
e.x+e.width-2*s, e.y+e.height);
|
|
for (int y=0; y<e.height-2*s; y+=2*s)
|
|
g.drawLine(e.x+e.width-2*s, e.y+y, e.x+e.width, e.y+y+2*s);
|
|
}
|
|
else {
|
|
for (int x=0; x<e.width; x+=2*s)
|
|
g.drawLine(e.x+x, e.y, e.x+x, e.y+e.height);
|
|
}
|
|
|
|
g.setColor(Color.yellow);
|
|
|
|
int[] xUp = { d.x + u*6, d.x + u*8, d.x + u*7 };
|
|
int[] yUp = { d.y + u*3, d.y + u*3, d.y + u*1 };
|
|
|
|
int[] xDown = { d.x + u*4, d.x + u*6, d.x + u*5 };
|
|
int[] yDown = { d.y + u*1, d.y + u*1, d.y + u*3 };
|
|
|
|
// draw arrows
|
|
if (direction == ElevatorBank.dirUp)
|
|
g.fillPolygon(xUp, yUp, 3);
|
|
else
|
|
g.drawPolygon(xUp, yUp, 3);
|
|
|
|
if (direction == ElevatorBank.dirDown)
|
|
g.fillPolygon(xDown, yDown, 3);
|
|
else
|
|
g.drawPolygon(xDown, yDown, 3);
|
|
}
|
|
|
|
private static final int s = 5;
|
|
|
|
private boolean doorsOpen = false;
|
|
private int floor = 0, prevFloor = 0, numRiders = 0;
|
|
private int direction = ElevatorBank.dirNeither;
|
|
|
|
private int elevator;
|
|
|
|
private boolean floorsSet[];
|
|
}
|
|
}
|