public void paintAfterMotes(Graphics g) {
    FontMetrics fm = g.getFontMetrics();
    g.setColor(Color.BLACK);

    /* Paint last output below motes */
    Mote[] allMotes = simulation.getMotes();
    for (Mote mote : allMotes) {
      String msg = null;
      {
        IPAddress ipAddr = mote.getInterfaces().getIPAddress();
        if (ipAddr != null) {
          msg = ipAddr.getIPString();
        }
      }

      if (msg == null) {
        RimeAddress rimeAddr = mote.getInterfaces().getRimeAddress();
        if (rimeAddr != null) {
          msg = rimeAddr.getAddressString();
        }
      }

      if (msg == null) {
        continue;
      }

      Position pos = mote.getInterfaces().getPosition();
      Point pixel = visualizer.transformPositionToPixel(pos);

      int msgWidth = fm.stringWidth(msg);
      g.drawString(msg, pixel.x - msgWidth / 2, pixel.y + 2 * Visualizer.MOTE_RADIUS + 3);
    }
  }
        public void update(Observable obs, Object obj) {

          /* Observe Rime and IP addresses */
          for (Mote mote : simulation.getMotes()) {
            IPAddress ipAddr = mote.getInterfaces().getIPAddress();
            if (ipAddr != null) {
              ipAddr.addObserver(addrObserver);
            }
            RimeAddress rimeAddr = mote.getInterfaces().getRimeAddress();
            if (rimeAddr != null) {
              rimeAddr.addObserver(addrObserver);
            }
          }
          visualizer.repaint();
        }
 public void update(Observable obs, Object obj) {
   visualizer.repaint();
 }
 {
   Visualizer.registerVisualizerSkin(CodeVisualizerSkin.class);
 }