Return-Path: 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 ; 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" 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: 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: 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