Return-Path: <env_935140838250543897@hermes.java.sun.com>
Received: from pacific-carrier-annex.mit.edu by po10.mit.edu (8.9.2/4.7) id RAA05877; Tue, 21 Aug 2001 17:53:10 -0400 (EDT)
Received: from hermes.java.sun.com (hermes.java.sun.com [204.160.241.85])
	by pacific-carrier-annex.mit.edu (8.9.2/8.9.2) with SMTP id RAA29618
	for <alexp@mit.edu>; Tue, 21 Aug 2001 17:53:09 -0400 (EDT)
Message-Id: <200108212153.RAA29618@pacific-carrier-annex.mit.edu>
Date: Tue, 21 Aug 2001 14:53:09 PDT
From: "JDC Tech Tips" <body_935140838250543897@hermes.java.sun.com>
To: alexp@mit.edu
Subject: JDC Tech Tips  August 21, 2001
Precedence: junk
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-Mailer: Beyond Email 2.2


 J  D  C    T  E  C  H    T  I  P  S

                      TIPS, TECHNIQUES, AND SAMPLE CODE


WELCOME to the Java Developer Connection(sm) (JDC) Tech Tips, 
August 21, 2001. This issue covers:

         * Supporting an Unlimited Number of Applet Parameters 
         * Delivering Dynamic Images from JavaServer Pages(tm) 
           (JSP(tm)) Technology

These tips were developed using Java(tm) 2 SDK, Standard Edition, 
v 1.3.       

This issue of the JDC Tech Tips is written by John Zukowski, 
president of JZ Ventures, Inc. (http://www.jzventures.com).

You can view this issue of the Tech Tips on the Web at
http://java.sun.com/jdc/JDCTechTips/2001/tt0821.html

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
SUPPORTING AN UNLIMITED NUMBER OF APPLET PARAMETERS

Have you ever had an applet that you wanted to support an 
unlimited number of parameters? Because applets can't query what 
parameters are passed in, they need to know parameter names in 
advance. But to support an unlimited number of parameters, how 
does an applet know the names in advance? Here are two approaches 
you can use in an applet to support an unlimited number of 
parameters.

The first approach to unlimited parameter support sidesteps the 
issue somewhat. Instead of passing an unlimited number of 
parameters, you put them all in one parameter and parse the 
multiple parameters by using the java.util.StringTokenizer class. 
For example, if you wanted to pass in a list of choices for 
display in an AWT List control, your parameter settings might 
look like this:

<param
  name="ChineseNames" 
  value="Shu, Niu, Hu, T'u, Lung, She, Ma, Yang, Hou, 
    Chi, Kou, Chu">
<param
  name="EnglishNames"
  value="Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, 
    Ram, Monkey, Rooster, Dog, Boar">

At this point, you can read each parameter with the standard 
getParameter() method of Applet:

  String chineseNames = getParameter("ChineseNames");
  String englishNames = getParameter("EnglishNames");

To parse the string, all you have to do is create a 
java.util.StringTokenizer, with the appropriate delimiters. You 
can then iterate through the individual parameters like an 
Enumeration, or use the hasMoreTokens() / nextToken() pair of 
methods. The nextToken() method returns a String so you won't 
have to cast from an Object to the more appropriate data type.

StringTokenizer chinese = 
  new StringTokenizer(chineseNames, ", ");
while (chinese.hasMoreTokens()) {
    System.out.println(chinese.nextToken());
  }

Instead of using the StringTokenizer to parse a single parameter 
into its pieces, wouldn't it be nicer if you could just provide 
separate parameters for each? While the animal year names in the 
example above were relatively short, imagine if each parameter 
was something like a URL, with a minimum width of twenty 
characters. The second approach to unlimited parameter support 
allows you to specify each name as a separate parameter.

In order to support an unlimited number of parameters by 
specifying each parameter separately, the parameters must 
follow a common naming pattern. For instance, PARAM1, PARAM2, 
PARAM3, ... Then, all you have to do is look for the next 
numbered parameter until no more are available. Once you find  
that one of the parameters isn't available, for example, PARAM4, 
you don't have to look for PARAM5, PARAM6, or PARAM7. If you
split apart the parameter setting used in the first approach,
and follow the naming pattern, you get something like this:

<param 
  name="Chinese1"
  value="Shu">
<param 
  name="Chinese2"
  value="Niu">
<param 
  name="Chinese3"
  value="Hu">
<param 
  name="Chinese4"
  value="T'u">
<param 
  name="Chinese5"
  value="Lung">
<param 
  name="Chinese6"
  value="She">
<param 
  name="Chinese7"
  value="Ma">
<param 
  name="Chinese8"
  value="Yang">
<param 
  name="Chinese9"
  value="Hou">
<param 
  name="Chinese10"
  value="Chi">
<param 
  name="Chinese11"
  value="Kou">
<param 
  name="Chinese12"
  value="Chu">
<param 
  name="English1"
  value="Rat">
<param 
  name="English2"
  value="Ox">
<param 
  name="English3"
  value="Tiger">
<param 
  name="English4"
  value="Rabbit">
<param 
  name="English5"
  value="Dragon">
<param 
  name="English6"
  value="Snake">
<param 
  name="English7"
  value="Horse">
<param 
  name="English8"
  value="Ram">
<param 
  name="English9"
  value="Monkey">
<param 
  name="English10"
  value="Rooster">
<param 
  name="English11"
  value="Dog">
<param 
  name="English12"
  value="Boar">

Reading the parameters gets a little more complicated. But you 
don't have to bother with a StringTokenizer, or excessively long 
value strings in the HTML file. All you have to do is put the 
getParameter() call in a while loop, where you increase an index 
with each pass through the loop. When there are no more 
parameters, you stop.  

  String value;
  int i = 1;
  while ((value = getParameter("Chinese" + i)) 
                                             != null) {
    System.out.println ("Param" + i + ": " + value);
    i++;
  }  

This method of working with unlimited parameters is demonstrated 
in its entirety with the following applet. The applet reads 
in the Chinese and English animal year names. It also has a text 
field; if a user enters a year in the text field, the applet
finds the appropriate animal for that year.

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.StringTokenizer;

public class AnimalYears2 extends Applet {
  List chineseList = new List();
  List englishList = new List();
  TextField inputField = new TextField();

  /**Initialize the applet*/
  public void init() {

    setLayout(new BorderLayout());

    String value;
    int i = 1;
    while ((value = getParameter("Chinese" + i)) 
                                             != null) {
      chineseList.add(value);
      i++;
    }
    chineseList.setEnabled(false);
    add(chineseList, BorderLayout.WEST);

    i = 1;
    while ((value = getParameter("English" + i)) 
                                             != null) {
      englishList.add(value);
      i++;
    }
    englishList.setEnabled(false);
    add(englishList, BorderLayout.EAST);

    inputField.addActionListener(
                  new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        String yearString = inputField.getText();
        try {
          int year = Integer.parseInt(yearString);
          year = year - 1900;
          int index = year % 12;
          if (index < 0) {
            index = 12+index;
          }
          chineseList.select(index);
          englishList.select(index);
        } catch (NumberFormatException exc) {
          getToolkit().beep();
        }
      }
    });
    add(inputField,  BorderLayout.NORTH);
  }
}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DELIVERING DYNAMIC IMAGES FROM JAVASERVER PAGES (JSP) TECHNOLOGY

Have you ever wanted to deliver dynamically-generated images from 
your JSP pages (or servlets)? This tip shows you how. To run the 
code in this tip, you need Tomcat or another JSP 1.1-enabled web 
server. You can download Tomcat from the Jakarta Project page at 
http://jakarta.apache.org/tomcat.

When a web page is delivered with a MIME type of image/jpeg (or 
one of the other image formats), your browser treats the response 
as an image. The browser then displays the image, either as part 
of a larger web page or on its own. To set up the MIME type for 
your JSP pages, you need to set the contentType attribute of the 
page directive in the .jsp file for the specific page:

<%@ page contentType="image/jpeg" ... %>

Then you need to create a BufferedImage to draw on for your 
dynamic image:

BufferedImage image = new BufferedImage(width, 
  height, BufferedImage.TYPE_INT_RGB);
 
After you create the BufferedImage, you need to get a graphics 
context to draw with, either a Graphics or Graphics2D object will 
do:  

Graphics   g   = image.getGraphics();
// or
Graphics2d g2d = image.createGraphics();

From here, you can draw the image content. Drawing to the 
graphics context draws to the BufferedImage. Initially, the 
entire image is black, so it's a good idea to fill the image with 
the desired background color. Then, when you are finished drawing, 
you need to dispose of the context:

g.dispose();
// or
g2d.dispose();

Once the image is completely drawn, you send the image back in 
the response. You can use the JPEGImageEncoder class of the 
non-standard com.sun.image.codec.jpeg package to encode the 
image. Or, if you use the Java 2 SDK, Standard Edition, v 1.4 
Beta, you can use the standard ImageIO class. There is one tricky 
part of using the JPEGImageEncoder. You must fetch the 
ServletOutputStream from the ServletResponse (response object), 
and not use the implicit JSP output variable out.

ServletOutputStream sos = response.getOutputStream();
JPEGImageEncoder encoder = 
  JPEGCodec.createJPEGEncoder(sos);
encoder.encode(image);
// or
ImageIO.write(image, "JPEG", out);

Here's a complete example that picks one option from all the 
choices (for example, g.dispose(); versus g2d.dispose();).
The example uses the Graphics object to draw a random 
polygon. The image is drawn back through the JPEGImageEncoder. 
Feel free to play with the number of points in the polygon to get 
more complex shapes, in other words, shapes with more points and 
edges. 

To run this example, place the JSP code from "<%@" to the 
last "%>" in a file named image.jsp. Place the image.jsp file in 
a directory that your web server can find. In the case of Tomcat, 
this is the ROOT directory, under the webapps directory, beneath 
the Tomcat installation directory. To start Tomcat, you need to 
run the startup script (startup.bat or startup.sh depending upon 
your platform) in the bin directory under the Tomcat installation 
directory. Make sure you have the JAVA_HOME environment variable 
set to the root level of your Java 2 SDK installation, for 
example, C:\jdk1.2.2. Once the file is in the appropriate 
directory and Tomcat is running, you can load the dynamic image 
generating JSP file with http://localhost:8080/image.jsp.

<%@ page contentType="image/jpeg" 
    import="java.awt.*,java.awt.image.*,
      com.sun.image.codec.jpeg.*,java.util.*"
%>

<%

// Create image
int width=200, height=200;
BufferedImage image = new BufferedImage(width, 
  height, BufferedImage.TYPE_INT_RGB);

// Get drawing context
Graphics g = image.getGraphics();

// Fill background
g.setColor(Color.white);
g.fillRect(0, 0, width, height);

// Create random polygon
Polygon poly = new Polygon();
Random random = new Random();
for (int i=0; i < 5; i++) {
  poly.addPoint(random.nextInt(width), 
    random.nextInt(height));
}

// Fill polygon
g.setColor(Color.cyan);
g.fillPolygon(poly);

// Dispose context
g.dispose();

// Send back image
ServletOutputStream sos = response.getOutputStream();
JPEGImageEncoder encoder = 
  JPEGCodec.createJPEGEncoder(sos);
encoder.encode(image);

%>

.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .

- NOTE

Sun respects your online time and privacy. The Java Developer 
Connection mailing lists are used for internal Sun Microsystems(tm) 
purposes only. You have received this email because you elected 
to subscribe. To unsubscribe, go to the Subscriptions page 
http://developer.java.sun.com/subscription/ 
uncheck the appropriate checkbox, and click the Update button.


- SUBSCRIBE

To subscribe to a JDC newsletter mailing list, go to the 
Subscriptions page 
http://developer.java.sun.com/subscription/
choose the newsletters you want to subscribe to, and click 
Update.


- FEEDBACK
Comments? Send your feedback on the JDC Tech Tips to:

jdc-webmaster@sun.com


- ARCHIVES
You'll find the JDC Tech Tips archives at:

http://java.sun.com/jdc/TechTips/index.html


- COPYRIGHT
Copyright 2001 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA.

This document is protected by copyright. For more information, see:

http://java.sun.com/jdc/copyright.html


- LINKS TO NON-SUN SITES
The JDC Tech Tips may provide, or third parties may provide, 
links to other Internet sites or resources. Because Sun has no 
control over such sites and resources, You acknowledge and agree 
that Sun is not responsible for the availability of such external 
sites or resources, and does not endorse and is not responsible 
or liable for any Content, advertising, products, or other 
materials on or available from such sites or resources. Sun will 
not be responsible or liable, directly or indirectly, for any 
damage or loss caused or alleged to be caused by or in connection 
with use of or reliance on any such Content, goods or services 
available on or through any such site or resource.


JDC Tech Tips 
August 21, 2001

Sun, Sun Microsystems, Java, Java Developer Connection, 
JavaServer Pages, and JSP are trademarks or registered trademarks 
of Sun Microsystems, Inc. in the United States and other 
countries.


	To use our one-click unsubscribe facility, select the following URL:
	http://hermes.java.sun.com/unsubscribe?935140838250543897
