Implementation Class for a Remote ThermObserver Object






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);
 }
}