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);
      }
    }
  }
}

DebugTag.java Custom tag that optionally makes use of a tag body

DebugTag.java Custom tag that optionally makes use of a tag body

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);
    }
  }
}

HeadingTag.java Custom tag that makes use of a tag body

HeadingTag.java Custom tag that makes use of a tag body


package cwp.tags;

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

/** Generates an HTML heading with the specified background
 *  color, foreground color, alignment, font, and font size.
 *  You can also turn on a border around it, which normally
 *  just barely encloses the heading, but which can also
 *  stretch wider. All attributes except the background
 *  color are optional.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class HeadingTag extends TagSupport {
  private String bgColor; // The one required attribute
  private String color = null;
  private String align="CENTER";
  private String fontSize="36";
  private String fontList="Arial, Helvetica, sans-serif";
  private String border="0";
  private String width=null;

  public void setBgColor(String bgColor) {
    this.bgColor = bgColor;
  }

  public void setColor(String color) {
    this.color = color;
  }

  public void setAlign(String align) {
    this.align = align;
  }

  public void setFontSize(String fontSize) {
    this.fontSize = fontSize;
  }

  public void setFontList(String fontList) {
    this.fontList = fontList;
  }

  public void setBorder(String border) {
    this.border = border;
  }

  public void setWidth(String width) {
    this.width = width;
  }

  public int doStartTag() {
    try {
      JspWriter out = pageContext.getOut();
      out.print("<TABLE BORDER=" + border +
                " BGCOLOR=\"" + bgColor + "\"" +
                " ALIGN=\"" + align + "\"");
      if (width != null) {
        out.print(" WIDTH=\"" + width + "\"");
      }
      out.print("><TR><TH>");
      out.print("<SPAN STYLE=\"" +
                "font-size: " + fontSize + "px; " +
                "font-family: " + fontList + "; ");
      if (color != null) {
        out.println("color: " + color + ";");
      }
      out.print("\"> "); // End of <SPAN ...>
    } catch(IOException ioe) {
      System.out.println("Error in HeadingTag: " + ioe);
    }
    return(EVAL_BODY_INCLUDE); // Include tag body
  }

  public int doEndTag() {
    try {
      JspWriter out = pageContext.getOut();
      out.print("</SPAN></TABLE>");
    } catch(IOException ioe) {
      System.out.println("Error in HeadingTag: " + ioe);
    }
    return(EVAL_PAGE); // Continue with rest of JSP page
  }
}

PrimeTag.java Custom tag that outputs a random prime number of a user-specifiable approximate length

PrimeTag.java Custom tag that outputs a random prime number of a user-specifiable approximate length

package cwp.tags;

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

/** Generates an N-digit random prime (default N = 50).
 *  Extends SimplePrimeTag, adding a length attribute
 *  to set the size of the prime. The doStartTag
 *  method of the parent class uses the len field
 *  to determine the approximate length of the prime.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class PrimeTag extends SimplePrimeTag {
  public void setLength(String length) {
    try {
      len = Integer.parseInt(length);
    } catch(NumberFormatException nfe) {
      len = 50;
    }
  }
}

SimplePrimeTag.java Custom tag that outputs a random prime number of a fixed approximate length

SimplePrimeTag.java Custom tag that outputs a random prime number of a fixed approximate length


package cwp.tags;

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

/** Generates a prime of approximately 50 digits.
 *  (50 is actually the length of the random number
 *  generated -- the first prime above that number will
 *  be returned.)
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class SimplePrimeTag extends TagSupport {
  protected int len = 50;

  public int doStartTag() {
    try {
      JspWriter out = pageContext.getOut();
      BigInteger prime = Primes.nextPrime(Primes.random(len));
      out.print(prime);
    } catch(IOException ioe) {
      System.out.println("Error generating prime: " + ioe);
    }
    return(SKIP_BODY);
  }
}

cwp-taglib.tld Tag Library Descriptor file used by the custom tags in this chapter.

cwp-taglib.tld Tag Library Descriptor file used by the custom tags in this chapter.

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
 PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
 "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

<!-- a tag library descriptor -->

<taglib>
  <!-- after this the default space is
        "http://java.sun.com/j2ee/dtds/jsptaglibrary_1_2.dtd"
   -->

  <tlibversion>1.0</tlibversion>
  <jspversion>1.1</jspversion>
  <shortname>cwp</shortname>
  <!-- ** CHANGED FROM "urn" TO "uri" IN TOMCAT 3.1 final ** -->
  <uri></uri>
  <info>
    A tag library from Core Web Programming Java 2 Edition,
    .
  </info>

<!--
  <tag>
    The name (after prefix) tag will have in JSP code
    <name>example</name>

    The actual class implementing tag. In
    Tomcat 3.1, it MUST be in a package.
    <tagclass>cwp.tags.ExampleTag</tagclass>

    Descriptive information about tag.
    <info>Simplest example: inserts one line of output</info>

    One of three values describing what goes between
    start and end tag. 
      empty: no body 
      JSP: body that is evaluated by container normally,
           then possibly processed by tag
      tagdependent: body is only processed by tag;
                    JSP in body is not evaluated. 
    ** NOTE: TOMCAT 3.1 FINAL DOES NOT SUPPORT BODYCONTENT **
    ** THE BETA SUPPORTED IT, AND IT IS PART OF SPEC, BUT... **
    <bodycontent>empty</bodycontent>
  </tag>      
-->

  <tag>
    <name>example</name>
    <tagclass>cwp.tags.ExampleTag</tagclass>
    <info>Simplest example: inserts one line of output</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT 
    <bodycontent>empty</bodycontent> -->
  </tag>      

  <tag>
    <name>simplePrime</name>
    <tagclass>cwp.tags.SimplePrimeTag</tagclass>
    <info>Outputs a random 50-digit prime.</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT 
    <bodycontent>empty</bodycontent> -->
  </tag>

  <tag>
    <name>prime</name>
    <tagclass>cwp.tags.PrimeTag</tagclass>
    <info>Outputs a random N-digit prime.</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT
    <bodycontent>empty</bodycontent> -->
    <attribute>
      <name>length</name>
      <required>false</required>
    </attribute>
  </tag>

  <tag>
    <name>heading</name>
    <tagclass>cwp.tags.HeadingTag</tagclass>
    <info>Outputs a 1-cell table used as a heading.</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT 
    <bodycontent>JSP</bodycontent> -->
    <attribute>
      <name>bgColor</name>
      <required>true</required>  <!-- bgColor is required -->
    </attribute>
    <attribute>
      <name>color</name>
      <required>false</required>
    </attribute>
    <attribute>
      <name>align</name>
      <required>false</required>
    </attribute>
    <attribute>
      <name>fontSize</name>
      <required>false</required>
    </attribute>
    <attribute>
      <name>fontList</name>
      <required>false</required>
    </attribute>
    <attribute>
      <name>border</name>
      <required>false</required>
    </attribute>
    <attribute>
      <name>width</name>
      <required>false</required>
    </attribute>
  </tag>

  <tag>
    <name>debug</name>
    <tagclass>cwp.tags.DebugTag</tagclass>
    <info>Includes body only if debug param is set.</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT 
    <bodycontent>JSP</bodycontent> -->
  </tag>

  <tag>
    <name>filter</name>
    <tagclass>cwp.tags.FilterTag</tagclass>
    <info>Replaces HTML-specific characters in body.</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT 
    <bodycontent>JSP</bodycontent> -->
  </tag>

  <tag>
    <name>repeat</name>
    <tagclass>cwp.tags.RepeatTag</tagclass>
    <info>Repeats body the specified number of times.</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT 
    <bodycontent>JSP</bodycontent> -->
    <attribute>
      <name>reps</name>
      <required>true</required>
      <!-- rtexprvalue indicates whether attribute
           can be a JSP expression. -->
      <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <name>if</name>
    <tagclass>cwp.tags.IfTag</tagclass>
    <info>if/condition/then/else tag.</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT 
    <bodycontent>JSP</bodycontent> -->
  </tag>

  <tag>
    <name>condition</name>
    <tagclass>cwp.tags.IfConditionTag</tagclass>
    <info>condition part of if/condition/then/else tag.</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT 
    <bodycontent>JSP</bodycontent> -->
  </tag>

  <tag>
    <name>then</name>
    <tagclass>cwp.tags.IfThenTag</tagclass>
    <info>then part of if/condition/then/else tag.</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT 
    <bodycontent>JSP</bodycontent> -->
  </tag>

  <tag>
    <name>else</name>
    <tagclass>cwp.tags.IfElseTag</tagclass>
    <info>else part of if/condition/then/else tag.</info>
    <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT 
    <bodycontent>JSP</bodycontent> -->
  </tag>

</taglib>

SharedCounts1.jsp, SharedCounts2.jsp, and SharedCounts3.jsp Three pages that all use the AccessCountBean. Results you get depend on which page is hit first and how many total hits the combined pages receive.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- 
Example of sharing beans. 

Taken from Core Web Programming Java 2 Edition
from Prentice Hall and Sun Microsystems Press,
.
May be freely used or adapted.
-->
<HTML>
<HEAD>
<TITLE>Shared Access Counts: Page 1</TITLE>
<LINK REL=STYLESHEET
      HREF="JSP-Styles.css"
      TYPE="text/css">
</HEAD>

<BODY>

<TABLE BORDER=5 ALIGN="CENTER">
  <TR><TH CLASS="TITLE">
      Shared Access Counts: Page 1</TABLE>
<P>
<jsp:useBean id="counter" 
             class="cwp.AccessCountBean"
             scope="application">
  <jsp:setProperty name="counter" 
                   property="firstPage"
                   value="SharedCounts1.jsp" />
</jsp:useBean>

Of SharedCounts1.jsp (this page), 
<A HREF="SharedCounts2.jsp">SharedCounts2.jsp</A>, and
<A HREF="SharedCounts3.jsp">SharedCounts3.jsp</A>, 
<jsp:getProperty name="counter" property="firstPage" />
was the first page accessed.
<P>
Collectively, the three pages have been accessed 
<jsp:getProperty name="counter" property="accessCount" />
times.
             
</BODY>
</HTML>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- 
Example of sharing beans. 
   
Taken from Core Web Programming Java 2 Edition
from Prentice Hall and Sun Microsystems Press,
.
May be freely used or adapted.
-->
<HTML>
<HEAD>
<TITLE>Shared Access Counts: Page 2</TITLE>
<LINK REL=STYLESHEET
      HREF="JSP-Styles.css"
      TYPE="text/css">
</HEAD>

<BODY>
<TABLE BORDER=5 ALIGN="CENTER">
  <TR><TH CLASS="TITLE">
      Shared Access Counts: Page 2</TABLE>
<P>
<jsp:useBean id="counter" 
             class="cwp.AccessCountBean"
             scope="application">
  <jsp:setProperty name="counter" 
                   property="firstPage"
                   value="SharedCounts2.jsp" />
</jsp:useBean>
Of SharedCounts2.jsp (this page), 
<A HREF="SharedCounts1.jsp">SharedCounts1.jsp</A>, and
<A HREF="SharedCounts3.jsp">SharedCounts3.jsp</A>, 
<jsp:getProperty name="counter" property="firstPage" />
was the first page accessed.
<P>
Collectively, the three pages have been accessed 
<jsp:getProperty name="counter" property="accessCount" />
times.      
</BODY>
</HTML>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- 
Example of sharing beans. 

Taken from Core Web Programming Java 2 Edition
from Prentice Hall and Sun Microsystems Press,
.
May be freely used or adapted.
-->
<HTML>
<HEAD>
<TITLE>Shared Access Counts: Page 3</TITLE>
<LINK REL=STYLESHEET
      HREF="JSP-Styles.css"
      TYPE="text/css">
</HEAD>

<BODY>
<TABLE BORDER=5 ALIGN="CENTER">
  <TR><TH CLASS="TITLE">
      Shared Access Counts: Page 3</TABLE>
<P>
<jsp:useBean id="counter" 
             class="cwp.AccessCountBean"
             scope="application">
  <jsp:setProperty name="counter" 
                   property="firstPage"
                   value="SharedCounts3.jsp" />
</jsp:useBean>
Of SharedCounts3.jsp (this page), 
<A HREF="SharedCounts1.jsp">SharedCounts1.jsp</A>, and
<A HREF="SharedCounts2.jsp">SharedCounts2.jsp</A>, 
<jsp:getProperty name="counter" property="firstPage" />
was the first page accessed.
<P>
Collectively, the three pages have been accessed 
<jsp:getProperty name="counter" property="accessCount" />
times.         
</BODY>
</HTML>

SaleEntry3.jsp Page that uses the SaleEntry bean, using property=”*” to read request parameters and assign them to bean properties

SaleEntry3.jsp Page that uses the SaleEntry bean, using property="*" to read request parameters and assign them to bean properties


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- 
Example of using jsp:setProperty and a general association
with the input parameters. See SaleEntry1.jsp
and SaleEntry2.jsp for alternatives. 
   
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 jsp:setProperty</TITLE>
<LINK REL=STYLESHEET
      HREF="JSP-Styles.css"
      TYPE="text/css">
</HEAD>

<BODY>
<TABLE BORDER=5 ALIGN="CENTER">
  <TR><TH CLASS="TITLE">
      Using jsp:setProperty</TABLE>
<jsp:useBean id="entry" class="cwp.SaleEntry" />
<%-- WARNING! Both the JSWDK 1.0.1 and the Java Web Server
              have a bug that makes them fail on automatic
              type conversions to double values.
--%>
<jsp:setProperty name="entry" property="*" />
<BR>
<TABLE ALIGN="CENTER" BORDER=1>
<TR CLASS="COLORED">
  <TH>Item ID<TH>Unit Price<TH>Number Ordered<TH>Total Price
<TR ALIGN="RIGHT">
  <TD><jsp:getProperty name="entry" property="itemID" />
  <TD>$<jsp:getProperty name="entry" property="itemCost" />
  <TD><jsp:getProperty name="entry" property="numItems" />
  <TD>$<jsp:getProperty name="entry" property="totalCost" />
</TABLE>      
</BODY>
</HTML>

SaleEntry.java //SaleEntry Bean
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());
  }
}