SaleEntry.java Bean used to demonstrate the various approaches to reading request parameters and stuffing them into Java objects.

package cwp;

/** Simple bean to illustrate the various forms
 *  of jsp:setProperty.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class SaleEntry {
  private String itemID = "unknown";
  private double discountCode = 1.0;
  private int numItems = 0;

  public String getItemID() {
    return(itemID);
  }

  public void setItemID(String itemID) {
    if (itemID != null) {
      this.itemID = itemID;
    } else {
      this.itemID = "unknown";
    }
  }

  public double getDiscountCode() {
    return(discountCode);
  }

  public void setDiscountCode(double discountCode) {
    this.discountCode = discountCode;
  }

  public int getNumItems() {
    return(numItems);
  }

  public void setNumItems(int numItems) {
    this.numItems = numItems;
  }

  // In real life, replace this with database lookup.

  public double getItemCost() {
    double cost;
    if (itemID.equals("a1234")) {
      cost = 12.99*getDiscountCode();
    } else {
      cost = -9999;
    }
    return(roundToPennies(cost));
  }

  private double roundToPennies(double cost) {
    return(Math.floor(cost*100)/100.0);
  }

  public double getTotalCost() {
    return(getItemCost() * getNumItems());
  }
}

The class that actually gets the strings over the network by means of an ObjectInputStream via HTTP tunneling.

import java.net.*;
import java.io.*;

/** When this class is built, it returns a value
 *  immediately, but this value returns false for isDone
 *  and null for getQueries. Meanwhile, it starts a Thread
 *  to request an array of query strings from the server,
 *  reading them in one fell swoop by means of an
 *  ObjectInputStream. Once they've all arrived, they
 *  are placed in the location getQueries returns,
 *  and the isDone flag is switched to true.
 *  Used by the ShowQueries applet.
 *  


 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
  *  May be freely used or adapted.
 */

public class QueryCollection implements Runnable {
  private String[] queries;
  private String[] tempQueries;
  private boolean isDone = false;
  private URL dataURL;

  public QueryCollection(String urlSuffix, URL currentPage) {
    try {
      // Only the URL suffix need be supplied, since
      // the rest of the URL is derived from the current page.
      String protocol = currentPage.getProtocol();
      String host = currentPage.getHost();
      int port = currentPage.getPort();
      dataURL = new URL(protocol, host, port, urlSuffix);
      Thread queryRetriever = new Thread(this);
      queryRetriever.start();
    } catch(MalformedURLException mfe) {
      isDone = true;
    }
  }

  public void run() {
    try {
      tempQueries = retrieveQueries();
      queries = tempQueries;
    } catch(IOException ioe) {
      tempQueries = null;
      queries = null;
    }
    isDone = true;
  }

  public String[] getQueries() {
    return(queries);
  }

  public boolean isDone() {
    return(isDone);
  }

  private String[] retrieveQueries() throws IOException {
    URLConnection connection = dataURL.openConnection();
    // Make sure browser doesn't cache this URL, since
    // I want different queries for each request.
    connection.setUseCaches(false);
    // Use ObjectInputStream so I can read a String[]
    // all at once.
    ObjectInputStream in =
      new ObjectInputStream(connection.getInputStream());
    try {
      // The return type of readObject is Object, so
      // I need a typecast to the actual type.
      String[] queryStrings = (String[])in.readObject();
      return(queryStrings);
    } catch(ClassNotFoundException cnfe) {
      return(null);
    }
  }
}

A class the encapsulates the URLs used by various search engines.

SearchSpec.java
*******************
/** Small class that encapsulates how to construct a
 *  search string for a particular search engine.
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,

 *  May be freely used or adapted.
 */

public class SearchSpec {
  private String name, baseURL, numResultsSuffix;

  private static SearchSpec[] commonSpecs =
    { new SearchSpec("google",
                     "http://www.google.com/search?q=",
                     "&num="),
      new SearchSpec("infoseek",
                     "http://infoseek.go.com/Titles?qt=",
                     "&nh="),
      new SearchSpec("lycos",
                     "http://lycospro.lycos.com/cgi-bin/" +
                        "pursuit?query=",
                     "&maxhits="),
      new SearchSpec("hotbot",
                     "http://www.hotbot.com/?MT=",
                     "&DC=")
    };

  public SearchSpec(String name,
                    String baseURL,
                    String numResultsSuffix) {
    this.name = name;
    this.baseURL = baseURL;
    this.numResultsSuffix = numResultsSuffix;
  }

  public String makeURL(String searchString,
                        String numResults) {
    return(baseURL + searchString +
           numResultsSuffix + numResults);
  }

  public String getName() {
    return(name);
  }

  public static SearchSpec[] getCommonSpecs() {
    return(commonSpecs);
  }
}

DebugExample.jsp Page that uses the DebugTag custom tag

# DebugExample.jsp Page that uses the DebugTag custom tag

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- 
Illustration of SimplePrimeTag tag. 

Taken from Core Web Programming Java 2 Edition
from Prentice Hall and Sun Microsystems Press,
.
May be freely used or adapted. 
-->
<HTML>
<HEAD>
<TITLE>Using the Debug Tag</TITLE>
<LINK REL=STYLESHEET
      HREF="JSP-Styles.css"
      TYPE="text/css">
</HEAD>
<BODY>
<H1>Using the Debug Tag</H1>
<%@ taglib uri="cwp-taglib.tld" prefix="cwp" %>
Top of regular page. Blah, blah, blah. Yadda, yadda, yadda.
<P>
<cwp:debug>
<B>Debug:</B>
<UL>
  <LI>Current time: <%= new java.util.Date() %>
  <LI>Requesting hostname: <%= request.getRemoteHost() %>
  <LI>Session ID: <%= session.getId() %>
</UL>
</cwp:debug>
<P>
Bottom of regular page. Blah, blah, blah. Yadda, yadda, yadda.
</BODY>
</HTML>

package cwp.tags;

import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
import javax.servlet.*;

/** A tag that includes the body content only if
 *  the "debug" request parameter is set.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class DebugTag extends TagSupport {
  public int doStartTag() {
    ServletRequest request = pageContext.getRequest();
    String debugFlag = request.getParameter("debug");
    if ((debugFlag != null) &&
        (!debugFlag.equalsIgnoreCase("false"))) {
      return(EVAL_BODY_INCLUDE);
    } else {
      return(SKIP_BODY);
    }
  }
}

ShearExample.java. Illustrates the effect of applying a shear transformation prior to drawing a square

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

/** An example of shear transformations on a rectangle. 
 *
 ***********************

public class ShearExample extends JPanel {
  private static int gap=10, width=100;
  private Rectangle rect = new Rectangle(gap, gap, 100, 100);

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    for (int i=0; i<5; i++) {
      g2d.setPaint(Color.red);
      g2d.fill(rect);
      // Each new square gets 0.2 more x shear.
      g2d.shear(0.2, 0.0);
      g2d.translate(2*gap + width, 0);
    }
  }

  public static void main(String[] args) {
    String title =
      "Shear: x shear ranges from 0.0 for the leftmost" +
      "'square' to 0.8 for the rightmost one.";
    WindowUtilities.openInJFrame(new ShearExample(),
                                 20*gap + 5*width, 
                                 5*gap + width,
                                 title);
  }
}

LineStyles.java Provides examples of the available styles for joining line segments

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

/** A demonstration of different controls when joining two line
 *  segments. The style of the line end point is controlled
 *  through the capStyle parameter.
 *
 ************************************

public class LineStyles extends JPanel {
  private GeneralPath path;
  private static int x = 30, deltaX = 150, y = 300,
                     deltaY = 250, thickness = 40;
  private Circle p1Large, p1Small, p2Large, p2Small,
                 p3Large, p3Small;
  private int compositeType = AlphaComposite.SRC_OVER;
  private AlphaComposite transparentComposite =
    AlphaComposite.getInstance(compositeType, 0.4F);
  private int[] caps =
    { BasicStroke.CAP_SQUARE, BasicStroke.CAP_BUTT,
      BasicStroke.CAP_ROUND };
  private String[] capNames =
    { "CAP_SQUARE", "CAP_BUTT", "CAP_ROUND" };
  private int[] joins =
    { BasicStroke.JOIN_MITER, BasicStroke.JOIN_BEVEL,
      BasicStroke.JOIN_ROUND };
  private String[] joinNames =
    { "JOIN_MITER", "JOIN_BEVEL", "JOIN_ROUND" };

  public LineStyles() {
    path = new GeneralPath();
    path.moveTo(x, y);
    p1Large = new Circle(x, y, thickness/2);
    p1Small = new Circle(x, y, 2);
    path.lineTo(x + deltaX, y - deltaY);
    p2Large = new Circle(x + deltaX, y - deltaY, thickness/2);
    p2Small = new Circle(x + deltaX, y - deltaY, 2);
    path.lineTo(x + 2*deltaX, y);
    p3Large = new Circle(x + 2*deltaX, y, thickness/2);
    p3Small = new Circle(x + 2*deltaX, y, 2);
    setFont(new Font("SansSerif", Font.BOLD, 20));
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    g2d.setColor(Color.lightGray);
    for(int i=0; i

Illustrates using a local font (Goudy Handtooled BT) to perform drawing in Java 2D

import java.awt.*;

/** An example of using local fonts to perform drawing in
 *  Java 2D.
 *
 **********************

public class FontExample extends GradientPaintExample {
  public FontExample() {
    GraphicsEnvironment env =
      GraphicsEnvironment.getLocalGraphicsEnvironment();
    env.getAvailableFontFamilyNames();
    setFont(new Font("Goudy Handtooled BT", Font.PLAIN, 100));
  }

  protected void drawBigString(Graphics2D g2d) {
    g2d.setPaint(Color.black);
    g2d.drawString("Java 2D", 25, 215);
  }

  public void paintComponent(Graphics g) {
    clear(g);
    Graphics2D g2d = (Graphics2D)g;
    drawGradientCircle(g2d);
    drawBigString(g2d);
  }

  public static void main(String[] args) {
    WindowUtilities.openInJFrame(new FontExample(), 380, 400);
  }
}

Draws a circle with a gradient fill

GradientPaintExample.java Draws a circle with a gradient fill. Inherits from ShapeExample.java. 
**************************************
import java.awt.*;

/** An example of applying a gradient fill to a circle. The
 *  color definition starts with red at (0,0), gradually
 *  changing to yellow at (175,175).
 *
 **********************************

public class GradientPaintExample extends ShapeExample {
  private GradientPaint gradient =
    new GradientPaint(0, 0, Color.red, 175, 175, Color.yellow,
                      true); // true means to repeat pattern

  public void paintComponent(Graphics g) {
    clear(g);
    Graphics2D g2d = (Graphics2D)g;
    drawGradientCircle(g2d);
  }

  protected void drawGradientCircle(Graphics2D g2d) {
    g2d.setPaint(gradient);
    g2d.fill(getCircle());
    g2d.setPaint(Color.black);
    g2d.draw(getCircle());
  }

  public static void main(String[] args) {
    WindowUtilities.openInJFrame(new GradientPaintExample(),
                                 380, 400);
  }
}

An applet that permits freehand drawing

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

/** An applet that lets you perform freehand drawing.
 *  


 ****************

public class SimpleWhiteboard extends Applet {
  protected int lastX=0, lastY=0;

  public void init() {
    setBackground(Color.white);
    setForeground(Color.blue);
    addMouseListener(new PositionRecorder());
    addMouseMotionListener(new LineDrawer());
  }

  protected void record(int x, int y) {
    lastX = x;
    lastY = y;
  }

  // Record position that mouse entered window or
  // where user pressed mouse button.
  
  private class PositionRecorder extends MouseAdapter {
    public void mouseEntered(MouseEvent event) {
      requestFocus(); // Plan ahead for typing
      record(event.getX(), event.getY());
    }

    public void mousePressed(MouseEvent event) {
      record(event.getX(), event.getY());
    }
  }

  // As user drags mouse, connect subsequent positions
  // with short line segments.
  
  private class LineDrawer extends MouseMotionAdapter {
    public void mouseDragged(MouseEvent event) {
      int x = event.getX();
      int y = event.getY();
      Graphics g = getGraphics();
      g.drawLine(lastX, lastY, x, y);
      record(x, y);
    }
  }
}

A TextField that uses key events to correct the spelling of the names of computer languages entered into it

import java.awt.*;
import java.awt.event.*;

/** A spelling-correcting TextField for entering
 *  a language name.
 *  


 *******************

public class LanguageField extends TextField {
  private String[] substrings =
    { "", "J", "Ja", "Jav", "Java" };

  public LanguageField() {
    addKeyListener(new SpellingCorrector());
    addActionListener(new WordCompleter());
    addFocusListener(new SubliminalAdvertiser());
  }

  // Put caret at end of field.
  
  private void setCaret() {
    setCaretPosition(5);
  }
  
  // Listener to monitor/correct spelling as user types.
  
  private class SpellingCorrector extends KeyAdapter {
    public void keyTyped(KeyEvent event) {
      setLanguage();
      setCaret();
    }

    // Enter partial name of good programming language that
    // most closely matches what they've typed so far.
    
    private void setLanguage() {
      int length = getText().length();
      if (length <= 4) {
        setText(substrings[length]);
      } else {
        setText("Java");
      }
      setCaret();
    }
  }

  // Listener to replace current partial name with
  // most closely-matching name of good language.
  
  private class WordCompleter implements ActionListener {

    // When they hit RETURN, fill in the right answer.
    
    public void actionPerformed(ActionEvent event) {
      setText("Java");
      setCaret();
    }
  }

  // Listener to give the user a hint.
  
  private class SubliminalAdvertiser extends FocusAdapter {
    public void focusGained(FocusEvent event) {
      String text = getText();
      for(int i=0; i<10; i++) {
        setText("Hint: Java");
        setText(text);
      }
    }
  }
}