// 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[]; } }