package therm; import java.util.*; // for Interface Observer & class Observable import java.awt.*; // for Canvas import java.rmi.*; import java.rmi.server.*; public class ThermObserverImpl extends Canvas implements ThermObserver { Thermometer currT; // Instance of thermometer being observed public ThermObserverImpl( Thermometer T ) throws RemoteException { // Export the remote object by listening for incoming calls to the obj // on a port. UnicastRemoteObject.exportObject( (Remote)this ); currT = T; T.addObserver( this ); // Register ThermObserverImpl as observer of T } public void attachObservable(Thermometer newT) throws RemoteException { //System.out.println("Entering ThermObserverImpl: attachObservable()"); if (newT != currT) { if (currT != null) currT.deleteObserver( this ); // Delete observer for prev currT = newT; currT.addObserver( this ); // Add observer for new thermo this.repaint(); // Repaint this canvas with } // new thermometer. } public void update(Object o, Object x)// From interface Observer { //System.out.println("Entering ThermObserverImpl: update()"); repaint(); } /******************************************************************** * paint() is used only to paint the first image of the thermometer. * All updates to the thermometer are done by the components method * update() which is shadowed below. ********************************************************************/ public void paint(Graphics g) { System.out.println("Entering ThermObserverImpl: paint()"); Dimension d = getSize(); // Get size of canvas int thermometerH = 3*d.height/4; // Calculate thermometer display height int thermometerW = 10; // and display width int xOrigin = (d.width - thermometerW)/2; // Center thermometer int yOrigin = (d.height - thermometerH)/2; // on canvas // Draw empty tube g.drawRect(xOrigin, yOrigin, thermometerW, thermometerH); // Mark tube with temperature readings g.setFont(new Font("Helvetica", Font.PLAIN, 8)); FontMetrics f = g.getFontMetrics(); int fH = f.getHeight(); int minTemp = 0, maxTemp = 0, temp = 0; try{ minTemp = currT.getMinTemp(); maxTemp = currT.getMaxTemp(); temp = currT.getTemp(); } catch ( RemoteException e) {} g.drawLine(xOrigin + 14, yOrigin, xOrigin + 19, yOrigin); g.drawString(maxTemp + " F", xOrigin + 23, yOrigin + fH/2); g.drawLine(xOrigin + 14, yOrigin + thermometerH/2, xOrigin + 19, yOrigin + thermometerH/2); g.drawString(((maxTemp - minTemp)/2) + " F", xOrigin + 23, yOrigin + (thermometerH + fH)/2); g.drawLine(xOrigin + 14, yOrigin + thermometerH, xOrigin + 19, yOrigin + thermometerH); g.drawString(minTemp + " F", xOrigin + 23, yOrigin + thermometerH + fH/2); // Calculate mercury height int mercuryH = thermometerH*(temp - minTemp)/(maxTemp - minTemp); // Fill tube w red mercury Color prevColor = g.getColor(); // Save current color g.setColor(Color.red); g.fillRect(xOrigin+1, yOrigin + thermometerH - mercuryH, thermometerW-1, mercuryH); // Draw bulb at bottom filled w red mercury g.drawOval(xOrigin - thermometerW/2, yOrigin + thermometerH, 2*thermometerW, 2*thermometerW); g.fillOval(xOrigin - thermometerW/2+1, yOrigin + thermometerH+1, 2*thermometerW-2, 2*thermometerW-2); g.setColor(prevColor); // Restore previous color // Write title g.setFont(new Font("Helvetica", Font.BOLD, 10)); f = g.getFontMetrics(); String title = ""; try{ title = currT.getTitle(); } catch (RemoteException e) {} g.drawString(title, (d.width - f.stringWidth(title))/2, yOrigin + thermometerH + 2*(thermometerW + fH)); } /******************************************************************** * Redefine the Component method update() to help control flicker by * avoiding repainting the entire thermometer canvas each time a part * of it changes. This update just redoes the amount of mercury and * the title each time it is called. repaint() is, thus, not called. * This reduces flicker substantially in this case. ********************************************************************/ public void update(Graphics g) { //System.out.println("Entering ThermObserverImpl: update()"); Dimension d = getSize(); // Get size of canvas int thermometerH = 3*d.height/4; // Calculate thermometer display height int thermometerW = 10; // and display width int xOrigin = (d.width - thermometerW)/2; // Get position of thermometer int yOrigin = (d.height - thermometerH)/2; // on canvas int minTemp = 0, maxTemp = 0, temp = 0; try{ minTemp = currT.getMinTemp(); maxTemp = currT.getMaxTemp(); temp = currT.getTemp(); } catch ( RemoteException e) {} // Paint over previous mercury in the tube Color prevColor = g.getColor(); // Save current color g.setColor(getBackground()); g.fillRect(xOrigin+1,yOrigin+1,thermometerW-1,thermometerH-2); g.setColor(prevColor); // Calculate new mercury height int mercuryH = thermometerH*(temp - minTemp)/(maxTemp - minTemp); // Fill tube w red mercury prevColor = g.getColor(); // Save current color g.setColor(Color.red); g.fillRect(xOrigin+1, yOrigin + thermometerH - mercuryH, thermometerW-1, mercuryH); g.setColor(prevColor); // Prepare to draw new title g.setFont(new Font("Helvetica", Font.BOLD, 10)); FontMetrics f = g.getFontMetrics(); int fH = f.getHeight(); // Erase current title prevColor = g.getColor(); g.setColor(getBackground()); g.fillRect(0, yOrigin + thermometerH + 2*thermometerW + fH, d.width, 3*fH/2); g.setColor(prevColor); // Draw new title String title = ""; try{ title = currT.getTitle(); } catch (RemoteException e) {} g.drawString(title, (d.width - f.stringWidth(title))/2, yOrigin + thermometerH + 2*(thermometerW + fH)); } public Dimension getMinimumSize() { System.out.println("Entering ThermObserverImpl: getMinimumSize()"); return new Dimension(100,200); } public Dimension getPreferredSize() { System.out.println("Entering ThermObserverImpl: getPreferredSize()"); return new Dimension(200,400); } }