FileDocCategorySizeDatePackage
AppletViewer.javaAPI DocExample3803Tue Jan 25 10:45:14 GMT 2000None

AppletViewer.java

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

import Acme.JPM.Encoders.GifEncoder;
import Acme.MainFrameModified;

public class AppletViewer extends HttpServlet { 

  static final int WIDTH = 450;
  static final int HEIGHT = 320;

  public void doGet(HttpServletRequest req, HttpServletResponse res)
                               throws ServletException, IOException {
    ServletOutputStream out = res.getOutputStream();

    MainFrameModified frame = null;
    Graphics g = null;
    Applet applet = null;

    try {
      String appletParam = req.getParameter("applet");
      String widthParam = req.getParameter("width");
      String heightParam = req.getParameter("height");

      // Load the given applet
      // Must be in the standard CLASSPATH
      try {
        applet = (Applet) Class.forName(appletParam).newInstance();
      }
      catch (Exception e) { 
        throw new ServletException("Could not load applet:" + e);
      }
  
      // Convert width/height to integers
      // Use default values if they weren't given or there's a problem
      int width = WIDTH;
      int height = HEIGHT;
      try { width = Integer.parseInt(widthParam); }
      catch (NumberFormatException e) { /* leave as default */ }
      try { height = Integer.parseInt(heightParam); }
      catch (NumberFormatException e) { /* leave as default */ }
  
      // Get a list of the other parameters in a format MainFrame understands
      // (Specifically, an array of "name=value" Strings)
      Vector temp = new Vector();
      Enumeration names = req.getParameterNames();
      while (names.hasMoreElements()) {
        String name = (String) names.nextElement();
        if (name != "applet" && name != "width" && name != "height")
          temp.addElement(name + "=" + req.getParameter(name));
      }
      temp.addElement("barebones=true");  // run without a menu bar
      // Now from Vector to array
      int size = temp.size();
      String args[] = new String[size];
      for (int i = 0; i < size; i++) { 
        args[i] = (String) temp.elementAt(i);
      }

      // Put the applet in its frame
      // addNotify() is called by MainFrameModified
      frame = new MainFrameModified(applet, args, width, height);
  
      // Get a graphics region to match the applet size, using the Frame
      Image image = frame.createImage(width, height);
      g = image.getGraphics();

      // Ask the applet to paint its children and itself
      applet.validate();
      paintContainerChildren(g, applet);
      applet.paint(g);
  
      // Encode and return what it painted
      res.setContentType("image/gif");
      GifEncoder encoder = new GifEncoder(image, out);
      encoder.encode();
    }
    finally {
      // Clean up resources
      if (applet != null) {
        applet.stop();
        applet.destroy();
        applet.removeAll();
      }
      if (g != null) {
        g.dispose();
      }
      if (frame != null) {
        frame.removeAll();
        frame.removeNotify();
        frame.dispose();
      }
    }
  }
  
  // Recursively paints all the Components of a Container.
  // It's different than paintComponents(Graphics) because 
  // paintComponents(Graphics) does not paint to the passed-in 
  // Graphics!  It uses it only to get the clipping region.
  void paintContainerChildren(Graphics g, Container c) {
    Component[] children = c.getComponents();
    for (int i = 0; i < children.length; i++) {
      if (children[i] != null) {
        children[i].paintAll(g);  // get lightweights too
        if (children[i] instanceof Container) {
          paintContainerChildren(g, (Container)children[i]);
        }
      }
    }
  }

}