|
Tech Tips Archive
August 21, 2001
WELCOME to the Java Developer Connection (JDC) Tech Tips, August 21, 2001. This issue covers:
These tips were developed using Java 2 SDK, Standard Edition, v 1.3.
This issue of the JDC Tech Tips is written by John Zukowski, president of JZ Ventures, Inc.
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
See the update to this tip.
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.
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 purposes only. You have received this email because you elected to subscribe. To unsubscribe, go to the Subscriptions page, uncheck the appropriate checkbox, and click the Update button.
As of May 22, 2001, Sun Microsystems updated its Privacy Policy to give you a better understanding of Sun's Privacy Policy and Practice. If you have any questions, contact privacy@sun.com.
- SUBSCRIBE
To subscribe to a JDC newsletter mailing list, go to the Subscriptions page, 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.
This issue of the JDC Tech Tips is written by John Zukowski.
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.
|