p1/machine/ElevatorGui.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[];
}
}