Category Archives: Java/J2EE/J2ME

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

SaleEntry1.jsp Page that uses the SaleEntry bean, using explicit Java code to read request parameters and assign them to bean properties.

SaleEntry1.jsp Page that uses the SaleEntry bean, using explicit Java code 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 with an explicit value
supplied to the "value" attribute. See SaleEntry2.jsp
and SaleEntry3.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" />
<jsp:setProperty 
    name="entry" 
    property="itemID"
    value='<%= request.getParameter("itemID") %>' />
<%
int numItemsOrdered = 1;
try {
  numItemsOrdered = 
    Integer.parseInt(request.getParameter("numItems"));
} catch(NumberFormatException nfe) {}
%>
<jsp:setProperty 
    name="entry" 
    property="numItems"
    value="<%= numItemsOrdered %>" />
<% 
double discountCode = 1.0;
try {
  String discountString = 
    request.getParameter("discountCode");
  // Double.parseDouble not available in JDK 1.1.
  discountCode = 
    Double.valueOf(discountString).doubleValue();
} catch(NumberFormatException nfe) {}
%>
<jsp:setProperty 
    name="entry" 
    property="discountCode"
    value="<%= discountCode %>" />
<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 //sale entry 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());
  }
}

StringBean.jsp Page that manipulates the StringBean bean with both jsp:useBean (i.e., XML-style) syntax

StringBean.jsp Page that manipulates the StringBean bean with both jsp:useBean (i.e., XML-style) syntax


package cwp;

/** Simple bean to illustrate sharing beans through
 *  use of the scope attribute of jsp:useBean.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class AccessCountBean {
  private String firstPage;
  private int accessCount = 1;

  public String getFirstPage() {
    return(firstPage);
  }

  public void setFirstPage(String firstPage) {
    this.firstPage = firstPage;
  }

  public int getAccessCount() {
    return(accessCount++);
  }
}

RepeatTag.java Custom tag that repeats the tag body a specified number of times

RepeatTag.java Custom tag that repeats the tag body a specified number of times

package cwp.tags;

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

/** A tag that repeats the body the specified
 *  number of times.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class RepeatTag extends BodyTagSupport {
  private int reps;

  public void setReps(String repeats) {
    try {
      reps = Integer.parseInt(repeats);
    } catch(NumberFormatException nfe) {
      reps = 1;
    }
  }

  public int doAfterBody() {
    if (reps-- >= 1) {
      BodyContent body = getBodyContent();
      try {
        JspWriter out = body.getEnclosingWriter();
        out.println(body.getString());
        body.clearBody(); // Clear for next evaluation
      } catch(IOException ioe) {
        System.out.println("Error in RepeatTag: " + ioe);
      }
      return(EVAL_BODY_TAG);
    } else {
      return(SKIP_BODY);
    }
  }
}

RepeatExample.jsp


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- 
Illustration of RepeatTag 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>Some 40-Digit Primes</TITLE>
<LINK REL=STYLESHEET
      HREF="JSP-Styles.css"
      TYPE="text/css">
</HEAD>
<BODY>
<H1>Some 40-Digit Primes</H1>
Each entry in the following list is the first prime number 
higher than a randomly selected 40-digit number.
<%@ taglib uri="cwp-taglib.tld" prefix="cwp" %>
<OL>
<!-- Repeats N times. A null reps value means repeat once. -->
<cwp:repeat reps='<%= request.getParameter("repeats") %>'>
  <LI><cwp:prime length="40" />
</cwp:repeat>
</OL>
</BODY>
</HTML>

An applet that reads arrays of strings packaged inside a QueryCollection and places them in a scrolling TextArea.

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

/** Applet reads arrays of strings packaged inside
 *  a QueryCollection and places them in a scrolling
 *  TextArea. The QueryCollection obtains the strings
 *  by means of a serialized object input stream
 *  connected to the QueryGenerator servlet.
 *  


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

public class ShowQueries extends Applet
                         implements ActionListener, Runnable {
  private TextArea queryArea;
  private Button startButton, stopButton, clearButton;
  private QueryCollection currentQueries;
  private QueryCollection nextQueries;
  private boolean isRunning = false;
  private String address =
    "/servlet/cwp.QueryGenerator";
  private URL currentPage;
  
  public void init() {
    setBackground(Color.white);
    setLayout(new BorderLayout());
    queryArea = new TextArea();
    queryArea.setFont(new Font("Serif", Font.PLAIN, 14));
    add(queryArea, BorderLayout.CENTER);
    Panel buttonPanel = new Panel();
    Font buttonFont = new Font("SansSerif", Font.BOLD, 16);
    startButton = new Button("Start");
    startButton.setFont(buttonFont);
    startButton.addActionListener(this);
    buttonPanel.add(startButton);
    stopButton = new Button("Stop");
    stopButton.setFont(buttonFont);
    stopButton.addActionListener(this);
    buttonPanel.add(stopButton);
    clearButton = new Button("Clear TextArea");
    clearButton.setFont(buttonFont);
    clearButton.addActionListener(this);
    buttonPanel.add(clearButton);
    add(buttonPanel, BorderLayout.SOUTH);
    currentPage = getCodeBase();
    // Request a set of sample queries. They
    // are loaded in a background thread, and
    // the applet checks to see if they have finished
    // loading before trying to extract the strings.
    currentQueries = new QueryCollection(address, currentPage);
    nextQueries = new QueryCollection(address, currentPage);
  }

  /** If you press the "Start" button, the system
   *  starts a background thread that displays
   *  the queries in the TextArea. Pressing "Stop"
   *  halts the process, and "Clear" empties the
   *  TextArea.
   */
 
  public void actionPerformed(ActionEvent event) {
    if (event.getSource() == startButton) {
      if (!isRunning) {
        Thread queryDisplayer = new Thread(this);
        isRunning = true;
        queryArea.setText("");
        queryDisplayer.start();
        showStatus("Started display thread...");
      } else {
        showStatus("Display thread already running...");
      }
    } else if (event.getSource() == stopButton) {
      isRunning = false;
      showStatus("Stopped display thread...");
    } else if (event.getSource() == clearButton) {
      queryArea.setText("");
    }
  }

  /** The background thread takes the currentQueries
   *  object and every half-second places one of the queries
   *  the object holds into the bottom of the TextArea. When
   *  all of the queries have been shown, the thread copies
   *  the value of the nextQueries object into
   *  currentQueries, sends a new request to the server
   *  in order to repopulate nextQueries, and repeats
   *  the process.
   */

  public void run() {
    while(isRunning) {
      showQueries(currentQueries);
      currentQueries = nextQueries;
      nextQueries = new QueryCollection(address, currentPage);
    }
  }

  private void showQueries(QueryCollection queryEntry) {
    // If request has been sent to server but the result
    // isn't back yet, poll every second. This should
    // happen rarely but is possible with a slow network
    // connection or an overloaded server.
    while(!queryEntry.isDone()) {
      showStatus("Waiting for data from server...");
      pause(1);
    }
    showStatus("Received data from server...");
    String[] queries = queryEntry.getQueries();
    String linefeed = "\n";
    // Put a string into TextArea every half-second.
    for(int i=0; i
                                

FilterTag.java Custom tag that modifies the tag body

FilterTag.java Custom tag that modifies the tag body

package cwp.tags;

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

/** A tag that replaces <, >, ", and & with their HTML
 *  character entities (<, >, ", and &).
 *  After filtering, arbitrary strings can be placed
 *  in either the page body or in HTML attributes.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class FilterTag extends BodyTagSupport {
  public int doAfterBody() {
    BodyContent body = getBodyContent();
    String filteredBody =
      ServletUtilities.filter(body.getString());
    try {
      JspWriter out = body.getEnclosingWriter();
      out.print(filteredBody);
    } catch(IOException ioe) {
      System.out.println("Error in FilterTag: " + ioe);
    }
    // SKIP_BODY means we're done. If we wanted to evaluate
    // and handle the body again, we'd return EVAL_BODY_TAG.
    return(SKIP_BODY);
  }
}

An applet that searches multiple search engines, displaying the results in side-by-side frame cells.

Using Applets as Front Ends to Server-Side Programs
**************************************************
SearchApplet.java An applet that searches multiple search engines,
 displaying the results in side-by-side frame cells. Uses the following files: 
SearchSpec.javaParallelSearches.htmlSearchAppletFrame.htmlGoogleResultsFrame.htmlInfoseekResultsFrame.htmlLycosResultsFrame.html
***************************************************
//
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
//

/** An applet that reads a value from a TextField,
 *  then uses it to build three distinct URLs with embedded
 *  GET data: one each for Google, Infoseek, and Lycos.
 *  The browser is directed to retrieve each of these
 *  URLs, displaying them in side-by-side frame cells.
 *  Note that standard HTML forms cannot automatically
 *  perform multiple submissions in this manner.
 *  


 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,

 *  May be freely used or adapted.
 */

public class SearchApplet extends Applet
                          implements ActionListener {
  private TextField queryField;
  private Button submitButton;

  public void init() {
    setBackground(Color.white);
    setFont(new Font("Serif", Font.BOLD, 18));
    add(new Label("Search String:"));
    queryField = new TextField(40);
    queryField.addActionListener(this);
    add(queryField);
    submitButton = new Button("Send to Search Engines");
    submitButton.addActionListener(this);
    add(submitButton);
  }

  /** Submit data when button is pressed or
   *  user presses Return in the TextField.
   */
  
  public void actionPerformed(ActionEvent event) {
    String query = URLEncoder.encode(queryField.getText());
    SearchSpec[] commonSpecs = SearchSpec.getCommonSpecs();
    // Omitting HotBot (last entry), as they use JavaScript to
    // pop result to top-level frame. Thus the length-1 below.
    for(int i=0; i
                                

RotationExample.java An example of translating and rotating the coordinate system prior to drawing

import java.awt.*;

/** An example of translating and rotating the coordinate
 *  system before each drawing.
 *
 *******************************

public class RotationExample extends StrokeThicknessExample {
  private Color[] colors = { Color.white, Color.black };

  public void paintComponent(Graphics g) {
    clear(g);
    Graphics2D g2d = (Graphics2D)g;
    drawGradientCircle(g2d);
    drawThickCircleOutline(g2d);
    // Move the origin to the center of the circle.
    g2d.translate(185.0, 185.0);
    for (int i=0; i<16; i++) {
      // Rotate the coordinate system around current
      // origin, which is at the center of the circle.
      g2d.rotate(Math.PI/8.0);
      g2d.setPaint(colors[i%2]);
      g2d.drawString("Java", 0, 0);
    }
  }

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

Demonstrates setting the pen width (in pixels) using a BasicStroke prior to drawing. Inherits from FontExample.java.

StrokeThicknessExample.java 
>>>>>>>>>>>>>>>>>>>>>>>>>>>
import java.awt.*;

/** An example of controlling the Stroke (pen) widths when
 *  drawing.
 *
 ******************
 */

public class StrokeThicknessExample extends FontExample {
  public void paintComponent(Graphics g) {
    clear(g);
    Graphics2D g2d = (Graphics2D)g;
    drawGradientCircle(g2d);
    drawBigString(g2d);
    drawThickCircleOutline(g2d);
  }

  protected void drawThickCircleOutline(Graphics2D g2d) {
    g2d.setPaint(Color.blue);
    g2d.setStroke(new BasicStroke(8)); // 8-pixel wide pen
    g2d.draw(getCircle());
  }

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

ListFonts.java Lists all local fonts available for graphical drawing.

ListFonts.java Lists all local fonts available for graphical drawing. 
***********************
import java.awt.*;

/** Lists the names of all available fonts. 
 *
 ******************

public class ListFonts {
  public static void main(String[] args) {
    GraphicsEnvironment env =
      GraphicsEnvironment.getLocalGraphicsEnvironment();
    String[] fontNames = env.getAvailableFontFamilyNames();
    System.out.println("Available Fonts:");
    for(int i=0; i>>>>>>>>>>>>>>>>>>>>>>>

Illustrates the effect of different transparency

~~~~~~~~~~~~~~~~~~~
TransparencyExample.java Illustrates the effect of different transparency (alpha) values when drawing a shape.
~~~~~~~~~~~~~~~~~~~
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

/** An illustration of the use of AlphaComposite to make
 *  partially transparent drawings.
 *
 **********************************

public class TransparencyExample extends JPanel {
  private static int gap=10, width=60, offset=20,
                     deltaX=gap+width+offset;
  private Rectangle
    blueSquare = new Rectangle(gap+offset, gap+offset, width,
                               width),
    redSquare = new Rectangle(gap, gap, width, width);

  private AlphaComposite makeComposite(float alpha) {
    int type = AlphaComposite.SRC_OVER;
    return(AlphaComposite.getInstance(type, alpha));
  }

  private void drawSquares(Graphics2D g2d, float alpha) {
    Composite originalComposite = g2d.getComposite();
    g2d.setPaint(Color.blue);
    g2d.fill(blueSquare);
    g2d.setComposite(makeComposite(alpha));
    g2d.setPaint(Color.red);
    g2d.fill(redSquare);
    g2d.setComposite(originalComposite);
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    for(int i=0; i<11; i++) {
      drawSquares(g2d, i*0.1F);
      g2d.translate(deltaX, 0);
    }
  }

  public static void main(String[] args) {
    String title = "Transparency example: alpha of the top " +
                   "(red) square ranges from 0.0 at the left " +
                   "to 1.0 at the right. Bottom (blue) square " + 
                   "is opaque.";
    WindowUtilities.openInJFrame(new TransparencyExample(),
                                 11*deltaX + 2*gap,
                                 deltaX + 3*gap,
                                 title, Color.lightGray);
  }
}
>>>>>>>>>>>>>>>>>>

Handling Events

***********************************    
* ActionExample1.java Inherits from CloseableFrame.java and uses SetSizeButton.java.
    * ActionExample2.java Inherits from CloseableFrame.java.
    **********************************************************
ActionExample1.java
*******************
import java.awt.*;

public class ActionExample1 extends CloseableFrame {
  public static void main(String[] args) {
    new ActionExample1();
  }

  public ActionExample1() {
    super("Handling Events in Component");
    setLayout(new FlowLayout());
    setFont(new Font("Serif", Font.BOLD, 18));
    add(new SetSizeButton(300, 200));
    add(new SetSizeButton(400, 300));
    add(new SetSizeButton(500, 400));
    setSize(400, 300);
    setVisible(true);
  }
}
********************
CloseableFrame.java 
********************
import java.awt.*;
import java.awt.event.*;

/** A Frame that you can actually quit. Used as the starting 
 *  point for most Java 1.1 graphical applications.
 ***********************

public class CloseableFrame extends Frame {
  public CloseableFrame(String title) {
    super(title);
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
  }

  /** Since we are doing something permanent, we need
   *  to call super.processWindowEvent first.
   */
  
  public void processWindowEvent(WindowEvent event) {
    super.processWindowEvent(event); // Handle listeners.
    if (event.getID() == WindowEvent.WINDOW_CLOSING) {
      // If the frame is used in an applet, use dispose().
      System.exit(0);
    }
  }
}
**********************
SetSizeButton.java
**********************
import java.awt.*;
import java.awt.event.*;

///////////////////////
public class SetSizeButton extends Button 
                           implements ActionListener {
  private int width, height;

  public SetSizeButton(int width, int height) {
    super("Resize to " + width + "x" + height);
    this.width = width;
    this.height = height;
    addActionListener(this);
  }

  public void actionPerformed(ActionEvent event) {
    getParent().setSize(width, height);
    getParent().invalidate();
    getParent().validate();
  }
}
***********************
ActionExample2.java
***********************
import java.awt.*;
import java.awt.event.*;

/***********/
public class ActionExample2 extends CloseableFrame
                            implements ActionListener {
  public static void main(String[] args) {
    new ActionExample2();
  }

  private Button button1, button2, button3;

  public ActionExample2() {
    super("Handling Events in Other Object");
    setLayout(new FlowLayout());
    setFont(new Font("Serif", Font.BOLD, 18));
    button1 = new Button("Resize to 300x200");
    button2 = new Button("Resize to 400x300");
    button3 = new Button("Resize to 500x400");
    button1.addActionListener(this);
    button2.addActionListener(this);
    button3.addActionListener(this);
    add(button1);
    add(button2);
    add(button3);
    setSize(400, 300);
    setVisible(true);
  }

  public void actionPerformed(ActionEvent event) {
    if (event.getSource() == button1) {
      updateLayout(300, 200);
    } else if (event.getSource() == button2) {
      updateLayout(400, 300);
    } else if (event.getSource() == button3) {
      updateLayout(500, 400);
    }
  }
  
  private void updateLayout(int width, int height) {
    setSize(width, height);
    invalidate();
    validate();
  }
}
****************/>
CloseableFrame.java.
****************/><
import java.awt.*;
import java.awt.event.*;

/** A Frame that you can actually quit. Used as the starting 
 *  point for most Java 1.1 graphical applications.
 *
 *********************

public class CloseableFrame extends Frame {
  public CloseableFrame(String title) {
    super(title);
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
  }

  /** Since we are doing something permanent, we need
   *  to call super.processWindowEvent first.
   */
  
  public void processWindowEvent(WindowEvent event) {
    super.processWindowEvent(event); // Handle listeners.
    if (event.getID() == WindowEvent.WINDOW_CLOSING) {
      // If the frame is used in an applet, use dispose().
      System.exit(0);
    }
  }
}
***************

A Frame that uses the Confirm dialog to verify quit

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

/** A Frame that uses the Confirm dialog to verify that
 *  users really want to quit.
 *
 
public class ConfirmTest extends Frame {
  public static void main(String[] args) {
    new ConfirmTest();
  }

  public ConfirmTest() {
    super("Confirming QUIT");
    setSize(200, 200);
    addWindowListener(new ConfirmListener());
    setVisible(true);
  }

  public ConfirmTest(String title) {
    super(title);
  }

  private class ConfirmListener extends WindowAdapter {
    public void windowClosing(WindowEvent event) {
      new Confirm(ConfirmTest.this);
    }
  }
}
****************
Confirm.java
****************
dialog box with two buttons: Yes and No
****************
import java.awt.*;
import java.awt.event.*;

/** A modal dialog box with two buttons: Yes and No.
 *  Clicking Yes exits Java. Clicking No exits the
 *  dialog. Used for confirmed quits from frames.
 ********************

class Confirm extends Dialog implements ActionListener {
  private Button yes, no;

  public Confirm(Frame parent) {
    super(parent, "Confirmation", true);
    setLayout(new FlowLayout());
    add(new Label("Really quit?"));
    yes = new Button("Yes");
    yes.addActionListener(this);
    no  = new Button("No");
    no.addActionListener(this);
    add(yes);
    add(no);
    pack();
    setVisible(true);
  }

  public void actionPerformed(ActionEvent event) {
    if (event.getSource() == yes) {
      System.exit(0);
    } else {
      dispose();
    }
  }
}
***************

CircleDrawer3.java Applet that uses a named nested class to handle mouse events and draw circles. Illustrates third approach to event-handling with listeners: using inner classes.

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

/** Draw circles centered where the user clicks.
 *  Uses named inner classes.
 *  


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

public class CircleDrawer3 extends Applet {
  public void init() {
    setForeground(Color.blue);
    addMouseListener(new CircleListener());
  }

  private class CircleListener extends MouseAdapter {
    private int radius = 25;

    public void mousePressed(MouseEvent event) {
      Graphics g = getGraphics();
      g.fillOval(event.getX()-radius,
                 event.getY()-radius,
                 2*radius,
                 2*radius);
    }
  }
}

Applet handle mouse events

ClickReporter.java A simple applet that uses the class to handle mouse events

import java.applet.Applet; import java.awt.*; 
/** Prints a message saying where the user clicks. 
* Uses an external listener. 
*

public class ClickReporter extends Applet { 
      public void init() { 
            setBackground(Color.yellow); 
            addMouseListener(new ClickListener()); 
      } 
}



	

Custom AWT Slider

*****************
Custom AWT Slider 

    * LabeledCostSlider.java. A numeric slider class with attached label.
    * CostSlider.java. A slider class that lets you read numeric values. Used in the LabeledCostSlider class.
    * Slider.java. A slider class: a combination of Scrollbar and TextField. Used in the CostSlider class.
    * ScrollbarPanel.java A Panel with adjustable top and bottom insets, used by the Slider class to change the thickness of the Slider.
*****************
LabeledCostSlider.java. A numeric slider class with attached label. 
>>>>>>>>>>>>>>>>>
import java.awt.*;

/** A CostSlider with a label centered above it. 
 *************
 

public class LabeledCostSlider extends Panel {
  public LabeledCostSlider(String labelString,
                           Font labelFont,
                           int minValue, int maxValue,
                           int initialValue,
                           Everest app) {
    setLayout(new BorderLayout());
    Label label = new Label(labelString, Label.CENTER);
    if (labelFont != null) {
      label.setFont(labelFont);
    }
    add(label, BorderLayout.NORTH);
    CostSlider slider = new CostSlider(minValue, 
                                       maxValue, 
                                       initialValue,
                                       app);
    add(slider, BorderLayout.CENTER);
  }
}  
<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>
CostSlider.java. A slider class that lets you read numeric values. Used in the LabeledCostSlider class. 
>>>>>>>>>>>>>>>>>>>
/** A Slider that takes an Everest applet as an argument,
 *  calling back to its setCostField when the slider value
 *  changes.
 *
 *******************

public class CostSlider extends Slider {
  private Everest app;

  public CostSlider(int minValue, int maxValue,
                    int initialValue, Everest app) {
    super(minValue, maxValue, initialValue);
    this.app = app;
  }

  public void doAction(int value) {
    app.setCostField(value);
  }
}
<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>
Slider.java. A slider class: a combination of Scrollbar and TextField. Used in the CostSlider class. 
>>>>>>>>>>>>>>>>>>>>>
import java.awt.*;
import java.awt.event.*;

/** A class that combines a horizontal Scrollbar and a TextField
 *  (to the right of the Scrollbar). The TextField shows the
 *  current scrollbar value, plus, if setEditable(true) is set,
 *  it can be used to change the value as well.
 *
 ********************

public class Slider extends Panel implements ActionListener,
                                             AdjustmentListener {
  private Scrollbar scrollbar;
  private TextField textfield;
  private ScrollbarPanel scrollbarPanel;
  private int preferredWidth = 250;

  /** Construct a slider with the specified min, max and initial
   *  values. The "bubble" (thumb) size is set to 1/10th the
   *  scrollbar range.
   */

  public Slider(int minValue, int maxValue, int initialValue) {
    this(minValue, maxValue, initialValue,
         (maxValue - minValue)/10);
  }

  /** Construct a slider with the specified min, max,and initial
   *  values, plus the specified "bubble" (thumb) value. This
   *  bubbleSize should be specified in the units that min and
   *  max use, not in pixels. Thus, if min is 20 and max is 320,
   *  then a bubbleSize of 30 is 10% of the visible range.
   */

  public Slider(int minValue, int maxValue, int initialValue,
                int bubbleSize) {
    setLayout(new BorderLayout());
    maxValue = maxValue + bubbleSize;
    scrollbar = new Scrollbar(Scrollbar.HORIZONTAL,
                              initialValue, bubbleSize,
                              minValue, maxValue);
    scrollbar.addAdjustmentListener(this);
    scrollbarPanel = new ScrollbarPanel(6);
    scrollbarPanel.add(scrollbar, BorderLayout.CENTER);
    add(scrollbarPanel, BorderLayout.CENTER);
    textfield = new TextField(numDigits(maxValue) + 1);
    textfield.addActionListener(this);
    setFontSize(12);
    textfield.setEditable(false);
    setTextFieldValue();
    add(textfield, BorderLayout.EAST);
  }

  /** A place holder to override for action to be taken when
   *  scrollbar changes.
   */

  public void doAction(int value) {
  }

  /** When textfield changes, sets the scrollbar */

  public void actionPerformed(ActionEvent event) {
    String value = textfield.getText();
    int oldValue = getValue();
    try {
      setValue(Integer.parseInt(value.trim()));
    } catch(NumberFormatException nfe) {
      setValue(oldValue);
    }
  }

  /** When scrollbar changes, sets the textfield */

  public void adjustmentValueChanged(AdjustmentEvent event) {
    setTextFieldValue();
    doAction(scrollbar.getValue());
  }

  /** Returns the Scrollbar part of the Slider. */

  public Scrollbar getScrollbar() {
    return(scrollbar);
  }

  /** Returns the TextField part of the Slider */

  public TextField getTextField() {
    return(textfield);
  }

  /** Changes the preferredSize to take a minimum width, since
   *  super-tiny scrollbars are hard to manipulate.
   */

  public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.height = textfield.getPreferredSize().height;
    d.width = Math.max(d.width, preferredWidth);
    return(d);
  }

  /** This just calls preferredSize */

  public Dimension getMinimumSize() {
    return(getPreferredSize());
  }

  /** To keep scrollbars legible, a minimum width is set. This
   *  returns the current value (default is 150).
   */

  public int getPreferredWidth() {
    return(preferredWidth);
  }

  /** To keep scrollbars legible, a minimum width is set. This
   *  sets the current value (default is 150).
   */

  public void setPreferredWidth(int preferredWidth) {
    this.preferredWidth = preferredWidth;
  }

  /** This returns the current scrollbar value */

  public int getValue() {
    return(scrollbar.getValue());
  }

  /** This assigns the scrollbar value. If it is below the
   *  minimum value or above the maximum, the value is set to
   *  the min and max value, respectively.
   */

  public void setValue(int value) {
    scrollbar.setValue(value);
    setTextFieldValue();
  }

  /** Sometimes horizontal scrollbars look odd if they are very
   *  tall. So empty top/bottom margins can be set. This returns
   *  the margin setting. The default is four.
   */

  public int getMargins() {
    return(scrollbarPanel.getMargins());
  }

  /** Sometimes horizontal scrollbars look odd if they are very
   *  tall. So empty top/bottom margins can be set. This sets
   *  the margin setting.
   */

  public void setMargins(int margins) {
    scrollbarPanel.setMargins(margins);
  }

  /** Returns the current textfield string. In most cases this
   *  is just the same as a String version of getValue, except
   *  that there may be padded blank spaces at the left.
   */

  public String getText() {
    return(textfield.getText());
  }

  /** This sets the TextField value directly. Use with extreme
   *  caution since it does not right-align or check if value
   *  is numeric.
   */

  public void setText(String text) {
    textfield.setText(text);
  }

  /** Returns the Font being used by the textfield.
   *  Courier bold 12 is the default.
   */

  public Font getFont() {
    return(textfield.getFont());
  }

  /** Changes the Font being used by the textfield. */

  public void setFont(Font textFieldFont) {
    textfield.setFont(textFieldFont);
  }

  /** The size of the current font */

  public int getFontSize() {
    return(getFont().getSize());
  }

  /** Rather than setting the whole font, you can just set the
   *  size (Monospaced bold will be used for the family/face).
   */

  public void setFontSize(int size) {
    setFont(new Font("Monospaced", Font.BOLD, size));
  }

  /** Determines if the textfield is editable. If it is, you can
   *  enter a number to change the scrollbar value. In such a
   *  case, entering a value outside the legal range results in
   *  the min or max legal value. A non-integer is ignored.
   */

  public boolean isEditable() {
    return(textfield.isEditable());
  }

  /** Determines if you can enter values directly into the
   *  textfield to change the scrollbar.
   */

  public void setEditable(boolean editable) {
    textfield.setEditable(editable);
  }

  // Sets a right-aligned textfield number.

  private void setTextFieldValue() {
    int value = scrollbar.getValue();
    int digits = numDigits(scrollbar.getMaximum());
    String valueString = padString(value, digits);
    textfield.setText(valueString);
  }

  // Repeated String concatenation is expensive, but this is
  // only used to add a small amount of padding, so converting
  // to a StringBuffer would not pay off.

  private String padString(int value, int digits) {
    String result = String.valueOf(value);
    for(int i=result.length(); i>>>>>>>>>>>>>>>>>>>
ScrollbarPanel.java A Panel with adjustable top and bottom insets, used by the Slider class to change the thickness of the Slider.
>>>>>>>>>>>>>>>>>>>
import java.awt.*;

/** A Panel with adjustable top/bottom insets value.
 *  Used to hold a Scrollbar in the Slider class.
 *
 *******************

public class ScrollbarPanel extends Panel {
  private Insets insets;

  public ScrollbarPanel(int margins) {
    setLayout(new BorderLayout());
    setMargins(margins);
  }

  public Insets insets() {
    return(insets);
  }

  public int getMargins() {
    return(insets.top);
  }

  public void setMargins(int margins) {
    this.insets = new Insets(margins, 0, margins, 0);
  }
}
<<<<<<<<<<<<<<<<<<<<<

Layout of a complicated GUI interface with GridLayout

##################################
GridBagTest.java Layout of a complicated GUI interface with GridLayout. Uses WindowUtilities.java and ExitListener.java. 
##################################
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;

/** An example demonstrating a GridBagLayout GUI with
 *  input text area and multiple buttons.
 *
 *********

public class GridBagTest extends JPanel {
  private JTextArea textArea;
  private JButton bSaveAs, bOk, bExit;
  private JTextField fileField;
  private GridBagConstraints c;

  public GridBagTest() {
    setLayout(new GridBagLayout());
    setBorder(BorderFactory.createEtchedBorder());

    textArea = new JTextArea(12,40);  // 12 rows, 40 cols
    bSaveAs = new JButton("Save As");
    fileField = new JTextField("C:\\Document.txt");
    bOk = new JButton("OK");
    bExit = new JButton("Exit");

    c = new GridBagConstraints();

    // Text Area.
    c.gridx      = 0;
    c.gridy      = 0;
    c.gridwidth  = GridBagConstraints.REMAINDER;
    c.gridheight = 1;
    c.weightx    = 1.0;
    c.weighty    = 1.0;
    c.fill       = GridBagConstraints.BOTH;
    c.insets     = new Insets(2,2,2,2); //t,l,b,r
    add(textArea,c);

    // Save As Button.
    c.gridx      = 0;
    c.gridy      = 1;
    c.gridwidth  = 1;
    c.gridheight = 1;
    c.weightx    = 0.0;
    c.weighty    = 0.0;
    c.fill       = GridBagConstraints.VERTICAL;
    add(bSaveAs,c);

    // Filename Input (Textfield).
    c.gridx      = 1;
    c.gridwidth  = GridBagConstraints.REMAINDER;
    c.gridheight = 1;
    c.weightx    = 1.0;
    c.weighty    = 0.0;
    c.fill       = GridBagConstraints.BOTH;
    add(fileField,c);

    // OK Button.
    c.gridx      = 2;
    c.gridy++;
    c.gridwidth  = 1;
    c.gridheight = 1;
    c.weightx    = 0.0;
    c.weighty    = 0.0;
    c.fill       = GridBagConstraints.NONE;
    add(bOk,c);

    // Exit Button.
    c.gridx      = 3;
    c.gridwidth  = 1;
    c.gridheight = 1;
    c.weightx    = 0.0;
    c.weighty    = 0.0;
    c.fill       = GridBagConstraints.NONE;
    add(bExit,c);

    // Filler so Column 1 has nonzero width.
    Component filler = Box.createRigidArea(new Dimension(1,1));
    c.gridx      = 1;
    c.weightx    = 1.0;
    add(filler,c);
  }

  public static void main(String[] args) {
    WindowUtilities.setNativeLookAndFeel();
    JFrame frame = new JFrame("GrigBagLayout Test");
    frame.setContentPane(new GridBagTest());
    frame.addWindowListener(new ExitListener());
    frame.pack();
    frame.setVisible(true);
  }
}

Lists.java

Lists.java Inherits from CloseableFrame.java. 
/./././././././././
import java.awt.*;

/*****************/

public class Lists extends CloseableFrame {
  public static void main(String[] args) {
    new Lists();
  }

  public Lists() {
    super("Lists");
    setLayout(new FlowLayout());
    setBackground(Color.lightGray);
    setFont(new Font("SansSerif", Font.BOLD, 18));
    List list1 = new List(3, false);
    list1.add("Vanilla");
    list1.add("Chocolate");
    list1.add("Strawberry");
    add(list1);
    List list2 = new List(3, true);
    list2.add("Colored Sprinkles");
    list2.add("Cashews");
    list2.add("Kiwi");
    add(list2);
    pack();
    setVisible(true);
  }
}

ChoiceTest

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

/*******/

public class ChoiceTest extends Applet {
  private Choice choice;

  public void init() {
    setFont(new Font("SansSerif", Font.BOLD, 36));
    choice = new Choice();
    choice.addItem("Choice 1");
    choice.addItem("Choice 2");
    choice.addItem("Choice 3");
    add(choice);
  }
}

ButtonExample.java Uses the following

/./././././././././
# ButtonExample.java Uses the following classes:

    * CloseableFrame.java
    * FgReporter.java
    * BgReporter.java
    * SizeReporter.java
******************
ButtonExample.java 
******************
import java.awt.*;
import java.awt.event.*;

/././././././././././

public class ButtonExample extends CloseableFrame {
  public static void main(String[] args) {
    new ButtonExample();
  }

  public ButtonExample() {
    super("Using ActionListeners");
    setLayout(new FlowLayout());
    Button b1 = new Button("Button 1");
    Button b2 = new Button("Button 2");
    Button b3 = new Button("Button 3");
    b1.setBackground(Color.lightGray);
    b2.setBackground(Color.gray);
    b3.setBackground(Color.darkGray);
    FgReporter fgReporter = new FgReporter();
    BgReporter bgReporter = new BgReporter();
    SizeReporter sizeReporter = new SizeReporter();
    b1.addActionListener(fgReporter);
    b2.addActionListener(fgReporter);
    b2.addActionListener(bgReporter);
    b3.addActionListener(fgReporter);
    b3.addActionListener(bgReporter);
    b3.addActionListener(sizeReporter);
    add(b1);
    add(b2);
    add(b3);
    setSize(350, 100);
    setVisible(true);
  }
}
/./././././././././
FgReporter.java
***************
import java.awt.event.*;
import java.awt.*;

/././././././././././

public class FgReporter implements ActionListener {
  public void actionPerformed(ActionEvent event) {
    Component c = (Component)event.getSource();
    System.out.println("Foreground: " + c.getForeground());
  }
}
****************
BgReporter.java
****************
/././././././././
import java.awt.event.*;
import java.awt.*;

/././././././././././././

public class BgReporter implements ActionListener {
  public void actionPerformed(ActionEvent event) {
    Component c = (Component)event.getSource();
    System.out.println("Background: " + c.getBackground());
  }
}
/././././././././././
SizeReporter.java
***********************

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

/././././././././

public class SizeReporter implements ActionListener {
  public void actionPerformed(ActionEvent event) {
    Component c = (Component)event.getSource();
    Dimension d = c.getSize();
    System.out.println("Size: " + d.width + "x" + d.height);
  }
}
********************

Uses a FileDialog to choose the file to display

DisplayFile.java 
****************
import java.awt.*;
import java.awt.event.*;
import java.io.*;

/** Uses a FileDialog to choose the file to display. 
 ***************
 
public class DisplayFile extends CloseableFrame 
                         implements ActionListener {
                                
  public static void main(String[] args) {
    new DisplayFile();
  }

  private Button loadButton;
  private TextArea fileArea;
  private FileDialog loader;

  public DisplayFile() {
    super("Using FileDialog");
    loadButton = new Button("Display File");
    loadButton.addActionListener(this);
    Panel buttonPanel = new Panel();
    buttonPanel.add(loadButton);
    add(buttonPanel, BorderLayout.SOUTH);
    fileArea = new TextArea();
    add("Center", fileArea);
    loader = new FileDialog(this, "Browse", FileDialog.LOAD);
    // Default file extension: .java.
    loader.setFile("*.java");
    setSize(350, 450);
    setVisible(true);
  }

  /** When the button is clicked, a file dialog is opened. When 
   * the file dialog is closed, load the file it referenced.
   */
  
  public void actionPerformed(ActionEvent event) {
      loader.show();
      displayFile(loader.getFile());
  }

  public void displayFile(String filename) {
    try {
      File file = new File(filename);
      FileInputStream in = new FileInputStream(file);
      int fileLength = (int)file.length();
      byte[] fileContents = new byte[fileLength];
      in.read(fileContents);
      String fileContentsString = new String(fileContents);
      fileArea.setText(fileContentsString);
    } catch(IOException ioe) {
      fileArea.setText("IOError: " + ioe);
    }
  }
}
*************
CloseableFrame.java. 
*************
import java.awt.*;
import java.awt.event.*;

/** A Frame that you can actually quit. Used as the starting 
 *  point for most Java 1.1 graphical applications.
 **********************

public class CloseableFrame extends Frame {
  public CloseableFrame(String title) {
    super(title);
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
  }

  /** Since we are doing something permanent, we need
   *  to call super.processWindowEvent first.
   */
  
  public void processWindowEvent(WindowEvent event) {
    super.processWindowEvent(event); // Handle listeners.
    if (event.getID() == WindowEvent.WINDOW_CLOSING) {
      // If the frame is used in an applet, use dispose().
      System.exit(0);
    }
  }
}

Applet that uses a anonymous nested class to handle mouse events and draw circles. Variation on third approach to event-handling: using inner classes.

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

/** Draw circles centered where the user clicks.
 *  Uses anonymous inner classes.
 *  


**********************
public class CircleDrawer4 extends Applet {
  public void init() {
    setForeground(Color.blue);
    addMouseListener
      (new MouseAdapter() {
         private int radius = 25;

         public void mousePressed(MouseEvent event) {
           Graphics g = getGraphics();
           g.fillOval(event.getX()-radius,
                      event.getY()-radius,
                      2*radius,
                      2*radius);
         }
      });
  }
}
*******************

Tiny applet that uses CircleListener to handle mouse events.

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

/** Draw circles centered where the user clicks.
 *  Uses an external listener.
 *  


 ***********
public class CircleDrawer1 extends Applet {
  public void init() {
    setForeground(Color.blue);
    addMouseListener(new CircleListener());
  }
}

Subclass of MouseAdapter

!!!!!!!!!!!!
ClickListener.java A simple subclass of MouseAdapter that reports where the mouse was pressed. When attached to an applet, look for the report in the Java Console.
!!!!!!!!!!!!
import java.awt.event.*;

/** The listener used by ClickReporter.
 *  


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

public class ClickListener extends MouseAdapter {
  public void mousePressed(MouseEvent event) {
    System.out.println("Mouse pressed at (" +
                       event.getX() + "," +
                       event.getY() + ").");
  }
}
<<<<<<<<<<<<<<

Create PopupMenu and add MenuItems

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
************************
/** Simple demo of pop-up menus. 
 *
 ********************

public class ColorPopupMenu extends Applet
                            implements ActionListener {
 private String[] colorNames =
   { "White", "Light Gray", "Gray", "Dark Gray", "Black" };
  private Color[] colors =
    { Color.white, Color.lightGray, Color.gray,
      Color.darkGray, Color.black };
  private PopupMenu menu;

  /** Create PopupMenu and add MenuItems. */
                              
  public void init() {
    setBackground(Color.gray);
    menu = new PopupMenu("Background Color");
    enableEvents(AWTEvent.MOUSE_EVENT_MASK);
    MenuItem colorName;
    for(int i=0; i

ReverseLabels.java Inherits from CloseableFrame.java and uses ReversibleLabel.java.

ReverseLabels.java Inherits from CloseableFrame.java and uses ReversibleLabel.java. 
**********************
ReverseLabels.java 
**********************
import java.awt.*;

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

public class ReverseLabels extends CloseableFrame {
  public static void main(String[] args) {
    new ReverseLabels();
  }

  public ReverseLabels() {
    super("Reversible Labels");
    setLayout(new FlowLayout());
    setBackground(Color.lightGray);
    setFont(new Font("Serif", Font.BOLD, 18));
    ReversibleLabel label1 =
      new ReversibleLabel("Black on White",
                          Color.white, Color.black);
    add(label1);
    ReversibleLabel label2 =
      new ReversibleLabel("White on Black",
                          Color.black, Color.white);
    add(label2);
    pack();
    setVisible(true);
  }
}
/./././././././././.
CloseableFrame.java 
&&&&&&&&&&&&&&&&&&&
import java.awt.*;
import java.awt.event.*;

/** A Frame that you can actually quit. Used as the starting 
 *  point for most Java 1.1 graphical applications.
 *
 *******************
 */

public class CloseableFrame extends Frame {
  public CloseableFrame(String title) {
    super(title);
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
  }

  /** Since we are doing something permanent, we need
   *  to call super.processWindowEvent first.
   */
  
  public void processWindowEvent(WindowEvent event) {
    super.processWindowEvent(event); // Handle listeners.
    if (event.getID() == WindowEvent.WINDOW_CLOSING) {
      // If the frame is used in an applet, use dispose().
      System.exit(0);
    }
  }
}
&&&&&&&&&&&&&&&&&&&&
ReversibleLabel.java. 
&&&&&&&&&&&&&&&&&&&&
import java.awt.*;
import java.awt.event.*;

/** A Label that reverses its background and
 *  foreground colors when the mouse is over it.
 *
 **********************
 
public class ReversibleLabel extends Label {
  public ReversibleLabel(String text,
                         Color bgColor, Color fgColor) {
    super(text);
    MouseAdapter reverser = new MouseAdapter() {
      public void mouseEntered(MouseEvent event) {
        reverseColors();
      }

      public void mouseExited(MouseEvent event) {
        reverseColors(); // or mouseEntered(event);
      }
    };
    addMouseListener(reverser);
    setText(text);
    setBackground(bgColor);
    setForeground(fgColor);
  }

  protected void reverseColors() {
    Color fg = getForeground();
    Color bg = getBackground();
    setForeground(bg);
    setBackground(fg);
  }
}
#############################

TextFields

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

/** A TextField from each of the four constructors.
 *
 *********************

public class TextFields extends Applet {
  public void init() {
    add(new TextField());
    add(new TextField(30));
    add(new TextField("Initial String"));
    add(new TextField("Initial", 30));
  }
}

ChoiceTest2

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

/***********************/

public class ChoiceTest2 extends Applet 
                         implements ItemListener {
  private Choice choice;

  public void init() {
    setFont(new Font("SansSerif", Font.BOLD, 36));
    choice = new Choice();
    choice.addItem("Choice 1");
    choice.addItem("Choice 2");
    choice.addItem("Choice 3");
    choice.addItemListener(this);
    add(choice);
  }

  public void itemStateChanged(ItemEvent event) {
    Choice choice = (Choice)event.getSource();
    String selection = choice.getSelectedItem();
    if (selection.equals("Choice 1")) {
      doChoice1Action();
    } else if (selection.equals("Choice 2")) {
      doChoice2Action();
    } else if (selection.equals("Choice 3")) {
      doChoice3Action();
    }
  }

  private void doChoice1Action() {
    System.out.println("Choice 1 Action");
  }

  private void doChoice2Action() {
    System.out.println("Choice 2 Action");
  }

  private void doChoice3Action() {
    System.out.println("Choice 3 Action");
  }
}

CheckboxGroups

CheckboxGroups.java
/./././././././././
/////////////////////
import java.applet.Applet;
import java.awt.*;

////////////////////
 
public class CheckboxGroups extends Applet {
  public void init() {
    setLayout(new GridLayout(4, 2));
    setBackground(Color.lightGray);
    setFont(new Font("Serif", Font.BOLD, 16));
    add(new Label("Flavor", Label.CENTER));
    add(new Label("Toppings", Label.CENTER));
    CheckboxGroup flavorGroup = new CheckboxGroup();
    add(new Checkbox("Vanilla", flavorGroup, true));
    add(new Checkbox("Colored Sprinkles"));
    add(new Checkbox("Chocolate", flavorGroup, false));
    add(new Checkbox("Cashews"));
    add(new Checkbox("Strawberry", flavorGroup, false));
    add(new Checkbox("Kiwi"));
  }
}

A textfield and three buttons arranged by a verticle BoxLayout

BoxLayoutTest.java A textfield and three buttons arranged by a verticle BoxLayout. Uses WindowUtilities.java and ExitListener.java. 
##################
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/** An example of BoxLayout.
 *
 ***********

public class BoxLayoutTest extends JPanel
                           implements ActionListener{
  BoxLayout layout;
  JButton topButton, middleButton, bottomButton;

  public BoxLayoutTest() {
    layout = new BoxLayout(this, BoxLayout.Y_AXIS);
    setLayout(layout);

    JLabel label = new JLabel("BoxLayout Demo");

    topButton = new JButton("Left Alignment");
    middleButton = new JButton("Center Alignment");
    bottomButton = new JButton("Right Alignment");
    topButton.addActionListener(this);
    middleButton.addActionListener(this);
    bottomButton.addActionListener(this);

    add(label);
    add(topButton);
    add(middleButton);
    add(bottomButton);
    setBackground(Color.white);
  }

  public void actionPerformed(ActionEvent event) {
    if (event.getSource() == topButton) {
      refresh(Component.LEFT_ALIGNMENT);
    } else if (event.getSource() == middleButton) {
      refresh(Component.CENTER_ALIGNMENT);
    } else if (event.getSource() == bottomButton) {
      refresh(Component.RIGHT_ALIGNMENT);
    }
  }

  private void refresh(float alignment){
    topButton.setAlignmentX(alignment);
    middleButton.setAlignmentX(alignment);
    bottomButton.setAlignmentX(alignment);
    revalidate();
    System.out.println("x: "+layout.getLayoutAlignmentX(this));
  }

  public static void main(String[] args) {
    WindowUtilities.setNativeLookAndFeel();
    WindowUtilities.openInJFrame(new BoxLayoutTest(), 300, 135,
                                 "BoxLayoutTest");
  }
}

Implementation of a simple browser in Swing (The user can specify a URL to load into the browser (JEditorPane))

Browser.java Implementation of a simple browser in Swing. The user can specify a URL to load into the browser (JEditorPane). By attaching an Hyperlink Listener, the editor pane is responsive to hyperlinks selected by the user. Uses the following class and image:

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

/** Very simplistic "Web browser" using Swing. Supply a URL on
 *  the command line to see it initially and to set the
 *  destination of the "home" button.
 *
  */

public class Browser extends JFrame implements HyperlinkListener, 
                                               ActionListener {
  public static void main(String[] args) {
    if (args.length == 0)
      new Browser("http://www.corewebprogramming.com/");
    else
      new Browser(args[0]);
  }

  private JIconButton homeButton;
  private JTextField urlField;
  private JEditorPane htmlPane;
  private String initialURL;

  public Browser(String initialURL) {
    super("Simple Swing Browser");
    this.initialURL = initialURL;
    addWindowListener(new ExitListener());
    WindowUtilities.setNativeLookAndFeel();

    JPanel topPanel = new JPanel();
    topPanel.setBackground(Color.lightGray);
    homeButton = new JIconButton("home.gif");
    homeButton.addActionListener(this);
    JLabel urlLabel = new JLabel("URL:");
    urlField = new JTextField(30);
    urlField.setText(initialURL);
    urlField.addActionListener(this);
    topPanel.add(homeButton);
    topPanel.add(urlLabel);
    topPanel.add(urlField);
    getContentPane().add(topPanel, BorderLayout.NORTH);

    try {
        htmlPane = new JEditorPane(initialURL);
        htmlPane.setEditable(false);
        htmlPane.addHyperlinkListener(this);
        JScrollPane scrollPane = new JScrollPane(htmlPane);
        getContentPane().add(scrollPane, BorderLayout.CENTER);
    } catch(IOException ioe) {
       warnUser("Can't build HTML pane for " + initialURL 
                + ": " + ioe);
    }

    Dimension screenSize = getToolkit().getScreenSize();
    int width = screenSize.width * 8 / 10;
    int height = screenSize.height * 8 / 10;
    setBounds(width/8, height/8, width, height);
    setVisible(true);
  }

  public void actionPerformed(ActionEvent event) {
    String url;
    if (event.getSource() == urlField) {
      url = urlField.getText();
    } else { // Clicked "home" button instead of entering URL.
      url = initialURL;
    }
    try {
      htmlPane.setPage(new URL(url));
      urlField.setText(url);
    } catch(IOException ioe) {
      warnUser("Can't follow link to " + url + ": " + ioe);
    }
  }

  public void hyperlinkUpdate(HyperlinkEvent event) {
    if (event.getEventType() == 
        HyperlinkEvent.EventType.ACTIVATED) {
      try {
        htmlPane.setPage(event.getURL());
        urlField.setText(event.getURL().toExternalForm());
      } catch(IOException ioe) {
        warnUser("Can't follow link to " 
                + event.getURL().toExternalForm() + ": " + ioe);
      }
    }
  }

  private void warnUser(String message) {
    JOptionPane.showMessageDialog(this, message, "Error", 
                                  JOptionPane.ERROR_MESSAGE);
  }
}

A simple applet (JApplet) created in Swing.

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

/** Tiny example showing the main differences in using 
 *  JApplet instead of Applet: using the content pane,
 *  getting Java (Metal) look and feel by default, and
 *  having BorderLayout be the default instead of FlowLayout.
 *
  */
 
public class JAppletExample extends JApplet {
  public void init() {
    WindowUtilities.setNativeLookAndFeel();
    Container content = getContentPane();
    content.setBackground(Color.white);
    content.setLayout(new FlowLayout()); 
    content.add(new JButton("Button 1"));
    content.add(new JButton("Button 2"));
    content.add(new JButton("Button 3"));
  }
}

Illustrates the insertion of menu entries in Frame menu bars.

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

/** Illustrates the insertion of menu entries in Frame
 *  menu bars.
 *
 
public class ColorMenu extends CloseableFrame 
                       implements ActionListener {
                        
  private String[] colorNames =
    { "Black", "White", "Light Gray", "Medium Gray", 
      "Dark Gray" };
  private Color[] colorValues =
    { Color.black, Color.white, Color.lightGray, 
      Color.gray, Color.darkGray };
   
  public ColorMenu() {
    super("ColorMenu");
    MenuBar bar = new MenuBar();
    Menu colorMenu = new Menu("Colors");
    for(int i=0; i<2; i++) {
      colorMenu.add(colorNames[i]);
    }
    Menu grayMenu = new Menu("Gray");
    for(int i=2; i

JTable Examples

# JTableSimpleExample.java Simple table that takes column names and data from arrays of Strings.

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

/** Simple JTable example that uses a String array for the
 *  table header and table data.
 *
 */

public class JTableSimpleExample extends JFrame {
  public static void main(String[] args) {
    new JTableSimpleExample();
  }

  private final int COLUMNS = 4;
  private final int ROWS = 15;
  private JTable sampleJTable;

  public JTableSimpleExample() {
    super("Creating a Simple JTable");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();

    String[]   columnNames = buildColumnNames(COLUMNS);
    String[][] tableCells = buildTableCells(ROWS, COLUMNS);

    sampleJTable = new JTable(tableCells, columnNames);
    JScrollPane tablePane = new JScrollPane(sampleJTable);
    content.add(tablePane, BorderLayout.CENTER);
    setSize(450,150);
    setVisible(true);
  }

  private String[] buildColumnNames(int columns) {
    String[] header = new String[columns];
    for(int i=0; i

Eight buttons: four each in two panels

mport java.applet.Applet; import java.awt.*; 
*************************** 
/** Eight buttons: four each in two panels. * */ 
public class ButtonTest2 extends Applet { 
      public void init() { 
            String[] labelPrefixes = { 
            "Start", "Stop", "Pause", "Resume" 
            }; 
      Panel p1 = new Panel(); for (int i=0; i<4; i++) { 
            p1.add(new Button(labelPrefixes[i] + " Thread1")); 
      } 
      Panel p2 = new Panel(); for (int i=0; i<4; i++) { 
      p2.add(new Button(labelPrefixes[i] + " Thread2")); 
      } add(p1); add(p2); 
      } 
} 
**************************

JList Examples

All examples, except for FileTransfer use WindowUtilities.java and ExitListener.java.
WindowUtilities.java: 
import javax.swing.*;
import java.awt.*;   // For Color and Container classes.

/** A few utilities that simplify using windows in Swing. 
 *
  */

public class WindowUtilities {

  /** Tell system to use native look and feel, as in previous
   *  releases. Metal (Java) LAF is the default otherwise.
   */

  public static void setNativeLookAndFeel() {
    try {
     UIManager.setLookAndFeel(
       UIManager.getSystemLookAndFeelClassName());
    } catch(Exception e) {
      System.out.println("Error setting native LAF: " + e);
    }
  }

  public static void setJavaLookAndFeel() {
    try {
     UIManager.setLookAndFeel(
       UIManager.getCrossPlatformLookAndFeelClassName());
    } catch(Exception e) {
      System.out.println("Error setting Java LAF: " + e);
    }
  }

   public static void setMotifLookAndFeel() {
    try {
      UIManager.setLookAndFeel(
        "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
    } catch(Exception e) {
      System.out.println("Error setting Motif LAF: " + e);
    }
  }

  /** A simplified way to see a JPanel or other Container. Pops
   *  up a JFrame with specified Container as the content pane.
   */

  public static JFrame openInJFrame(Container content,
                                    int width,
                                    int height,
                                    String title,
                                    Color bgColor) {
    JFrame frame = new JFrame(title);
    frame.setBackground(bgColor);
    content.setBackground(bgColor);
    frame.setSize(width, height);
    frame.setContentPane(content);
    frame.addWindowListener(new ExitListener());
    frame.setVisible(true);
    return(frame);
  }

  /** Uses Color.white as the background color. */

  public static JFrame openInJFrame(Container content,
                                    int width,
                                    int height,
                                    String title) {
    return(openInJFrame(content, width, height,
                        title, Color.white));
  }

  /** Uses Color.white as the background color, and the
   *  name of the Container's class as the JFrame title.
   */

  public static JFrame openInJFrame(Container content,
                                    int width,
                                    int height) {
    return(openInJFrame(content, width, height,
                        content.getClass().getName(),
                        Color.white));
  }
}
**//
ExitListener.java.:
import java.awt.*;
import java.awt.event.*;

/** A listener that you attach to the top-level JFrame of
 *  your application, so that quitting the frame exits the 
 *  application.
 *
  */
public class ExitListener extends WindowAdapter {
  public void windowClosing(WindowEvent event) {
    System.exit(0);
  }
}
**//

JList Examples

* JListSimpleExample.java Illustrates creating a simple list. In this example, all the entries for the list are stored in a String array and later supplied in the JList constructor. In addition, a private class, ValueReporter, implements a ListSelectionListener to display the last entry in the list selected by the user.

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;

/** Simple JList example illustrating
 *  


     *    
    Creating a JList, which we do by passing values 
     *        directly to the JList constructor, rather than 
     *        using a ListModel, and
     *    
    Attaching a listener to determine when values change.
     *  


 */

public class JListSimpleExample extends JFrame {
  public static void main(String[] args) {
    new JListSimpleExample();
  }

  private JList sampleJList;
  private JTextField valueField;
  
  public JListSimpleExample() {
    super("Creating a Simple JList");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();

    // Create the JList, set the number of visible rows, add a
    // listener, and put it in a JScrollPane.
    String[] entries = { "Entry 1", "Entry 2", "Entry 3",
                         "Entry 4", "Entry 5", "Entry 6" };
    sampleJList = new JList(entries);
    sampleJList.setVisibleRowCount(4);
    sampleJList.addListSelectionListener(new ValueReporter());
    JScrollPane listPane = new JScrollPane(sampleJList);
    Font displayFont = new Font("Serif", Font.BOLD, 18);
    sampleJList.setFont(displayFont);

    JPanel listPanel = new JPanel();
    listPanel.setBackground(Color.white);
    Border listPanelBorder =
      BorderFactory.createTitledBorder("Sample JList");
    listPanel.setBorder(listPanelBorder);
    listPanel.add(listPane);
    content.add(listPanel, BorderLayout.CENTER);
    JLabel valueLabel = new JLabel("Last Selection:");
    valueLabel.setFont(displayFont);
    valueField = new JTextField("None", 7);
    valueField.setFont(displayFont);
    valueField.setEditable(false);
    JPanel valuePanel = new JPanel();
    valuePanel.setBackground(Color.white);
    Border valuePanelBorder =
      BorderFactory.createTitledBorder("JList Selection");
    valuePanel.setBorder(valuePanelBorder);
    valuePanel.add(valueLabel);
    valuePanel.add(valueField);
    content.add(valuePanel, BorderLayout.SOUTH);
    pack();
    setVisible(true);
  }

  private class ValueReporter implements ListSelectionListener {

    /** You get three events in many cases -- one for the 
     *  deselection of the originally selected entry, one 
     *  indicating the selection is moving, and one for the 
     *  selection of the new entry. In the first two cases, 
     *  getValueIsAdjusting returns true; thus, the test below
     *  when only the third case is of interest.
     */

    public void valueChanged(ListSelectionEvent event) {
      if (!event.getValueIsAdjusting()) {
        Object value = sampleJList.getSelectedValue();
        if (value != null) {
          valueField.setText(value.toString());
        }  
      }
    }
  }
}
**//

DefaultListModelExample.java Creates a list using a DefaultListModel. By default, a JList doesn't permit you to directly add new entries; however, with the DefaultListModel you can add or delete entries to the model (which are reflected in the list).

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

/** JList example illustrating
 *  


     *    
    The creation of a JList by creating a DefaultListModel,
     *        adding the values there, then passing that to the
     *        JList constructor.
     *    
    Adding new values at runtime, the key thing that 
     *        DefaultListModel lets you do that you can't do with
     *        a JList where you supply values directly.
     *  


 *
 */

public class DefaultListModelExample extends JFrame {
  public static void main(String[] args) {
    new DefaultListModelExample();
  }

  JList sampleJList;
  private DefaultListModel sampleModel;
  
  public DefaultListModelExample() {
    super("Creating a Simple JList");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
   
    String[] entries = { "Entry 1", "Entry 2", "Entry 3",
                         "Entry 4", "Entry 5", "Entry 6" };
    sampleModel = new DefaultListModel();
    for(int i=0; ibefore trying to scroll
     *  to make the index visible.
     */

    public void actionPerformed(ActionEvent event) {
      int index = sampleModel.getSize();
      sampleModel.addElement("Entry " + (index+1));
      ((JComponent)getContentPane()).revalidate();
      sampleJList.setSelectedIndex(index);
      sampleJList.ensureIndexIsVisible(index);
    }
  }
}
**//

# JListCustomModel.java  Example illustrating that you can use your own custom data model (data structure) to hold the entries in a list. Uses the following classes:

* JavaLocationListModel.java A custom list model (implements ListModel interface which provides support for custom data structures) to store data for the list.
* JavaLocationCollection.java A simple collection of JavaLocation (below) objects.
* JavaLocation.java An object representing a city named Java. Defines the country where the Java city is located, along with a comment and country flag (gif image).

JListCustomModel.java:
import java.awt.*;
import javax.swing.*;

/** Simple JList example illustrating the use of a custom
 *  ListModel (JavaLocationListModel).
 *
  */

public class JListCustomModel extends JFrame {
  public static void main(String[] args) {
    new JListCustomModel();
  }

  public JListCustomModel() {
    super("JList with a Custom Data Model");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();

    JavaLocationCollection collection =
      new JavaLocationCollection();
    JavaLocationListModel listModel =
      new JavaLocationListModel(collection);
    JList sampleJList = new JList(listModel);
    Font displayFont = new Font("Serif", Font.BOLD, 18);
    sampleJList.setFont(displayFont);
    content.add(sampleJList);

    pack();
    setVisible(true);
  }
}
**//
# JavaLocationListModel.java:

import javax.swing.*;
import javax.swing.event.*;

/** A simple illustration of writing your own ListModel.
 *  Note that if you wanted the user to be able to add and
 *  remove data elements at runtime, you should start with
 *  AbstractListModel and handle the event reporting part.
 *
 */

public class JavaLocationListModel implements ListModel {
  private JavaLocationCollection collection;
  
  public JavaLocationListModel(JavaLocationCollection collection) {
    this.collection = collection;
  }

  public Object getElementAt(int index) {
    return(collection.getLocations()[index]);
  }

  public int getSize() {
    return(collection.getLocations().length);
  }

  public void addListDataListener(ListDataListener l) {}

  public void removeListDataListener(ListDataListener l) {}
}

**//

JavaLocationCollection.java:
/** A simple collection that stores multiple JavaLocation
 *  objects in an array and determines the number of
 *  unique countries represented in the data.
 *
 */

public class JavaLocationCollection {
  private static JavaLocation[] defaultLocations =
    { new JavaLocation("Belgium",
                       "near Liege",
                       "flags/belgium.gif"),
      new JavaLocation("Brazil",
                       "near Salvador",
                       "flags/brazil.gif"),
      new JavaLocation("Colombia",
                       "near Bogota",
                       "flags/colombia.gif"),
      new JavaLocation("Indonesia",
                       "main island",
                       "flags/indonesia.gif"),
      new JavaLocation("Jamaica",
                       "near Spanish Town",
                       "flags/jamaica.gif"),
      new JavaLocation("Mozambique",
                       "near Sofala",
                       "flags/mozambique.gif"),
      new JavaLocation("Philippines",
                       "near Quezon City",
                       "flags/philippines.gif"),
      new JavaLocation("Sao Tome",
                       "near Santa Cruz",
                       "flags/saotome.gif"),
      new JavaLocation("Spain",
                       "near Viana de Bolo",
                       "flags/spain.gif"),
      new JavaLocation("Suriname",
                       "near Paramibo",
                       "flags/suriname.gif"),
      new JavaLocation("United States",
                       "near Montgomery, Alabama",
                       "flags/usa.gif"),
      new JavaLocation("United States",
                       "near Needles, California",
                       "flags/usa.gif"),
      new JavaLocation("United States",
                       "near Dallas, Texas",
                       "flags/usa.gif")
    };

  private JavaLocation[] locations;
  private int numCountries;

  public JavaLocationCollection(JavaLocation[] locations) {
    this.locations = locations;
    this.numCountries = countCountries(locations);
  }
  
  public JavaLocationCollection() {
    this(defaultLocations);
  }

  public JavaLocation[] getLocations() {
    return(locations);
  }

  public int getNumCountries() {
    return(numCountries);
  }

  // Count the number of unique countries in the data.
  // Assumes the list is sorted by country name
  private int countCountries(JavaLocation[] locations) {
    int n = 0;
    String currentCountry, previousCountry = "None";
    for(int i=0;i
 *  Note that this method can get called lots and lots of times
 *  as you click on entries. We don't want to keep generating 
 *  new ImageIcon objects, so we make a Hashtable that associates 
 *  previously displayed values with icons, reusing icons for 
 *  entries that have been displayed already.
 *  


 *  Note that in the first release of JDK 1.2, the default 
 *  renderer  has a bug: the renderer doesn't clear out icons for 
 *  later entries. So if you mix plain strings and ImageIcons in 
 *  your JList, the plain strings still get an icon. The 
 *  call below clears the old icon when the value is not a 
 *  JavaLocation.
 *
 
 */

public class JavaLocationRenderer extends 
                                  DefaultListCellRenderer {
  private Hashtable iconTable = new Hashtable();
  
  public Component getListCellRendererComponent(JList list,
                                                Object value,
                                                int index,
                                                boolean isSelected,
                                                boolean hasFocus) {
    // First build the label containing the text, then 
    // later add the image.
    JLabel label =
      (JLabel)super.getListCellRendererComponent(list,
                                                 value,
                                                 index,
                                                 isSelected,
                                                 hasFocus);
    if (value instanceof JavaLocation) {
      JavaLocation location = (JavaLocation)value;
      ImageIcon icon = (ImageIcon)iconTable.get(value);
      if (icon == null) {
        icon = new ImageIcon(location.getFlagFile());
        iconTable.put(value, icon);
      }
      label.setIcon(icon);
    } else {
      // Clear old icon; needed in 1st release of JDK 1.2.
      label.setIcon(null); 
    }
    return(label);
  }
}
**//
# JavaLocationListModel.java A custom list model (implements ListModel interface) to store data for a list.
# JavaLocationCollection.java A simple collection of JavaLocation (below) objects.
# JavaLocation.java An object representing a city named Java. Defines the country where the Java 
city is located, along with a comment and country flag

Position circles down the diagonal so that their borders

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

/** Position circles down the diagonal so that their borders
 *  just touch. Illustrates that AWT components are 
 *  rectangular and opaque.
  */

public class CircleTest2 extends Applet {
  public void init() {
    setBackground(Color.lightGray);
    setLayout(null); // Turn off layout manager.
    Circle circle;
    int radius = getSize().width/6;
    int deltaX = round(2.0 * (double)radius / Math.sqrt(2.0));
    for (int x=radius; x<6*radius; x=x+deltaX) {
      circle = new Circle(Color.black, radius);
      add(circle);
      circle.setCenter(x, x);
    }
  }

  private int round(double num) {
    return((int)Math.round(num));
  }
}
*********************************
Circle.java
*********************************
import java.awt.*;

/** A Circle component built using a Canvas. 
 *
  */

public class Circle extends Canvas {
  private int width, height;        
        
  public Circle(Color foreground, int radius) {
    setForeground(foreground);
    width = 2*radius;
    height = 2*radius;
    setSize(width, height);
  }

  public void paint(Graphics g) {
    g.fillOval(0, 0, width, height);
  }

  public void setCenter(int x, int y) {
    setLocation(x - width/2, y - height/2);
  }
}
*****************************

Insert three circles into an Applet using FlowLayout

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

/** Insert three circles into an Applet using FlowLayout. 
 *
 */

public class CircleTest extends Applet {
  public void init() {
    setBackground(Color.lightGray);
    add(new Circle(Color.white, 30));
    add(new Circle(Color.gray, 40));
    add(new Circle(Color.black, 50));
  }
}

Accesses methods in a Ship2 object

*********************************************
Test2.java Accesses methods in a Ship2 object
*********************************************

// Give the ship public move and printLocation methods.

class Ship2 {
  public double x=0.0, y=0.0, speed=1.0, direction=0.0;
  public String name = "UnnamedShip";

  private double degreesToRadians(double degrees) {
    return(degrees * Math.PI / 180.0);
  }

  public void move() {
    double angle = degreesToRadians(direction);
    x = x + speed * Math.cos(angle);
    y = y + speed * Math.sin(angle);
  }

  public void printLocation() {
    System.out.println(name + " is at " +
                       "(" + x + "," + y + ").");
  }
}

public class Test2 {
  public static void main(String[] args) {
    Ship2 s1 = new Ship2();
    s1.name = "Ship1";
    Ship2 s2 = new Ship2();
    s2.direction = 135.0; // Northwest
    s2.speed = 2.0;
    s2.name = "Ship2";
    s1.move();
    s2.move();
    s1.printLocation();
    s2.printLocation();
  }
}
**********************

Placement of buttons in a BoxLayout using rigid areas, struts, and glue

###############
InvisibleComponentTest.java Placement of buttons in a BoxLayout using rigid areas, struts, and glue
###############
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

/** Example of using rigid areas, struts, and glue to
 *  produce the effect of invisible components.
 *
 ******************

public class InvisibleComponentTest extends JPanel {
  Component spacer;

  public InvisibleComponentTest() {
    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

    // Place a rigid invisible component 25 pixels wide and
    // 75 pixels tall between the two buttons
    JPanel p1= new JPanel();
    spacer = Box.createRigidArea(new Dimension(20,75));
    setUpPanel(p1, "Rigid Area - 20x75 pixels", spacer);

    // Separate two buttons by a 60-pixel horizontal strut
    JPanel p2= new JPanel();
    spacer = Box.createHorizontalStrut(60);
    setUpPanel(p2, "Horizontal Strut - 60 pixels", spacer);

    // Horizontal glue in FlowLayout - not useful
    JPanel p3= new JPanel();
    spacer = Box.createHorizontalGlue();
    setUpPanel(p3, "Horizontal Glue - FlowLayout", spacer);

    // Add glue to fill all remaining horizontal space between
    // the two buttons. Glue not supported by default FlowLayout
    // of JPanel.  Change layout of JPanel to BoxLayout.
    JPanel p4= new JPanel();
    p4.setLayout(new BoxLayout(p4,BoxLayout.X_AXIS));
    spacer = Box.createHorizontalGlue();
    setUpPanel(p4, "Horizontal Glue - BoxLayout", spacer);

    add(p1);
    add(p2);
    add(p3);
    add(p4);
  }

  // Helper to set the border and add components
  private void setUpPanel(JPanel p, String title,
                          Component spacer) {
    p.setBorder(BorderFactory.createTitledBorder(
                       BorderFactory.createEtchedBorder(),title,
                       TitledBorder.TOP,TitledBorder.CENTER));
    p.setBackground(Color.white);
    p.add(new JButton("Left"));
    p.add(spacer);
    p.add(new JButton("Right"));
  }

  public static void main(String[] args) {
    String title = "Using Invisible Components";
    WindowUtilities.setNativeLookAndFeel();
    WindowUtilities.openInJFrame(new InvisibleComponentTest(),
                                 350, 325, title);
  }
}

Adds typing to the freehand drawing.

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

/** A better whiteboard that lets you enter
 *  text in addition to freehand drawing.
 *  


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

public class Whiteboard extends SimpleWhiteboard {
  protected FontMetrics fm;

  public void init() {
    super.init();
    Font font = new Font("Serif", Font.BOLD, 20);
    setFont(font);
    fm = getFontMetrics(font);
    addKeyListener(new CharDrawer());
  }

  private class CharDrawer extends KeyAdapter {
    // When user types a printable character,
    // draw it and shift position rightwards.
    
    public void keyTyped(KeyEvent event) {
      String s = String.valueOf(event.getKeyChar());
      getGraphics().drawString(s, lastX, lastY);
      record(lastX + fm.stringWidth(s), lastY);
    }
  }
}

java Nested container where the top-level panels are positioned by hand

######################
ButtonCol.java Nested container where the top-level panels are positioned by hand
######################
import java.applet.Applet;
import java.awt.*;

/** An example of a layout performed manually. The top-level
 *  panels are positioned by hand, after you determine the size
 *  of the applet. Since applets can't be resized in most
 *  browsers, setting the size once when the applet is created
 *  is sufficient.
 *
 ***************************

public class ButtonCol extends Applet {
  public void init() {
    setLayout(null);
    int width1 = getSize().width*4/10,
        width2 = getSize().width - width1,
        height = getSize().height;
    Panel buttonPanel = new Panel();
    buttonPanel.setBounds(0, 0, width1, height);
    buttonPanel.setLayout(new GridLayout(6, 1));
    buttonPanel.add(new Label("Buttons", Label.CENTER));
    buttonPanel.add(new Button("Button One"));
    buttonPanel.add(new Button("Button Two"));
    buttonPanel.add(new Button("Button Three"));
    buttonPanel.add(new Button("Button Four"));
    buttonPanel.add(new Button("Button Five"));
    add(buttonPanel);
    Panel everythingElse = new Panel();
    everythingElse.setBounds(width1+1, 0, width2, height);
    everythingElse.add(new Label("Everything Else"));
    add(everythingElse);
  }
}

Layout of complicated GUI by taking advantage of nested containers

#################
NestedLayout.java Layout of complicated GUI by taking advantage of nested containers. Uses WindowUtilities.java and ExitListener.java. 
##################
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;

/** An example demonstrating the use of nested containers
 *  to lay out the components. See GridBagTest.java for
 *  implementation by a single layout manager, GridBagLayout.
 *
 *******************
 */

public class NestedLayout extends JPanel {

  private JTextArea textArea;
  private JButton bSaveAs, bOk, bExit;
  private JTextField fileField;

  public NestedLayout() {

    setLayout(new BorderLayout(2,2));
    setBorder(BorderFactory.createEtchedBorder());

    textArea = new JTextArea(12,40);  // 12 rows, 40 cols
    bSaveAs = new JButton("Save As");
    fileField = new JTextField("C:\\Document.txt");
    bOk = new JButton("OK");
    bExit = new JButton("Exit");

    add(textArea,BorderLayout.CENTER);

    // Set up buttons and textfield in bottom panel.
    JPanel bottomPanel = new JPanel();
    bottomPanel.setLayout(new GridLayout(2,1));

    JPanel subPanel1 = new JPanel();
    JPanel subPanel2 = new JPanel();
    subPanel1.setLayout(new BorderLayout());
    subPanel2.setLayout(new FlowLayout(FlowLayout.RIGHT,2,2));

    subPanel1.add(bSaveAs,BorderLayout.WEST);
    subPanel1.add(fileField,BorderLayout.CENTER);
    subPanel2.add(bOk);
    subPanel2.add(bExit);

    bottomPanel.add(subPanel1);
    bottomPanel.add(subPanel2);

    add(bottomPanel,BorderLayout.SOUTH);
  }

  public static void main(String[] args) {
    WindowUtilities.setNativeLookAndFeel();
    JFrame frame = new JFrame("Nested Containers");
    frame.setContentPane(new NestedLayout());
    frame.addWindowListener(new ExitListener());
    frame.pack();
    frame.setVisible(true);
  }
}
##########################

A demo providing multiple buttons to select a playing card-A Panel, using CardLayout control which of four possible subpanels, holding a different card, to display

#######################
# CardDemo.java A demo providing multiple buttons to select a playing card. A Panel, using CardLayout control which of four possible subpanels, holding a different card, to display.Uses the following class and images:
    * CardPanel.java A Panel that displays a playing card.
    * ImageLabel.java A Canvas for displaying images.
    * Ace.gif, King.gif, Queen.gif, Jack.gif.
#####################
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

/** An example of CardLayout. The right side of the window holds
 *  a Panel that uses CardLayout to control four possible
 *  subpanels (each of which is a CardPanel that shows a
 *  picture of a playing card). The buttons on the left side
 *  of the window manipulate the "cards" in this layout by
 *  calling methods in the right-hand panel's layout manager.
 *
 *********************************

public class CardDemo extends Applet implements ActionListener {
  private Button first, last, previous, next;
  private String[] cardLabels = { "Jack","Queen","King","Ace" };
  private CardPanel[] cardPanels = new CardPanel[4];
  private CardLayout layout;
  private Panel cardDisplayPanel;

  public void init() {
    setBackground(Color.white);
    setLayout(new BorderLayout());
    addButtonPanel();
    addCardDisplayPanel();
  }

  private void addButtonPanel() {
    Panel buttonPanel = new Panel();
    buttonPanel.setLayout(new GridLayout(9, 1));
    Font buttonFont = new Font("SansSerif", Font.BOLD, 18);
    buttonPanel.setFont(buttonFont);
    for(int i=0; inot use CardLayout. Rather, instances of CardPanel
 *  are contained in another window used in the CardDemo
 *  example. It is this enclosing window that uses CardLayout
 *  to manipulate which CardPanel it shows.
 *
 *************************

public class CardPanel extends Panel {
  private Label name;
  private ImageLabel picture;

  public CardPanel(String cardName,
                   URL directory, String imageFile) {
    setLayout(new BorderLayout());
    name = new Label(cardName, Label.CENTER);
    name.setFont(new Font("SanSerif", Font.BOLD, 50));
    add(name, BorderLayout.NORTH);
    picture = new ImageLabel(directory, imageFile);
    Panel picturePanel = new Panel();
    picturePanel.add(picture);
    add(picturePanel, BorderLayout.CENTER);
    setSize(getPreferredSize());
  }

  public Label getLabel() {
    return(name);
  }

  public ImageLabel getImageLabel() {
    return(picture);
  }
}
*******************
ImageLabel.java A Canvas for displaying images.
*******************
import java.awt.*;
import java.net.*; 

/** A class for displaying images. It places the Image
 *  into a canvas so that it can moved around by layout
 *  managers, will get repainted automatically, etc.
 *  No mouseXXX or action events are defined, so it is
 *  most similar to the Label Component.
 *  


 *  By default, with FlowLayout the ImageLabel takes
 *  its minimum size (just enclosing the image). The
 *  default with BorderLayout is to expand to fill
 *  the region in width (North/South), height
 *  (East/West) or both (Center). This is the same
 *  behavior as with the builtin Label class. If you
 *  give an explicit setSize or
 *  setBounds call before adding the
 *  ImageLabel to the Container, this size will
 *  override the defaults.
 *  


 *  Here is an example of its use:
 *  


 *  

 *  public class ShowImages extends Applet {
 *    private ImageLabel image1, image2;
 *
 *    public void init() {
 *      image1 = new ImageLabel(getCodeBase(),
 *                              "some-image.gif");
 *      image2 = new ImageLabel(getCodeBase(),
 *                              "other-image.jpg");
 *      add(image1);
 *      add(image2);
 *    }
 *  }
 *  


 *
  */

public class ImageLabel extends Canvas {
  // Instance variables.
  
  // The actual Image drawn on the canvas. 
  private Image image;

  // A String corresponding to the URL of the image you will 
  // get if you call the constructor with no arguments.
  private static String defaultImageString
    = "http://java.sun.com/lib/images/" +
      "logo.java.color-transp.55x60.gif";

  // The URL of the image. But sometimes we will use an existing
  // image object (e.g. made by createImage) for which this info 
  // will not be available, so a default string is used here.
  private String imageString = "";

  // Turn this on to get verbose debugging messages. 
  private boolean debug = false;

  /** Amount of extra space around the image. */
  
  private int border = 0;

  /** If there is a non-zero border, what color should it be? 
   *  Default is to use the background color of the Container.
   */
   
  private Color borderColor = null;
  
  // Width and height of the Canvas. This is the
  //  width/height of the image plus twice the border.
  private int width, height;

  /** Determines if it will be sized automatically. If the user
   *  issues a setSize() or setBounds()call before adding the 
   *  label to the Container, or if the LayoutManager resizes 
   *  before drawing (as with BorderLayout), then those sizes
   *  override the default, which is to make the label the same 
   *  size as the image it holds (after reserving space for the 
   *  border, if any). This flag notes this, so subclasses that
   *  override ImageLabel need to check this flag, and if it is 
   *  true, and they draw modified image, then they need to draw 
   *  them based on the width height variables, not just blindly 
   *  drawing them full size.
   */
   
  private boolean explicitSize = false;
  private int explicitWidth=0, explicitHeight=0;
  
  // The MediaTracker that can tell if image has been loaded 
  // before trying to paint it or setSize based on its size.
  private MediaTracker tracker;
  
  // Used by MediaTracker to be sure image is loaded before 
  // paint & setSize, since you can't find out the size until it
  // is done loading.
  private static int lastTrackerID=0;
  private int currentTrackerID;
  private boolean doneLoading = false;

  private Container parentContainer;

  /** Create an ImageLabel with the default image.
   *
   * @see #getDefaultImageString
   * @see #setDefaultImageString
   */
  // Remember that the funny "this()" syntax calls
  // constructor of same class
  public ImageLabel() {
    this(defaultImageString);
  }
  
  /** Create an ImageLabel using the image at URL
   *  specified by the string.
   *
   * @param imageURLString A String specifying the
   *   URL of the image.
   */
   
  public ImageLabel(String imageURLString) {
    this(makeURL(imageURLString));
  }

  /** Create an ImageLabel using the image at URL
   *  specified.
   *
   * @param imageURL The URL of the image.
   */
   
  public ImageLabel(URL imageURL) {
    this(loadImage(imageURL));
    imageString = imageURL.toExternalForm();
  }

  /** Create an ImageLabel using the image in the file
   *  in the specified directory.
   *
   * @param imageDirectory Directory containing image
   * @param file Filename of image
   */
   
  public ImageLabel(URL imageDirectory, String file) {
    this(makeURL(imageDirectory, file));
    imageString = file;
  }
  
  /** Create an ImageLabel using the image specified. The other
   *  constructors eventually call this one, but you may want 
   *  to call it directly if you already have an image (e.g. 
   *  created through createImage).
   *
   * @param image The image
   */
   
  public ImageLabel(Image image) {
    this.image = image;
    tracker = new MediaTracker(this);
    currentTrackerID = lastTrackerID++;
    tracker.addImage(image, currentTrackerID);
  }

  /** Makes sure that the Image associated with the Canvas is 
   *  done loading before returning, since loadImage spins off
   *  a separate thread to do the loading. Once you get around 
   *  to drawing the image, this will make sure it is loaded,
   *  waiting if not. The user does not need to call this at 
   *  all, but if several ImageLabels are used in the same 
   *  Container, this can cause several repeated layouts, so 
   *  users might want to explicitly call this themselves before
   *  adding the ImageLabel to the Container. Another 
   *  alternative is to start asynchronous loading by calling 
   *  prepareImage on the ImageLabel's image (see getImage). 
   *
   * @param doLayout Determines if the Container should be 
   *   re-laid out after you are finished waiting. This 
   *   should be true when called from user functions, 
   *   but is set to false when called from getPreferredSize 
   *   to avoid an infinite loop. This is needed when using 
   *   BorderLayout, which calls getPreferredSize
   *   before calling paint.
   */
   
  public void waitForImage(boolean doLayout) {
    if (!doneLoading) {
      debug("[waitForImage] - Resizing and waiting for "
            + imageString);
      try { tracker.waitForID(currentTrackerID); } 
      catch (InterruptedException ie) {} 
      catch (Exception e) { 
        System.out.println("Error loading "
                           + imageString + ": "
                           + e.getMessage()); 
        e.printStackTrace(); 
      } 
      if (tracker.isErrorID(0)) 
        new Throwable("Error loading image "
                      + imageString).printStackTrace();
      doneLoading = true;
      if (explicitWidth != 0)
        width = explicitWidth;
      else
        width = image.getWidth(this) + 2*border;
      if (explicitHeight != 0)
        height = explicitHeight;
      else
        height = image.getHeight(this) + 2*border;
      setSize(width, height);
      debug("[waitForImage] - " + imageString + " is "
            + width + "x" + height + ".");

      // If no parent, you are OK, since it will have
      // been resized before being added. But if
      // parent exists, you have already been added,
      // and the change in size requires re-layout. 
      if (((parentContainer = getParent()) != null)
          && doLayout) {
        setBackground(parentContainer.getBackground());
        parentContainer.doLayout();
      }
    }
  }

  /** Moves the image so that it is centered at
   *  the specified location, as opposed to the setLocation
   *  method of Component which places the top left
   *  corner at the specified location.
   *  


   *  Note: The effects of this could be undone
   *  by the LayoutManager of the parent Container, if
   *  it is using one. So this is normally only used
   *  in conjunction with a null LayoutManager.
   *
   * @param x The X coord of center of the image
   *          (in parent's coordinate system)
   * @param y The Y coord of center of the image
   *          (in parent's coordinate system)
   * @see java.awt.Component#setLocation
   */

  public void centerAt(int x, int y) {
    debug("Placing center of " + imageString + " at ("
          + x + "," + y + ")");
    setLocation(x - width/2, y - height/2); 
  }

  /** Determines if the x and y (in the ImageLabel's
   *  own coordinate system) is inside the
   *  ImageLabel. Put here because Netscape 2.02 has
   *  a bug in which it doesn't process contains() and
   *  locate() tests correctly. 
   */
   
  public synchronized boolean contains(int x, int y) {
    return((x >= 0) && (x <= width)
           && (y >= 0) && (y <= height));
  }
  
  /** Draws the image. If you override this in a
   *  subclass, be sure to call super.paint.
   */
   
  public void paint(Graphics g) {
    if (!doneLoading)
      waitForImage(true);
    else {
      if (explicitSize)
        g.drawImage(image, border, border,
                    width-2*border, height-2*border,
                    this);
      else
        g.drawImage(image, border, border, this);
      drawRect(g, 0, 0, width-1, height-1,
               border, borderColor);
    }
  }

  /** Used by layout managers to calculate the usual
   *  size allocated for the Component. Since some
   *  layout managers (e.g. BorderLayout) may
   *  call this before paint is called, you need to
   *  make sure that the image is done loading, which
   *  will force a setSize, which determines the values
   *  returned.
   */
  public Dimension getPreferredSize() {
    if (!doneLoading)
      waitForImage(false);
    return(super.getPreferredSize());
  }

  /** Used by layout managers to calculate the smallest
   *  size allocated for the Component. Since some
   *  layout managers (e.g. BorderLayout) may
   *  call this before paint is called, you need to
   *  make sure that the image is done loading, which
   *  will force a setSize, which determines the values
   *  returned.
   */
   public Dimension getMinimumSize() {
     if (!doneLoading)
       waitForImage(false);
     return(super.getMinimumSize());
   }
  
  // LayoutManagers (such as BorderLayout) might call
  // setSize or setBounds with only 1 dimension of
  // width/height non-zero. In such a case, you still
  // want the other dimension to come from the image
  // itself.

  /** Resizes the ImageLabel. If you don't setSize the
   *  label explicitly, then what happens depends on
   *  the layout manager. With FlowLayout, as with
   *  FlowLayout for Labels, the ImageLabel takes its
   *  minimum size, just enclosing the image. With
   *  BorderLayout, as with BorderLayout for Labels,
   *  the ImageLabel is expanded to fill the
   *  section. Stretching GIF/JPG files does not always
   *  result in clear looking images. So just as
   *  with builtin Labels and Buttons, don't
   *  use FlowLayout if you don't want the Buttons to
   *  get resized. If you don't use any
   *  LayoutManager, then the ImageLabel will also
   *  just fit the image.
   *  


   *  Note that if you setSize explicitly, you must do
   *  it before the ImageLabel is added to the
   *  Container. In such a case, the explicit size
   *  overrides the image dimensions.
   *
   * @see #setBounds
   */
   
  public void setSize(int width, int height) {
    if (!doneLoading) {
      explicitSize=true;
      if (width > 0)
        explicitWidth=width;
      if (height > 0)
        explicitHeight=height;
    }
    super.setSize(width, height);
  }

  /** Resizes the ImageLabel. If you don't setSize the
   *  label explicitly, then what happens depends on
   *  the layout manager. With FlowLayout, as with
   *  FlowLayout for Labels, the ImageLabel takes its
   *  minimum size, just enclosing the image. With
   *  BorderLayout, as with BorderLayout for Labels,
   *  the ImageLabel is expanded to fill the
   *  section. Stretching GIF/JPG files does not always
   *  result in clear looking images. So just as
   *  with builtin Labels and Buttons, don't
   *  use FlowLayout if you don't want the Buttons to
   *  get resized. If you don't use any
   *  LayoutManager, then the ImageLabel will also
   *  just fit the image.
   *  


   *  Note that if you setSize explicitly, you must do
   *  it before the ImageLabel is added to the
   *  Container. In such a case, the explicit size
   *  overrides the image dimensions.
   *
   * @see #setSize
   */
   
  public void setBounds(int x, int y,
                      int width, int height) {
    if (!doneLoading) {
      explicitSize=true;
      if (width > 0)
        explicitWidth=width;
      if (height > 0)
        explicitHeight=height;
    }
    super.setBounds(x, y, width, height);
  }
  
  // You can't just set the background color to
  // the borderColor and skip drawing the border,
  // since it messes up transparent gifs. You
  // need the background color to be the same as
  // the container.
  
  /** Draws a rectangle with the specified OUTSIDE
   *  left, top, width, and height.
   *  Used to draw the border.
   */
   
  protected void drawRect(Graphics g,
                          int left, int top,
                          int width, int height,
                          int lineThickness,
                          Color rectangleColor) {
    g.setColor(rectangleColor);
    for(int i=0; i
                                

BorderLayout divides the window into five regions

# BorderTest.java Five buttons arranged by BorderLayout
BorderLayout divides the window into five regions: NORTH, SOUTH, EAST, WEST, and CENTER. 
/./././././././././././././
import java.applet.Applet;
import java.awt.*;

/** An example of BorderLayout.
 *
 &&&&&&&&&&&&&&&&&&&&&&&&&&&

public class BorderTest extends Applet {
  public void init() {
    setLayout(new BorderLayout());
    add(new Button("Button 1"), BorderLayout.NORTH);
    add(new Button("Button 2"), BorderLayout.SOUTH);
    add(new Button("Button 3"), BorderLayout.EAST);
    add(new Button("Button 4"), BorderLayout.WEST);
    add(new Button("Button 5"), BorderLayout.CENTER);
  }
}
&&&&&&&&&&&&&&&&&&&&

Checkboxes

Checkboxes.java Inherits from CloseableFrame.java. 
******************
import java.awt.*;

/./././././././././

public class Checkboxes extends CloseableFrame {
  public static void main(String[] args) {
    new Checkboxes();
  }

  public Checkboxes() {
    super("Checkboxes");
    setFont(new Font("SansSerif", Font.BOLD, 18));
    setLayout(new GridLayout(0, 2));
    Checkbox box;
    for(int i=0; i<12; i++) {
      box = new Checkbox("Checkbox " + i);
      if (i%2 == 0) {
        box.setState(true);
      }
      add(box);
    }
    pack();
    setVisible(true);
  }
}

Places a Panel holding 100 buttons in a ScrollPane

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

/** Places a Panel holding 100 buttons in a ScrollPane that is
 *  too small to hold it.
 *
  */

public class ScrollPaneTest extends Applet {
  public void init() {
    setLayout(new BorderLayout());
    ScrollPane pane = new ScrollPane();
    Panel bigPanel = new Panel();
    bigPanel.setLayout(new GridLayout(10, 10));
    for(int i=0; i<100; i++) {
      bigPanel.add(new Button("Button " + i));
    }
    pane.add(bigPanel);
    add(pane, BorderLayout.CENTER);
  }
}

Five buttons arranged by FlowLayout

FlowTest.java 
*************
FlowTest.java Five buttons arranged by FlowLayout
By default, FlowLayout arranges components in rows, left to right, and centered. 
/././././././././././././
import java.applet.Applet;
import java.awt.*;

/** FlowLayout puts components in rows.
 *
 ************************************
public class FlowTest extends Applet {
  public void init() {
    for(int i=1; i<6; i++) {
      add(new Button("Button " + i));
    }
  }
}

A Frame that lets you draw circles with mouse clicks

SavedFrame.java
****************
A Frame that lets you draw circles with mouse clicks 
//**************
import java.awt.*;
import java.awt.event.*;
import java.io.*;

/** A Frame that lets you draw circles with mouse clicks 
 *  and then save the Frame and all circles to disk.
 *
public class SavedFrame extends CloseableFrame
                        implements ActionListener {
  
  /** If a saved version exists, use it. Otherwise create a 
   *  new one.
   */
                          
  public static void main(String[] args) {
    SavedFrame frame;
    File serializeFile = new File(serializeFilename);
    if (serializeFile.exists()) {
      try {
        FileInputStream fileIn = 
          new FileInputStream(serializeFile);
        ObjectInputStream in = new ObjectInputStream(fileIn);
        frame = (SavedFrame)in.readObject();
        frame.setVisible(true);
      } catch(IOException ioe) {
        System.out.println("Error reading file: " + ioe);
      } catch(ClassNotFoundException cnfe) {
        System.out.println("No such class: " + cnfe);
      }
    } else {
      frame = new SavedFrame();
    }
  }

  private static String serializeFilename ="SavedFrame.ser";
  private CirclePanel circlePanel;
  private Button clearButton, saveButton;

  /** Build a frame with CirclePanel and buttons. */
                          
  public SavedFrame() {
    super("SavedFrame");
    setBackground(Color.white);
    setFont(new Font("Serif", Font.BOLD, 18));
    circlePanel = new CirclePanel();
    add("Center", circlePanel);
    Panel buttonPanel = new Panel();
    buttonPanel.setBackground(Color.lightGray);
    clearButton = new Button("Clear");
    saveButton = new Button("Save");
    buttonPanel.add(clearButton);
    buttonPanel.add(saveButton);
    add(buttonPanel, BorderLayout.SOUTH);
    clearButton.addActionListener(this);
    saveButton.addActionListener(this);
    setSize(300, 300);
    setVisible(true);
  }

  /** If "Clear" clicked, delete all existing circles. If "Save"
   *  clicked, save existing frame configuration (size, 
   *  location, circles, etc.) to disk.
   */
                          
  public void actionPerformed(ActionEvent event) {
    if (event.getSource() == clearButton) {
      circlePanel.removeAll();
      circlePanel.repaint();
    } else if (event.getSource() == saveButton) {
      try {
        FileOutputStream fileOut =
          new FileOutputStream("SavedFrame.ser");
        ObjectOutputStream out = 
          new ObjectOutputStream(fileOut);
        out.writeObject(this);
        out.flush();
        out.close();
      } catch(IOException ioe) {
        System.out.println("Error saving frame: " + ioe);
      }
    }
  }
}
****************

FrameExample1.java and 2

******************
# FrameExample1.java
******************
import java.awt.*;

/** 
 */

public class FrameExample1 {
  public static void main(String[] args) {
    Frame f = new Frame("Frame Example 1");
    f.setSize(400, 300);
    f.setVisible(true);
  }
}
*********************
# FrameExample2.java 
*********************
import java.awt.*;

/** 
 */

public class FrameExample2 extends Frame {
  public static void main(String[] args) {
    new FrameExample2();
  }
 
  public FrameExample2() {
    super("Frame Example 2");
    setSize(400, 300);
    setVisible(true);
  }
}
**********************

ThreadedRSAKey.java Illustrates converting a method in an existing class from a single-threaded method to a multi-threaded method.

ThreadedRSAKey.java  Illustrates converting a method in an existing class from a single-threaded method to a multi-threaded method. In this example, RSAKey  computes an RSA public-private key pair, where the key size has a specified number of digits. As large prime numbers require considerable CPU time, ThreadedRSAKey converts the original computeKey method in RSAKey  to a multi-threaded method, thus allowing simultaneous (multithreaded) computation of multiple key pairs. Uses the following classes:

 

import java.io.*;   

 * RSAKey.java Computes RSA public-private key pairs of arbitrary length.


 * Primes.java Generates large prime numbers.


/** An example of creating a background process for an
 *  originally nonthreaded, class method. Normally,
 *  the program flow will wait until computeKey is finished.
 
public class ThreadedRSAKey extends RSAKey implements Runnable {

  // Store strNumDigits into the thread to prevent race
  // conditions.
  public void computeKey(String strNumDigits) {
    RSAThread t = new RSAThread(this, strNumDigits);
    t.start();
  }

  // Retrieve the stored strNumDigits and call the original
  // method.  Processing is now done in the background.
  public void run() {
    RSAThread t = (RSAThread)Thread.currentThread();
    String strNumDigits = t.getStrDigits();
    super.computeKey(strNumDigits);
  }

  public static void main(String[] args){
    ThreadedRSAKey key = new ThreadedRSAKey();
    for (int i=0; i " + n);
    System.out.println("public  => " + encrypt);
    System.out.println("private => " + decrypt);
  }
}


 * Primes.java Generates large prime numbers.
***

import java.math.BigInteger;

/** A few utilities to generate a large random BigInteger,
 *  and find the next prime number above a given BigInteger.
 
public class Primes {
  // Note that BigInteger.ZERO was new in JDK 1.2, and 1.1
  // code is being used to support the most servlet engines.
  private static final BigInteger ZERO = new BigInteger("0");
  private static final BigInteger ONE = new BigInteger("1");
  private static final BigInteger TWO = new BigInteger("2");
  
  // Likelihood of false prime is less than 1/2^ERR_VAL
  // Assumedly BigInteger uses the Miller-Rabin test or
  // equivalent, and thus is NOT fooled by Carmichael numbers.
  // See section 33.8 of Cormen et al. Introduction to
  // Algorithms for details.
  private static final int ERR_VAL = 100;
  
  public static BigInteger nextPrime(BigInteger start) {
    if (isEven(start))
      start = start.add(ONE);
    else
      start = start.add(TWO);
    if (start.isProbablePrime(ERR_VAL))
      return(start);
    else
      return(nextPrime(start));
  }

  private static boolean isEven(BigInteger n) {
    return(n.mod(TWO).equals(ZERO));
  }

  private static StringBuffer[] digits =
    { new StringBuffer("0"), new StringBuffer("1"),
      new StringBuffer("2"), new StringBuffer("3"),
      new StringBuffer("4"), new StringBuffer("5"),
      new StringBuffer("6"), new StringBuffer("7"),
      new StringBuffer("8"), new StringBuffer("9") };

  private static StringBuffer randomDigit() {
    int index = (int)Math.floor(Math.random() * 10);
    return(digits[index]);
  }
  
  public static BigInteger random(int numDigits) {
    StringBuffer s = new StringBuffer("");
    for(int i=0; i 0)
      numDigits = Integer.parseInt(args[0]);
    else
      numDigits = 150;
    BigInteger start = random(numDigits);
    for(int i=0; i<50; i++) {
      start = nextPrime(start);
      System.out.println("Prime " + i + " = " + start);
    }
  }
}

Eight ungrouped buttons in an Applet using FlowLayout

mport java.applet.Applet; import java.awt.
*; 
************************** 
/** Eight ungrouped buttons in an Applet using FlowLayout. * */ 
public class ButtonTest1 extends Applet { 
      public void init() { 
            String[] labelPrefixes = { 
                  "Start", "Stop", "Pause", "Resume" 
      }; 
      for (int i=0; i<4; i++) { 
           add(new Button(labelPrefixes[i] + " Thread1")); 
      } 
      for (int i=0; i<4; i++) { 
           add(new Button(labelPrefixes[i] + " Thread2")); 
      } 
   }  
}

A Circle component built using a Canvas

import java.awt.*;

/** A Circle component built using a Canvas. 
 *
  */

public class Circle extends Canvas {
  private int width, height;        
        
  public Circle(Color foreground, int radius) {
    setForeground(foreground);
    width = 2*radius;
    height = 2*radius;
    setSize(width, height);
  }

  public void paint(Graphics g) {
    g.fillOval(0, 0, width, height);
  }

  public void setCenter(int x, int y) {
    setLocation(x - width/2, y - height/2);
  }
}

Simplifies the setting of native look and feel

WindowUtilities.java Simplifies the setting of native look and feel. 
####################
import javax.swing.*;
import java.awt.*;   // For Color and Container classes.

/** A few utilities that simplify using windows in Swing. 
 *
###################

public class WindowUtilities {

  /** Tell system to use native look and feel, as in previous
   *  releases. Metal (Java) LAF is the default otherwise.
   */

  public static void setNativeLookAndFeel() {
    try {
     UIManager.setLookAndFeel(
       UIManager.getSystemLookAndFeelClassName());
    } catch(Exception e) {
      System.out.println("Error setting native LAF: " + e);
    }
  }

  public static void setJavaLookAndFeel() {
    try {
     UIManager.setLookAndFeel(
       UIManager.getCrossPlatformLookAndFeelClassName());
    } catch(Exception e) {
      System.out.println("Error setting Java LAF: " + e);
    }
  }

   public static void setMotifLookAndFeel() {
    try {
      UIManager.setLookAndFeel(
        "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
    } catch(Exception e) {
      System.out.println("Error setting Motif LAF: " + e);
    }
  }

  /** A simplified way to see a JPanel or other Container. Pops
   *  up a JFrame with specified Container as the content pane.
   */

  public static JFrame openInJFrame(Container content,
                                    int width,
                                    int height,
                                    String title,
                                    Color bgColor) {
    JFrame frame = new JFrame(title);
    frame.setBackground(bgColor);
    content.setBackground(bgColor);
    frame.setSize(width, height);
    frame.setContentPane(content);
    frame.addWindowListener(new ExitListener());
    frame.setVisible(true);
    return(frame);
  }

  /** Uses Color.white as the background color. */

  public static JFrame openInJFrame(Container content,
                                    int width,
                                    int height,
                                    String title) {
    return(openInJFrame(content, width, height,
                        title, Color.white));
  }

  /** Uses Color.white as the background color, and the
   *  name of the Container's class as the JFrame title.
   */

  public static JFrame openInJFrame(Container content,
                                    int width,
                                    int height) {
    return(openInJFrame(content, width, height,
                        content.getClass().getName(),
                        Color.white));
  }
}

Using the this reference in class Ship3

/./././././././././.
// Give Ship3 a constructor to let the instance variables
// be specified when the object is created.
/./././././././././

class Ship3 {
  public double x, y, speed, direction;
  public String name;

  public Ship3(double x, double y, double speed,
               double direction, String name) {
    this.x = x; // "this" differentiates instance vars
    this.y = y; //  from local vars.
    this.speed = speed;
    this.direction = direction;
    this.name = name;
  }
  
  private double degreesToRadians(double degrees) {
    return(degrees * Math.PI / 180.0);
  }

 public void move() {
    double angle = degreesToRadians(direction);
    x = x + speed * Math.cos(angle);
    y = y + speed * Math.sin(angle);
  }

  public void printLocation() {
    System.out.println(name + " is at " + 
                       "(" + x + "," + y + ").");
  }
}

public class Test3 {
  public static void main(String[] args) {
    Ship3 s1 = new Ship3(0.0, 0.0, 1.0,   0.0, "Ship1");
    Ship3 s2 = new Ship3(0.0, 0.0, 2.0, 135.0, "Ship2");
    s1.move();
    s2.move();
    s1.printLocation();
    s2.printLocation();
  }
}

DashedStrokeExample.java Draws a circle with a dashed line segment (border). Inherits from FontExample.java.

>>>>>>>>>>>>>>>>>
import java.awt.*;

/** An example of creating a custom dashed line for drawing.
 *
 *********************
public class DashedStrokeExample extends FontExample {
  public void paintComponent(Graphics g) {
    clear(g);
    Graphics2D g2d = (Graphics2D)g;
    drawGradientCircle(g2d);
    drawBigString(g2d);
    drawDashedCircleOutline(g2d);
  }

  protected void drawDashedCircleOutline(Graphics2D g2d) {
    g2d.setPaint(Color.blue);
    // 30-pixel line, 10-pixel gap, 10-pixel line, 10-pixel gap
    float[] dashPattern = { 30, 10, 10, 10 };
    g2d.setStroke(new BasicStroke(8, BasicStroke.CAP_BUTT,
                                  BasicStroke.JOIN_MITER, 10,
                                  dashPattern, 0));
    g2d.draw(getCircle());
  }

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

draws a circle wherever mouse was pressed

CircleListener.java A subclass of MouseAdapter that draws a circle wherever mouse was pressed. Illustrates first approach to event-handling with listeners: attaching a separate listener
***********

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

/** The listener used by CircleDrawer1. Note call
 *  to getSource to obtain reference to the applet.
 *  


 ***************
public class CircleListener extends MouseAdapter {
  private int radius = 25;

  public void mousePressed(MouseEvent event) {
    Applet app = (Applet)event.getSource();
    Graphics g = app.getGraphics();
    g.fillOval(event.getX()-radius,
               event.getY()-radius,
               2*radius,
               2*radius);
  }
}

Six buttons arranged in a 2 row x 3 column grid by GridLayout

/././././././
GridTest.java Six buttons arranged in a 2 row x 3 column grid by GridLayout.GridLayout divides the window into equal-sized rectangles based upon the number of rows and columns specified. 
******************
import java.applet.Applet;
import java.awt.*;

/** An example of GridLayout.
 *
 /./././././.

public class GridTest extends Applet {
  public void init() {
    setLayout(new GridLayout(2,3)); // 2 rows, 3 cols
    add(new Button("Button One"));
    add(new Button("Button Two"));
    add(new Button("Button Three"));
    add(new Button("Button Four"));
    add(new Button("Button Five"));
    add(new Button("Button Six"));
  }
}

ListEvent2.java

# ListEvents.java Uses the following classes:

    * CloseableFrame.java
    * SelectionReporter.java
    * ActionReporter.java
/././././././././././././
import java.awt.event.*;

/././././././

public class ListEvents2 extends ListEvents {
  public static void main(String[] args) {
    new ListEvents2();
  }

  /** Extends ListEvents with the twist that
   *  typing any of the letters of "JAVA" or "java"
   *  over the language list will result in "Java"
   *  being selected
   */

  public ListEvents2() {
    super();
    // Create a KeyAdapter and attach it to languageList.
    // Since this is an inner class, it has access
    // to nonpublic data (such as the ListEvent's
    // protected showJava method).
    KeyAdapter javaChooser = new KeyAdapter() {
      public void keyPressed(KeyEvent event) {
        int key = event.getKeyChar();
        if ("JAVAjava".indexOf(key) != -1) {
          showJava();
        }
      }
    };
    languageList.addKeyListener(javaChooser);
  }
}

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

/** A class to demonstrate list selection/deselection
 *  and action events.
 *
 /*******************/.>

public class ListEvents extends CloseableFrame {
  public static void main(String[] args) {
    new ListEvents();
  }

  protected List languageList;
  private TextField selectionField, actionField;
  private String selection = "[NONE]", action;

  /** Build a Frame with list of language choices
   *  and two textfields to show the last selected
   *  and last activated items from this list.
   */
  public ListEvents() {
    super("List Events");
    setFont(new Font("Serif", Font.BOLD, 16));
    add(makeLanguagePanel(), BorderLayout.WEST);
    add(makeReportPanel(), BorderLayout.CENTER);
    pack();
    setVisible(true);
  }

  // Create Panel containing List with language choices.
  // Constructor puts this at left side of Frame.
  
  private Panel makeLanguagePanel() {
    Panel languagePanel = new Panel();
    languagePanel.setLayout(new BorderLayout());
    languagePanel.add(new Label("Choose Language"), 
                      BorderLayout.NORTH);
    languageList = new List(3);
    String[] languages =
      { "Ada", "C", "C++", "Common Lisp", "Eiffel",
        "Forth", "Fortran", "Java", "Pascal",
        "Perl", "Scheme", "Smalltalk" };
    for(int i=0; i

A Frame that can actually quit

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

/** A Frame that you can actually quit. Used as the starting 
 *  point for most Java 1.1 graphical applications.
 *

public class CloseableFrame extends Frame {
  public CloseableFrame(String title) {
    super(title);
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
  }

  /** Since we are doing something permanent, we need
   *  to call super.processWindowEvent first.
   */
  
  public void processWindowEvent(WindowEvent event) {
    super.processWindowEvent(event); // Handle listeners.
    if (event.getID() == WindowEvent.WINDOW_CLOSING) {
      // If the frame is used in an applet, use dispose().
      System.exit(0);
    }
  }
}

creating a simple Swing application using a JFrame

JFrameExample.java Demonstrates creating a simple Swing application using a JFrame. As with a JApplet, components must be added to the content pane, instead of the window directly.import java.awt.*;

import javax.swing.*;

/** Tiny example showing the main difference in using 
 *  JFrame instead of Frame: using the content pane
 *  and getting the Java (Metal) look and feel by default
 *  instead of the native look and feel.
 *
 */

public class JFrameExample {
  public static void main(String[] args) {
    WindowUtilities.setNativeLookAndFeel();
    JFrame f = new JFrame("This is a test");
    f.setSize(400, 150);
    Container content = f.getContentPane();
    content.setBackground(Color.white);
    content.setLayout(new FlowLayout()); 
    content.add(new JButton("Button 1"));
    content.add(new JButton("Button 2"));
    content.add(new JButton("Button 3"));
    f.addWindowListener(new ExitListener());
    f.setVisible(true);
  }
}

Explicit placement of five buttons with the layout manager turned off

NullTest.java Explicit placement of five buttons with the layout manager turned off (set to null)
##########################
import java.applet.Applet;
import java.awt.*;

/** Layout managers are intended to help you, but there
 *  is no law saying you have to use them.
 *  Set the layout to null to turn them off.
 *
*******************
public class NullTest extends Applet {
  public void init() {
    setLayout(null);
    Button b1 = new Button("Button 1");
    Button b2 = new Button("Button 2");
    Button b3 = new Button("Button 3");
    Button b4 = new Button("Button 4");
    Button b5 = new Button("Button 5");
    b1.setBounds(0, 0, 150, 50);
    b2.setBounds(150, 0, 75, 50);
    b3.setBounds(225, 0, 75, 50);
    b4.setBounds(25, 60, 100, 40);
    b5.setBounds(175, 60, 100, 40);
    add(b1);
    add(b2);
    add(b3);
    add(b4);
    add(b5);
  }
}

JTree Examples

SimpleTree.java Basic tree built out of DefaultMutableTreeNodes. A DefualtMutableTreeNode is a starting point for a root node, in which children nodes can be added.

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

/** Example tree built out of DefaultMutableTreeNodes. 
 *
 */

public class SimpleTree extends JFrame {
  public static void main(String[] args) {
    new SimpleTree();
  }
 
  public SimpleTree() {
    super("Creating a Simple JTree");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    Object[] hierarchy =
      { "javax.swing",
        "javax.swing.border",
        "javax.swing.colorchooser",
        "javax.swing.event",
        "javax.swing.filechooser",
        new Object[] { "javax.swing.plaf",
                       "javax.swing.plaf.basic",
                       "javax.swing.plaf.metal",
                       "javax.swing.plaf.multi" },
        "javax.swing.table",
        new Object[] { "javax.swing.text",
                       new Object[] { "javax.swing.text.html",
                                     "javax.swing.text.html.parser" },
                       "javax.swing.text.rtf" },
        "javax.swing.tree",
        "javax.swing.undo" };
    DefaultMutableTreeNode root = processHierarchy(hierarchy);
    JTree tree = new JTree(root);
    content.add(new JScrollPane(tree), BorderLayout.CENTER);
    setSize(275, 300);
    setVisible(true);
  }

  /** Small routine that will make a node out of the first entry
   *  in the array, then make nodes out of subsequent entries
   *  and make them child nodes of the first one. The process 
   *  is repeated recursively for entries that are arrays.
   */

  private DefaultMutableTreeNode processHierarchy(
                                           Object[] hierarchy) {
    DefaultMutableTreeNode node =
      new DefaultMutableTreeNode(hierarchy[0]);
    DefaultMutableTreeNode child;
    for(int i=1; i 0) {
      try {
        n = Integer.parseInt(args[0]);
      } catch(NumberFormatException nfe) {
        System.out.println(
          "Can't parse number; using default of " + n);
      }
   }
    new DynamicTree(n);
  }
 
  public DynamicTree(int n) {
    super("Creating a Dynamic JTree");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    JTree tree = new JTree(new OutlineNode(1, n));
    content.add(new JScrollPane(tree), BorderLayout.CENTER);
    setSize(300, 475);
    setVisible(true);
  }
}


    * OutlineNode.java A simple tree node that builds its children.
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;

/** Simple TreeNode that builds children on the fly.
 *  The key idea is that getChildCount is always called before
 *  any actual children are requested. That way, getChildCount 
 *  builds the children if they don't already exist.
 *  


 *  In this case, it just builds an "outline" tree. I.e.,
 *  if the root is current node is "x", the children are
 *  "x.0", "x.1", "x.2", and "x.3".
 * 


 *
 */

public class OutlineNode extends DefaultMutableTreeNode {
  private boolean areChildrenDefined = false;
  private int outlineNum;
  private int numChildren;

  public OutlineNode(int outlineNum, int numChildren) {
    this.outlineNum = outlineNum;
    this.numChildren = numChildren;
  }
  
  public boolean isLeaf() {
    return(false);
  }

  public int getChildCount() {
    if (!areChildrenDefined) {
      defineChildNodes();
    }
    return(super.getChildCount());
  }

  private void defineChildNodes() {
    // You must set the flag before defining children if you
    // use "add" for the new children. Otherwise, you get an 
    // infinite recursive loop since add results in a call 
    // to getChildCount. However, you could use "insert" in such 
    // a case.
    areChildrenDefined = true;
    for(int i=0; i
                                

Printing in Java 2

   *
          o PrintExample.java Demonstrates printing a Graphics2D object.

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.print.*;

/** An example of a printable window in Java 1.2. The key point
 *  here is that any component is printable in Java 1.2.
 *  However, you have to be careful to turn off double buffering
 *  globally (not just for the top-level window).
 *  See the PrintUtilities class for the printComponent method
 *  that lets you print an arbitrary component with a single
 *  function call.
 *
 */

public class PrintExample extends JFrame
                           implements ActionListener {
  public static void main(String[] args) {
    new PrintExample();
  }

  public PrintExample() {
    super("Printing Swing Components in JDK 1.2");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    JButton printButton = new JButton("Print");
    printButton.addActionListener(this);
    JPanel buttonPanel = new JPanel();
    buttonPanel.setBackground(Color.white);
    buttonPanel.add(printButton);
    content.add(buttonPanel, BorderLayout.SOUTH);
    DrawingPanel drawingPanel = new DrawingPanel();
    content.add(drawingPanel, BorderLayout.CENTER);
    pack();
    setVisible(true);
  }

  public void actionPerformed(ActionEvent event) {
    PrintUtilities.printComponent(this);
  }
}

 Uses the following classes:
                + PrintUtilities.java Simple utility class to support printing graphical windows in JDK 1.2.

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

/** A simple utility class that lets you very simply print
 *  an arbitrary component in JDK 1.2. Just pass the 
 *  component to PrintUtilities.printComponent. The 
 *  component you want to print doesn't need a print method 
 *  and doesn't have to implement any interface or do 
 *  anything special at all.
 *  


 *  If you are going to be printing many times, it is marginally
 *  more efficient to first do the following:
 *  

 *    PrintUtilities printHelper = 
 *      new PrintUtilities(theComponent);
 *  


 *  then later do printHelper.print(). But this is a very tiny
 *  difference, so in most cases just do the simpler
 *  PrintUtilities.printComponent(componentToBePrinted).
 *
 
 */

public class PrintUtilities implements Printable {
  protected Component componentToBePrinted;

  public static void printComponent(Component c) {
    new PrintUtilities(c).print();
  }
  
  public PrintUtilities(Component componentToBePrinted) {
    this.componentToBePrinted = componentToBePrinted;
  }
  
  public void print() {
    PrinterJob printJob = PrinterJob.getPrinterJob();
    printJob.setPrintable(this);
    if (printJob.printDialog())
      try {
        printJob.print();
      } catch(PrinterException pe) {
        System.out.println("Error printing: " + pe);
      }
  }

  // General print routine for JDK 1.2. Use PrintUtilities2
  // for printing in JDK 1.3.
  public int print(Graphics g, PageFormat pageFormat, 
                   int pageIndex) {
    if (pageIndex > 0) {
      return(NO_SUCH_PAGE);
    } else {
      Graphics2D g2d = (Graphics2D)g;
      g2d.translate(pageFormat.getImageableX(), 
                    pageFormat.getImageableY());
      disableDoubleBuffering(componentToBePrinted);
      componentToBePrinted.paint(g2d);
      enableDoubleBuffering(componentToBePrinted);
      return(PAGE_EXISTS);
    }
  }

  /** The speed and quality of printing suffers dramatically if
   *  any of the containers have double buffering turned on,
   *  so this turns it off globally.  This step is only 
   *  required in JDK 1.2.
   */
   
  public static void disableDoubleBuffering(Component c) {
    RepaintManager currentManager = 
                      RepaintManager.currentManager(c);
    currentManager.setDoubleBufferingEnabled(false);
  }

  /** Reenables double buffering globally. This step is only 
   *  required in JDK 1.2.
   */
  
  public static void enableDoubleBuffering(Component c) {
    RepaintManager currentManager = 
                      RepaintManager.currentManager(c);
    currentManager.setDoubleBufferingEnabled(true);
  }
}
//
                + DrawingPanel.java A basic JPanel containing a Java 2D drawing.

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

/** A window with a custom paintComponent method. 
 *  Illustrates that you can make a general-purpose method
 *  that can print any component, regardless of whether
 *  that component performs custom drawing.
 *  See the PrintUtilities class for the printComponent method
 *  that lets you print an arbitrary component with a single
 *  function call.
 *
  */

public class DrawingPanel extends JPanel {
  private int fontSize = 90;
  private String message = "Java 2D";
  private int messageWidth;
  
  public DrawingPanel() {
    setBackground(Color.white);
    Font font = new Font("Serif", Font.PLAIN, fontSize);
    setFont(font);
    FontMetrics metrics = getFontMetrics(font);
    messageWidth = metrics.stringWidth(message);
    int width = messageWidth*5/3;
    int height = fontSize*3;
    setPreferredSize(new Dimension(width, height));
  }

  /** Draws a black string with a tall angled "shadow"
   *  of the string behind it.
   */

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    int x = messageWidth/10;
    int y = fontSize*5/2;
    g2d.translate(x, y);
    g2d.setPaint(Color.lightGray);
    AffineTransform origTransform = g2d.getTransform();
    g2d.shear(-0.95, 0);
    g2d.scale(1, 3);
    g2d.drawString(message, 0, 0);
    g2d.setTransform(origTransform);
    g2d.setPaint(Color.black);
    g2d.drawString(message, 0, 0);
  }
}

          o PrintUtilities2.java Simple utility class to support printing graphical windows in JDK 1.3 and later. Inherits from PrintUtilities.java.

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

/** A simple utility class for printing an arbitrary
 *  component in JDK 1.3. The class relies on the 
 *  fact that in JDK 1.3 the JComponent class overrides
 *  print (in Container) to automatically set a flag
 *  that disables double buffering before the component
 *  is painted. If the printing flag is set, paint calls 
 *  printComponent, printBorder, and printChildren.
 *
 *  To print a component, just pass the component to 
 *  PrintUtilities2.printComponent(componentToBePrinted). 
 *
  */

public class PrintUtilities2 extends PrintUtilities {

  public static void printComponent(Component c) {
    new PrintUtilities2(c).print();
  }
  
  public PrintUtilities2(Component componentToBePrinted) {
    super(componentToBePrinted);
  }
  
  // General print routine for JDK 1.3. Use PrintUtilities1
  // for printing in JDK 1.2.
  public int print(Graphics g, PageFormat pageFormat, 
                   int pageIndex) {
    if (pageIndex > 0) {
      return(NO_SUCH_PAGE);
    } else {
      Graphics2D g2d = (Graphics2D)g;
      g2d.translate(pageFormat.getImageableX(), 
                    pageFormat.getImageableY());
      componentToBePrinted.print(g2d);
      return(PAGE_EXISTS);
    }
  }
}

    * FileTransfer.java Demonstrates the proper technique for updating Swing components in a multithreaded program.

/** 

// Final version of FileTransfer. Modification of the 
// label is thread safe.

public class FileTransfer extends Thread {
  private String filename;
  private JLabel label;

  public FileTransfer(String filename, JLabel label) {
    this.filename = filename;
    this.label = label;
  }

  public void run() {
  
    try {
      // Place the runnable object to update the label
      // on the event queue. The invokeAndWait method
      // will block until the label is updated.
      SwingUtilities.invokeAndWait(
        new Runnable() {
          public void run() {
            label.setText("Transferring " + filename);
          }
        });
    } catch(InvocationTargetException ite) {
    } catch(InterruptedException ie) { }
       
    // Transfer file to server. Lengthy process.
    doTransfer(...);

    // Perform the final update to the label from
    // within the runnable object. Use invokeLater;
    // blocking is not necessary.
    SwingUtilities.invokeLater(
       new Runnable() {
         public void run() {
           label.setText("Transfer completed");
         }
       });
  }
}
    * WindowUtilities.java Utility class that simplifies creating a window and setting the look and feel.
    * ExitListener.java A WindowListener with support to close the window.

BetterCircleTest.java

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

/** Position circles down the diagonal so that their borders
 *  just touch. Illustrates that Java 1.1 lightweight 
 *  components can be partially transparent.
 *
  */

public class BetterCircleTest extends Applet {
  public void init() {
    setBackground(Color.lightGray);
    setLayout(null);
    BetterCircle circle;
    int radius = getSize().width/6;
    int deltaX = round(2.0 * (double)radius / Math.sqrt(2.0));
    for (int x=radius; x<6*radius; x=x+deltaX) {
      circle = new BetterCircle(Color.black, radius);
      add(circle);
      circle.setCenter(x, x);
    }
  }

  private int round(double num) {
    return((int)Math.round(num));
  }
}
********************************
BetterCircle.java
********************************
import java.awt.*;

/** An improved variation of the Circle class that uses Java 1.1
 *  lightweight components instead of Canvas.
 *
  */

public class BetterCircle extends Component {
  private Dimension preferredDimension;
  private int width, height;
  
  public BetterCircle(Color foreground, int radius) {
    setForeground(foreground);
    width = 2*radius;
    height = 2*radius;
    preferredDimension = new Dimension(width, height);
    setSize(preferredDimension);
  }

  public void paint(Graphics g) {
    g.setColor(getForeground());
    g.fillOval(0, 0, width, height);
  }

  public void setCenter(int x, int y) {
    setLocation(x - width/2, y - height/2);
  }

  /** Report the original size as the preferred size.
   *  That way, the BetterCircle doesn't get
   *  shrunk by layout managers.
   */
  
  public Dimension getPreferredSize() {
    return(preferredDimension);
  }

  /** Report same thing for minimum size as
   *  preferred size.
   */
  
  public Dimension getMinimumSize() {
    return(preferredDimension);
  }
}
*******************************

RMI Example – Numerical Integration, a more realistic RMI example that sends an evaluatable object (function) from a client to a server for numerical integration.

Integral.java  Performs actual numerical integration of the function (evaluatable object).

/** A class to calculate summations and numeric integrals. The
 *  integral is calculated according to the midpoint rule.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class Integral {
  /** Returns the sum of f(x) from x=start to x=stop, where the
   *  function f is defined by the evaluate method of the
   *  Evaluatable object.
   */

  public static double sum(double start, double stop,
                           double stepSize,
                           Evaluatable evalObj) {
    double sum = 0.0, current = start;
    while (current <= stop) {
      sum += evalObj.evaluate(current);
      current += stepSize;
    }
    return(sum);
  }

  /** Returns an approximation of the integral of f(x) from
   *  start to stop, using the midpoint rule. The function f is
   *  defined by the evaluate method of the Evaluatable object.
   */

  public static double integrate(double start, double stop,
                                 int numSteps,
                                 Evaluatable evalObj) {
    double stepSize = (stop - start) / (double)numSteps;
    start = start + stepSize / 2.0;
    return(stepSize * sum(start, stop, stepSize, evalObj));
  }
}



Evaluatable.java  An interface for evaluating functions. Requires the Evaluatable  object to implement the evaluate method. 

/** An interface for evaluating functions y = f(x) at a specific
 *  value. Both x and y are double-precision floating-point
 *  numbers.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public interface Evaluatable {
  public double evaluate(double value);
}


RemoteIntegral.java  Establishes the methods in the remote object available to the client. 

import java.rmi.*;

/** Interface for remote numeric integration object.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public interface RemoteIntegral extends Remote {

  public double sum(double start, double stop, double stepSize,
                    Evaluatable evalObj)
    throws RemoteException;

  public double integrate(double start, double stop,
                          int numSteps, Evaluatable evalObj)
    throws RemoteException;
}


RemoteIntegralClient.java  The client that sends an Evaluatable object to the remote server for integration. 

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

/** This class calculates a variety of numerical integration
 *  values, printing the results of successively more accurate
 *  approximations. The actual computation is performed on a
 *  remote machine whose hostname is specified as a command-
 *  line argument.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class RemoteIntegralClient {
  public static void main(String[] args) {
    try {
      String host = (args.length > 0) ? args[0] : "localhost";
      RemoteIntegral remoteIntegral =
        (RemoteIntegral)Naming.lookup("rmi://" + host +
                                      "/RemoteIntegral");
      for(int steps=10; steps<=10000; steps*=10) {
        System.out.println
          ("Approximated with " + steps + " steps:" +
           "\n  Integral from 0 to pi of sin(x)=" +
           remoteIntegral.integrate(0.0, Math.PI,
                                    steps, new Sin()) +
           "\n  Integral from pi/2 to pi of cos(x)=" +
           remoteIntegral.integrate(Math.PI/2.0, Math.PI,
                                    steps, new Cos()) +
           "\n  Integral from 0 to 5 of x^2=" +
           remoteIntegral.integrate(0.0, 5.0, steps,
                                    new Quadratic()));
      }
      System.out.println
        ("`Correct' answer using Math library:" +
         "\n  Integral from 0 to pi of sin(x)=" +
         (-Math.cos(Math.PI) - -Math.cos(0.0)) +
         "\n  Integral from pi/2 to pi of cos(x)=" +
         (Math.sin(Math.PI) - Math.sin(Math.PI/2.0)) +
         "\n  Integral from 0 to 5 of x^2=" +
         (Math.pow(5.0, 3.0) / 3.0));
    } catch(RemoteException re) {
      System.out.println("RemoteException: " + re);
    } catch(NotBoundException nbe) {
      System.out.println("NotBoundException: " + nbe);
    } catch(MalformedURLException mfe) {
      System.out.println("MalformedURLException: " + mfe);
    }
  }
}


Sin.java  Evaluatable version of sin(x).
import java.io.Serializable;

/** An evaluatable version of sin(x).
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

class Sin implements Evaluatable, Serializable {
  public double evaluate(double val) {
    return(Math.sin(val));
  }

  public String toString() {
    return("Sin");
  }
}

Cos.java  Evaluatable version of cos(x). 

import java.io.Serializable;

/** An evaluatable version of cos(x).
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

class Cos implements Evaluatable, Serializable {
  public double evaluate(double val) {
    return(Math.cos(val));
  }

  public String toString() {
    return("Cosine");
  }
}


Quadratic.java  Evaluatable version of x2. 


import java.io.Serializable;

/** An evaluatable version of x^2.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

class Quadratic implements Evaluatable, Serializable {
  public double evaluate(double val) {
    return(val * val);
  }

  public String toString() {
    return("Quadratic");
  }
}

RemoteIntegralImpl.java  The remote object which provides a concrete implementation of the RemoteIntegral interface. 

import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

/** The actual implementation of the RemoteIntegral interface.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class RemoteIntegralImpl extends UnicastRemoteObject
                                implements RemoteIntegral {

  /** Constructor must throw RemoteException. */

  public RemoteIntegralImpl() throws RemoteException {}

  /** Returns the sum of f(x) from x=start to x=stop, where the
   *  function f is defined by the evaluate method of the
   *  Evaluatable object.
   */

  public double sum(double start, double stop, double stepSize,
                    Evaluatable evalObj) {
    return(Integral.sum(start, stop, stepSize, evalObj));
  }

  /** Returns an approximation of the integral of f(x) from
   *  start to stop, using the midpoint rule. The function f is
   *  defined by the evaluate method of the Evaluatable object.
   * @see #sum
   */

  public double integrate(double start, double stop, int numSteps,
                          Evaluatable evalObj) {
    return(Integral.integrate(start, stop, numSteps, evalObj));
  }
}



RemoteIntegralServer.java  Creates an instance of RemoteIntegralImpl on the remote server and binds the object in the registry for lookup by the client. 

import java.rmi.*;
import java.net.*;

/** Creates a RemoteIntegralImpl object and registers it under
 *  the name 'RemoteIntegral' so that remote clients can connect
 *  to it for numeric integration results. The idea is to place
 *  this server on a workstation with very fast floating-point
 *  capabilities, while slower interfaces can run on smaller
 *  computers but still use the integration routines.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class RemoteIntegralServer {
  public static void main(String[] args) {
    try {
      RemoteIntegralImpl integral =  new RemoteIntegralImpl();
      Naming.rebind("rmi:///RemoteIntegral", integral);
    } catch(RemoteException re) {
      System.out.println("RemoteException: " + re);
    } catch(MalformedURLException mfe) {
      System.out.println("MalformedURLException: " + mfe);
    }
  }
}


RemoteIntegralClient2.java  An enterprise version of the client that imposes a security manager to support the Java 2 RMI 1.2 stub protocol. 

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

/** This class is a Java 2 version of RemoteIntegralClient
 *  that imposes a SecurityManager to allow the client to
 *  connect to a remote machine for loading stub files and
 *  performing numerical integration through a remote
 *  object.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class RemoteIntegralClient2 {
  public static void main(String[] args) {
    try {
      System.setSecurityManager(new RMISecurityManager());
      String host =
        (args.length > 0) ? args[0] : "localhost";
      RemoteIntegral remoteIntegral =
        (RemoteIntegral)Naming.lookup("rmi://" + host +
                                      "/RemoteIntegral");
      for(int steps=10; steps<=10000; steps*=10) {
        System.out.println
          ("Approximated with " + steps + " steps:" +
           "\n  Integral from 0 to pi of sin(x)=" +
           remoteIntegral.integrate(0.0, Math.PI,
                                    steps, new Sin()) +
           "\n  Integral from pi/2 to pi of cos(x)=" +
           remoteIntegral.integrate(Math.PI/2.0, Math.PI,
                                    steps, new Cos()) +
           "\n  Integral from 0 to 5 of x^2=" +
           remoteIntegral.integrate(0.0, 5.0, steps,
                                    new Quadratic()));
      }
      System.out.println
        ("`Correct' answer using Math library:" +
         "\n  Integral from 0 to pi of sin(x)=" +
         (-Math.cos(Math.PI) - -Math.cos(0.0)) +
         "\n  Integral from pi/2 to pi of cos(x)=" +
         (Math.sin(Math.PI) - Math.sin(Math.PI/2.0)) +
         "\n  Integral from 0 to 5 of x^2=" +
         (Math.pow(5.0, 3.0) / 3.0));
    } catch(RemoteException re) {
      System.out.println("RemoteException: " + re);
    } catch(NotBoundException nbe) {
      System.out.println("NotBoundException: " + nbe);
    } catch(MalformedURLException mfe) {
      System.out.println("MalformedURLException: " + mfe);
    }
  }
}

rmiclient.policy  Policy file for the client. Grants permissions for the client to connect to the RMI server and Web server. 

//  Taken from Core Web Programming from
//  Prentice Hall and Sun Microsystems Press,
//  .
//  © 2001 Marty Hall and Larry Brown;
//  may be freely used or adapted.

grant {
  // rmihost - RMI registry and the server
  // webhost - HTTP server for stub classes
  permission java.net.SocketPermission 
    "rmihost:1024-65535", "connect";
  permission java.net.SocketPermission 
    "webhost:80", "connect";
};

A JPanel that displays six radio buttons with labels.

A JPanel that displays six radio buttons with labels.

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

/** A JPanel that displays six JRadioButtons. 
 *
 *.
 */

public class SixChoicePanel extends JPanel {
  public SixChoicePanel(String title, String[] buttonLabels) {
    super(new GridLayout(3, 2));
    setBackground(Color.lightGray);
    setBorder(BorderFactory.createTitledBorder(title));
    ButtonGroup group = new ButtonGroup();
    JRadioButton option;
    int halfLength = buttonLabels.length/2;  // Assumes even length
    for(int i=0; i

ThreadedEchoServer.java A multithreaded version of EchoServer, where each client request is serviced on a separate thread. Requires the following classes

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

/** A multithreaded variation of EchoServer.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class ThreadedEchoServer extends EchoServer
                                implements Runnable {
  public static void main(String[] args) {
    int port = 8088;
    if (args.length > 0) {
      try {
        port = Integer.parseInt(args[0]);
      } catch(NumberFormatException nfe) {}
    }
    ThreadedEchoServer echoServer =
      new ThreadedEchoServer(port, 0);
    echoServer.serverName = "Threaded EchoServer";
  }

  public ThreadedEchoServer(int port, int connections) {
    super(port, connections);
  }

  /** The new version of handleConnection starts a thread. This
   *  new thread will call back to the old version of
   *  handleConnection, resulting in the same server behavior
   *  in a multithreaded version. The thread stores the Socket
   *  instance since run doesn't take any arguments, and since
   *  storing the socket in an instance variable risks having
   *  it overwritten if the next thread starts before the run
   *  method gets a chance to copy the socket reference.
   */

  public void handleConnection(Socket server) {
    Connection connectionThread = new Connection(this, server);
    connectionThread.start();
  }

  public void run() {
    Connection currentThread =
      (Connection)Thread.currentThread();
    try {
      super.handleConnection(currentThread.getSocket());
    } catch(IOException ioe) {
      System.out.println("IOException: " + ioe);
      ioe.printStackTrace();
    }
  }
}

/** This is just a Thread with a field to store a Socket object.
 *  Used as a thread-safe means to pass the Socket from
 *  handleConnection to run.
 */

class Connection extends Thread {
  private Socket serverSocket;

  public Connection(Runnable serverObject,
                    Socket serverSocket) {
    super(serverObject);
    this.serverSocket = serverSocket;
  }

  public Socket getSocket() {
    return serverSocket;
  }
}



EchoServer.java  Creates a Web page showing all data sent from the client (browser). 


import java.net.*;
import java.io.*;
import java.util.StringTokenizer;

/** A simple HTTP server that generates a Web page showing all
 *  of the data that it received from the Web client (usually
 *  a browser). To use this server, start it on the system of
 *  your choice, supplying a port number if you want something
 *  other than port 8088. Call this system server.com. Next,
 *  start a Web browser on the same or a different system, and
 *  connect to http://server.com:8088/whatever. The resultant
 *  Web page will show the data that your browser sent. For 
 *  debugging in servlet or CGI programming, specify 
 *  http://server.com:8088/whatever as the ACTION of your HTML
 *  form. You can send GET or POST data; either way, the
 *  resultant page will show what your browser sent.
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */

public class EchoServer extends NetworkServer {
  protected int maxRequestLines = 50;
  protected String serverName = "EchoServer";

  /** Supply a port number as a command-line
   *  argument. Otherwise, use port 8088.
   */
  
  public static void main(String[] args) {
    int port = 8088;
    if (args.length > 0) {
      try {
        port = Integer.parseInt(args[0]);
      } catch(NumberFormatException nfe) {}
    }
    new EchoServer(port, 0);
  }

  public EchoServer(int port, int maxConnections) {
    super(port, maxConnections);
    listen();
  }

  /** Overrides the NetworkServer handleConnection method to 
   *  read each line of data received, save it into an array
   *  of strings, then send it back embedded inside a PRE 
   *  element in an HTML page.
   */
  
  public void handleConnection(Socket server)
      throws IOException{
    System.out.println
        (serverName + ": got connection from " +
         server.getInetAddress().getHostName());
    BufferedReader in = SocketUtil.getReader(server);
    PrintWriter out = SocketUtil.getWriter(server);
    String[] inputLines = new String[maxRequestLines];
    int i;
    for (i=0; i\n" +
       "\n" +
       "\n" +
       "  \n" +
       "\n" +
       "\n" +
       "\n" +
       "
" + serverName +
         " Results
\n" +
       "Here is the request line and request headers\n" +
       "sent by your browser:\n" +
       "

");
  }

  // Print bottom of a standard Web page.
  
  private void printTrailer(PrintWriter out) {
    out.println
      ("

\n" +
       "\n" +
       "\n");
  }

  // Normal Web page requests use GET, so this server can simply
  // read a line at a time. However, HTML forms can also use 
  // POST, in which case we have to determine the number of POST
  // bytes that are sent so we know how much extra data to read
  // after the standard HTTP headers.
  
  private boolean usingPost(String[] inputs) {
    return(inputs[0].toUpperCase().startsWith("POST"));
  }

  private void readPostData(String[] inputs, int i,
                            BufferedReader in)
      throws IOException {
    int contentLength = contentLength(inputs);
    char[] postData = new char[contentLength];
    in.read(postData, 0, contentLength);
    inputs[++i] = new String(postData, 0, contentLength);
  }

  // Given a line that starts with Content-Length,
  // this returns the integer value specified.
  
  private int contentLength(String[] inputs) {
    String input;
    for (int i=0; iOverride this method in servers
   *  you write.
   *  


   *  This generic version simply reports the host that made
   *  the connection, shows the first line the client sent,
   *  and sends a single line in response.
   */

  protected void handleConnection(Socket server)
      throws IOException{
    BufferedReader in = SocketUtil.getReader(server);
    PrintWriter out = SocketUtil.getWriter(server);
    System.out.println
      ("Generic Network Server: got connection from " +
       server.getInetAddress().getHostName() + "\n" +
       "with first line '" + in.readLine() + "'");
    out.println("Generic Network Server");
    server.close();
  }

  /** Gets the max connections server will handle before
   *  exiting. A value of 0 indicates that server should run
   *  until explicitly killed.
   */

  public int getMaxConnections() {
    return(maxConnections);
  }

  /** Sets max connections. A value of 0 indicates that server
   *  should run indefinitely (until explicitly killed).
   */

  public void setMaxConnections(int maxConnections) {
    this.maxConnections = maxConnections;
  }

  /** Gets port on which server is listening. */

  public int getPort() {
    return(port);
  }

  /** Sets port. You can only do before "connect" is
   *  called. That usually happens in the constructor.
   */

  protected void setPort(int port) {
    this.port = port;
  }
}


SocketUtil.java  Simplifies the creation of a PrintWriter and BufferedReader.

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

/** A shorthand way to create BufferedReaders and
 *  PrintWriters associated with a Socket.
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */

public class SocketUtil {
  /** Make a BufferedReader to get incoming data. */

  public static BufferedReader getReader(Socket s)
      throws IOException {
    return(new BufferedReader(
       new InputStreamReader(s.getInputStream())));
  }

  /** Make a PrintWriter to send outgoing data.
   *  This PrintWriter will automatically flush stream
   *  when println is called.
   */

  public static PrintWriter getWriter(Socket s)
      throws IOException {
    // Second argument of true means autoflush.
    return(new PrintWriter(s.getOutputStream(), true));
  }
}

Implementing a Server : Network Server

NetworkServerTest.java  Establishes a network Server that listens for client requests on the port specified (command-line argument). Uses the following classes:

 

/** Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */


public class NetworkServerTest {
  public static void main(String[] args) {
    int port = 8088;
    if (args.length > 0) {
      port = Integer.parseInt(args[0]);
    }
    NetworkServer nwServer = new NetworkServer(port, 1);
    nwServer.listen();
  }
}


# NetworkServer.java  A starting point for network servers. 

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

/** A starting point for network servers. You'll need to
 *  override handleConnection, but in many cases listen can
 *  remain unchanged. NetworkServer uses SocketUtil to simplify
 *  the creation of the PrintWriter and BufferedReader.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class NetworkServer {
  private int port, maxConnections;

  /** Build a server on specified port. It will continue to
   *  accept connections, passing each to handleConnection until
   *  an explicit exit command is sent (e.g., System.exit) or
   *  the maximum number of connections is reached. Specify
   *  0 for maxConnections if you want the server to run
   *  indefinitely.
   */

  public NetworkServer(int port, int maxConnections) {
    setPort(port);
    setMaxConnections(maxConnections);
  }

  /** Monitor a port for connections. Each time one is
   *  established, pass resulting Socket to handleConnection.
   */

  public void listen() {
    int i=0;
    try {
      ServerSocket listener = new ServerSocket(port);
      Socket server;
      while((i++ < maxConnections) || (maxConnections == 0)) {
        server = listener.accept();
        handleConnection(server);
      }
    } catch (IOException ioe) {
      System.out.println("IOException: " + ioe);
      ioe.printStackTrace();
    }
  }

  /** This is the method that provides the behavior to the
   *  server, since it determines what is done with the
   *  resulting socket. Override this method in servers
   *  you write.
   *  


   *  This generic version simply reports the host that made
   *  the connection, shows the first line the client sent,
   *  and sends a single line in response.
   */

  protected void handleConnection(Socket server)
      throws IOException{
    BufferedReader in = SocketUtil.getReader(server);
    PrintWriter out = SocketUtil.getWriter(server);
    System.out.println
      ("Generic Network Server: got connection from " +
       server.getInetAddress().getHostName() + "\n" +
       "with first line '" + in.readLine() + "'");
    out.println("Generic Network Server");
    server.close();
  }

  /** Gets the max connections server will handle before
   *  exiting. A value of 0 indicates that server should run
   *  until explicitly killed.
   */

  public int getMaxConnections() {
    return(maxConnections);
  }

  /** Sets max connections. A value of 0 indicates that server
   *  should run indefinitely (until explicitly killed).
   */

  public void setMaxConnections(int maxConnections) {
    this.maxConnections = maxConnections;
  }

  /** Gets port on which server is listening. */

  public int getPort() {
    return(port);
  }

  /** Sets port. You can only do before "connect" is
   *  called. That usually happens in the constructor.
   */

  protected void setPort(int port) {
    this.port = port;
  }
}

SocketUtil.java  Simplifies the creation of a PrintWriter and BufferedReader.


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

/** A shorthand way to create BufferedReaders and
 *  PrintWriters associated with a Socket.
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */

public class SocketUtil {
  /** Make a BufferedReader to get incoming data. */

  public static BufferedReader getReader(Socket s)
      throws IOException {
    return(new BufferedReader(
       new InputStreamReader(s.getInputStream())));
  }

  /** Make a PrintWriter to send outgoing data.
   *  This PrintWriter will automatically flush stream
   *  when println is called.
   */

  public static PrintWriter getWriter(Socket s)
      throws IOException {
    // Second argument of true means autoflush.
    return(new PrintWriter(s.getOutputStream(), true));
  }
}

UrlTest.java Demonstrates the ease in which the various components of an URL can be determined (host, port, protocol, etc.)

জা
import java.net.*;

/** Read a URL from the command line, then print
 *  the various components.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class UrlTest {
  public static void main(String[] args) {
    if (args.length == 1) {
      try {
        URL url = new URL(args[0]);
        System.out.println
          ("URL: " + url.toExternalForm() + "\n" +
           "  File:      " + url.getFile() + "\n" +
           "  Host:      " + url.getHost() + "\n" +
           "  Port:      " + url.getPort() + "\n" +
           "  Protocol:  " + url.getProtocol() + "\n" +
           "  Reference: " + url.getRef());
      } catch(MalformedURLException mue) {
        System.out.println("Bad URL.");
      }
    } else
      System.out.println("Usage: UrlTest ");
  }
}

Counter2Test.java Driver class that creates three threaded objects (Counter2) that count from 0 to 4.

/** Try out a few instances of the Counter2 class. 

Driver class that creates three threaded objects (Counter2) that count from 0 to 4. In this case, 
the driver does not start the threads, as each thread is automatically started in Counter2's 
constructor. Uses the following class:

Counter2Test.java
Counter2.java
**************************    
public class Counter2Test {
  public static void main(String[] args) {
    Counter2 c1 = new Counter2(5);
    Counter2 c2 = new Counter2(5);
    Counter2 c3 = new Counter2(5);
  }
}

* Counter2.java A Runnable  that counts to a specified value and sleeps a random number of seconds 
in between counts. Here, the thread is started automatically when the object is instantiated.
/** A Runnable that counts up to a specified
 *  limit with random pauses in between each count.
 
public class Counter2 implements Runnable {
  private static int totalNum = 0;
  private int currentNum, loopLimit;

  public Counter2(int loopLimit) {
    this.loopLimit = loopLimit;
    currentNum = totalNum++;
    Thread t = new Thread(this);
    t.start();
  }

  private void pause(double seconds) {
    try { Thread.sleep(Math.round(1000.0*seconds)); }
    catch(InterruptedException ie) {}
  }
  
  public void run() {
    for(int i=0; i

Template illustrating the first approach for creating a class with thread behavior.

** Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
  *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class ThreadClass extends Thread {
 public void run() {
   // Thread behavior here.
  }
}

Creates three radio buttons and illustrates handling

JRadioButtonTest.java Creates three radio buttons and illustrates handling ItemEvents in response to selecting a radio button. 
import javax.swing.JRadioButton;
import javax.swing.ButtonGroup;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/** 
 */

public class JRadioButtonTest extends JPanel
                              implements ItemListener {

  public JRadioButtonTest() {
   
    String[] labels = {"Java Swing","Java Servlets",
                       "JavaServer Pages"};
    JRadioButton[] buttons = new JRadioButton[3];
    ButtonGroup group = new  ButtonGroup();

    for(int i=0; i

Simple button that the user can select to load the entered URL.

JIconButton.java A simple button that the user can select to load the entered URL. 
import javax.swing.*;

/** A regular JButton created with an ImageIcon and with borders
 *  and content areas turned off.
 *
  */

public class JIconButton extends JButton {
  public JIconButton(String file) {
    super(new ImageIcon(file));
    setContentAreaFilled(false);
    setBorderPainted(false);
    setFocusPainted(false);
  }
}

A simple button that contains an image and a label for use in a toolbar

ToolBarButton.java A simple button that contains an image and a label for use in a toolbar. 
import java.awt.*;
import javax.swing.*;

/** Part of a small example showing basic use of JToolBar.
 *  The point here is that dropping a regular JButton in a
 *  JToolBar (or adding an Action) in JDK 1.2 doesn't give 
 *  you what you want -- namely, a small button just enclosing
 *  the icon, and with text labels (if any) below the icon,
 *  not to the right of it. In JDK 1.3, if you add an Action
 *  to the toolbar, the Action label is no longer displayed.
 *
  */

public class ToolBarButton extends JButton {
  private static final Insets margins =
    new Insets(0, 0, 0, 0);

  public ToolBarButton(Icon icon) {
    super(icon);
    setMargin(margins);
    setVerticalTextPosition(BOTTOM);
    setHorizontalTextPosition(CENTER);
  }

  public ToolBarButton(String imageFile) {
    this(new ImageIcon(imageFile));
  }

  public ToolBarButton(String imageFile, String text) {
    this(new ImageIcon(imageFile));
    setText(text);
  }
}

Demonstrates the use of a JColorChooser which presents a dialog with three different tabbed panes to allow the user to select a color preference

Demonstrates the use of a JColorChooser which presents a dialog with three different tabbed panes to allow the user to select a color preference. The dialog returns a Color object based on the user's selection or null if the user entered Cancel.

 

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

/** Simple example illustrating the use of internal frames. 
 *
 *   */

public class JInternalFrames extends JFrame {
  public static void main(String[] args) {
    new JInternalFrames();
  }

  public JInternalFrames() {
    super("Multiple Document Interface");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    content.setBackground(Color.white);
    JDesktopPane desktop = new JDesktopPane();
    desktop.setBackground(Color.white);
    content.add(desktop, BorderLayout.CENTER);
    setSize(450, 400);
    for(int i=0; i<5; i++) {
      JInternalFrame frame
        = new JInternalFrame(("Internal Frame " + i),
                             true, true, true, true);
      frame.setLocation(i*50+10, i*50+10);
      frame.setSize(200, 150);
      frame.setBackground(Color.white);
      frame.setVisible(true);
      desktop.add(frame);
      frame.moveToFront();
    }
    setVisible(true);
  }
}

Creates various buttons. In Swing

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

/** Simple example illustrating the use of JButton, especially
 *  the new constructors that permit you to add an image.
 *
  */

public class JButtons extends JFrame {
  public static void main(String[] args) {
    new JButtons();
  }

  public JButtons() {
    super("Using JButton");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    content.setBackground(Color.white);
    content.setLayout(new FlowLayout());
    JButton button1 = new JButton("Java");
    content.add(button1);
    ImageIcon cup = new ImageIcon("images/cup.gif");
    JButton button2 = new JButton(cup);
    content.add(button2);
    JButton button3 = new JButton("Java", cup);
    content.add(button3);
    JButton button4 = new JButton("Java", cup);
    button4.setHorizontalTextPosition(SwingConstants.LEFT);
    content.add(button4);
    pack();
    setVisible(true);
  }
}

Multithreaded Graphics and Double Buffering

ShipSimulation.java  Illustrates the basic approach of multithreaded graphics whereas a thread adjusts parameters affecting the appearance of the graphics and then calls repaint to schedule an update of the display.

 

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

public class ShipSimulation extends Applet implements Runnable {
  ...
  
  public void run() {
    Ship s;
    for(int i=0; i
   *  When the "stop" button is pressed, stop the thread and
   *  clear the Vector of circles.
   */

  public void actionPerformed(ActionEvent event) {
    if (event.getSource() == startButton) {
      if (circles.size() == 0) {
        // Erase any circles from previous run.
        getGraphics().clearRect(0, 0, getSize().width,
                                      getSize().height);
        animationThread = new Thread(this);
        animationThread.start();
      }
      int radius = 25;
      int x = radius + randomInt(width - 2 * radius);
      int y = radius + randomInt(height - 2 * radius);
      int deltaX = 1 + randomInt(10);
      int deltaY = 1 + randomInt(10);
      circles.addElement(new MovingCircle(x, y, radius, deltaX,
                                          deltaY));
    } else if (event.getSource() == stopButton) {
      if (animationThread != null) {
        animationThread = null;
        circles.removeAllElements();
      }
    }
    repaint();
  }

  /** Each time around the loop, call paint and then take a
   *  short pause. The paint method will move the circles and
   *  draw them.
   */

  public void run() {
    Thread myThread = Thread.currentThread();
    // Really while animationThread not null
    while(animationThread==myThread) {
      repaint();
      pause(100);
    }
  }

  /** Skip the usual screen-clearing step of update so that
   *  there is no flicker between each drawing step.
   */

  public void update(Graphics g) {
    paint(g);
  }

  /** Erase each circle's old position, move it, then draw it
   *  in new location.
   */

  public void paint(Graphics g) {
    MovingCircle circle;
    for(int i=0; i windowWidth) && (deltaX > 0)) {
      setDeltaX(-deltaX);
    }
    if ((y -radius < 0) && (deltaY < 0)) {
      setDeltaY(-deltaY);
    } else if((y + radius > windowHeight) && (deltaY > 0)) {
      setDeltaY(-deltaY);
    }
  }

  public int getDeltaX() {
    return(deltaX);
  }

  public void setDeltaX(int deltaX) {
    this.deltaX = deltaX;
  }

  public int getDeltaY() {
    return(deltaY);
  }

  public void setDeltaY(int deltaY) {
    this.deltaY = deltaY;
  }
}
*//
SimpleCircle.java A class to store the x, y, and radius of a circle. Also, provides a draw method to paint the circle on the graphics object.
import java.awt.*;

/** A class to store an x, y, and radius, plus a draw method.
 *
  */

public class SimpleCircle {
  private int x, y, radius;

  public SimpleCircle(int x, int y, int radius) {
    setX(x);
    setY(y);
    setRadius(radius);
  }

  /** Given a Graphics, draw the SimpleCircle
   *  centered around its current position.
   */

  public void draw(Graphics g) {
    g.fillOval(x - radius, y - radius,
               radius * 2, radius * 2);
  }

  public int getX() { return(x); }

  public void setX(int x) { this.x = x; }

  public int getY() { return(y); }

  public void setY(int y) { this.y = y; }

  public int getRadius() { return(radius); }

  public void setRadius(int radius) {
    this.radius = radius;
  }
}
*//
DoubleBufferBounce.java  An enhancement to the previous applet containing bouncing circles. In this case, double buffering is used to improve the animation; all incremental updating is done in an off-screen image and then the image is drawn to the screen.
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;

/** Bounce circles around on the screen, using double buffering
 *  for speed and to avoid problems with overlapping circles.
 *  Overrides update to avoid flicker problems.
 *
  */

public class DoubleBufferBounce extends Applet implements
                                      Runnable, ActionListener {
  private Vector circles;
  private int width, height;
  private Image offScreenImage;
  private Graphics offScreenGraphics;
  private Button startButton, stopButton;
  private Thread animationThread = null;

  public void init() {
    setBackground(Color.white);
    width = getSize().width;
    height = getSize().height;
    offScreenImage = createImage(width, height);
    offScreenGraphics = offScreenImage.getGraphics();
    // Automatic in some systems, not in others.
    offScreenGraphics.setColor(Color.black);
    circles = new Vector();
    startButton = new Button("Start a circle");
    startButton.addActionListener(this);
    add(startButton);
    stopButton = new Button("Stop all circles");
    stopButton.addActionListener(this);
    add(stopButton);
  }

  /** When the "start" button is pressed, start the animation
   *  thread if it is not already started. Either way, add a
   *  circle to the Vector of circles that are being bounced.
   *  


   *  When the "stop" button is pressed, stop the thread and
   *  clear the Vector of circles.
   */

  public void actionPerformed(ActionEvent event) {
    if (event.getSource() == startButton) {
      if (circles.size() == 0) {
        animationThread = new Thread(this);
        animationThread.start();
      }
      int radius = 25;
      int x = radius + randomInt(width - 2 * radius);
      int y = radius + randomInt(height - 2 * radius);
      int deltaX = 1 + randomInt(10);
      int deltaY = 1 + randomInt(10);
      circles.addElement(new MovingCircle(x, y, radius, deltaX,
                                          deltaY));
      repaint();
    } else if (event.getSource() == stopButton) {
      if (animationThread != null) {
        animationThread = null;
        circles.removeAllElements();
      }
    }
  }

  /** Each time around the loop, move each circle based on its
   *  current position and deltaX/deltaY values. These values
   *  reverse when the circles reach the edge of the window.
   */

  public void run() {
    MovingCircle circle;
    Thread myThread = Thread.currentThread();
    // Really while animationThread not null.
    while(animationThread==myThread) {
      for(int j=0; j= NUMIMAGES) {
        index = 0;
      }

      parent.repaint();

      try {
        Thread.sleep(100);
      } catch (InterruptedException e) {
        break;   // Break while loop.
      }
    }
  }
}
*//
TimedAnimation.java An applet that demonstrates animation of an image by using a Timer. Note that Timer is located in the javax.swing package.
import java.awt.*;
import javax.swing.*;

/** An example of performing animation through Swing timers.
 *  Two timed Dukes are created with different timer periods.
 *
  */

public class TimedAnimation extends JApplet {
  private static final int NUMDUKES = 2;
  private TimedDuke[] dukes;
  private int i, index;

  public void init() {
    dukes = new TimedDuke[NUMDUKES];
    setBackground(Color.white);
    dukes[0] = new TimedDuke( 1, 100, this);
    dukes[1] = new TimedDuke(-1, 500, this);

  }

  //  Start each Duke timer.

  public void start() {
    for (int i=0; i= NUMIMAGES) {
      index = 0;
    }
    parent.repaint();
  }

  // Public service to start the timer.
  public void startTimer() {
    timer.start();
  }

  // Public service to stop the timer.
  public void stopTimer() {
    timer.stop();
  }
}
**//

Driver class that creates three threaded objects (Counter2) that count from 0 to 4.

/** Try out a few instances of the Counter2 class. 

public class Counter2Test {
  public static void main(String[] args) {
    Counter2 c1 = new Counter2(5);
    Counter2 c2 = new Counter2(5);
    Counter2 c3 = new Counter2(5);
  }
}

/** A Runnable that counts up to a specified
 *  limit with random pauses in between each count.
 
public class Counter2 implements Runnable {
  private static int totalNum = 0;
  private int currentNum, loopLimit;

  public Counter2(int loopLimit) {
    this.loopLimit = loopLimit;
    currentNum = totalNum++;
    Thread t = new Thread(this);
    t.start();
  }

  private void pause(double seconds) {
    try { Thread.sleep(Math.round(1000.0*seconds)); }
    catch(InterruptedException ie) {}
  }
  
  public void run() {
    for(int i=0; i

Template illustrating the second approach for creating a class with thread behavior.

Template illustrating the second approach for creating a class with thread behavior. In this case, the class implements the Runnable interface while providing a run method for thread execution.

public class ThreadedClass extends AnyClass implements Runnable {
  public void run() {
    // Thread behavior here.
  }

  public void startThread() {
    Thread t = new Thread(this);
    t.start(); // Calls back to the run method in "this."
  }

  ...
}

Creates and starts three threaded objects

Creates and starts three threaded objects which count from 0 to 4. Uses the following class:
CounterTest.java
Counter.java
/** Try out a few instances of the Counter class.
public class CounterTest {
public static void main(String[] args) {
Counter c1 = new Counter(5);
Counter c2 = new Counter(5);
Counter c3 = new Counter(5);
c1.start();
c2.start();
c3.start();
}
}

Counter.java:A class that inherits from Thread and defines a run method that counts up to a specified value, pausing for a random time interval in between

value counts.
/** A subclass of Thread that counts up to a specified
 *  limit with random pauses in between each count.
 
public class Counter extends Thread {
  private static int totalNum = 0;
  private int currentNum, loopLimit;

  public Counter(int loopLimit) {
    this.loopLimit = loopLimit;
    currentNum = totalNum++;
  }

  private void pause(double seconds) {
    try { Thread.sleep(Math.round(1000.0*seconds)); }
    catch(InterruptedException ie) {}
  }

  /** When run finishes, the thread exits. */
  
  public void run() {
    for(int i=0; i

DOM example that represents the basic structure of an XML document as a JTree

//XMLTree.java
//Uses the following files

Uses the following files:

    * XMLFrame.java:Swing application to select an XML document and display in a JTree.

ExtensionFileFilter.java Allows you to specify which file extensions will be displayed in a JFileChooser.

test.xml Default file loaded if none selected by user. 

perennials.xml and perennials.dtd Data on daylilies and corresponding DTD.

WindowUtilities.java  

ExitListener.java. 

//XMLTree.java as follows
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;

/** Given a filename or a name and an input stream,
 *  this class generates a JTree representing the
 *  XML structure contained in the file or stream.
 *  Parses with DOM then copies the tree structure
 *  (minus text and comment nodes).
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 *  
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */

public class XMLTree extends JTree {
  public XMLTree(String filename) throws IOException {
    this(filename, new FileInputStream(new File(filename)));
  }

  public XMLTree(String filename, InputStream in) {
    super(makeRootNode(in));
  }

  // This method needs to be static so that it can be called
  // from the call to the parent constructor (super), which
  // occurs before the object is really built.
  
  private static DefaultMutableTreeNode
                                 makeRootNode(InputStream in) {
    try {
      // Use JAXP's DocumentBuilderFactory so that there
      // is no code here that is dependent on a particular
      // DOM parser. Use the system property
      // javax.xml.parsers.DocumentBuilderFactory (set either
      // from Java code or by using the -D option to "java").
      // or jre_dir/lib/jaxp.properties to specify this.
      DocumentBuilderFactory builderFactory =
        DocumentBuilderFactory.newInstance();
      DocumentBuilder builder =
        builderFactory.newDocumentBuilder();
      // Standard DOM code from hereon. The "parse"
      // method invokes the parser and returns a fully parsed
      // Document object. We'll then recursively descend the
      // tree and copy non-text nodes into JTree nodes.
      Document document = builder.parse(in);
      document.getDocumentElement().normalize();
      Element rootElement = document.getDocumentElement();
      DefaultMutableTreeNode rootTreeNode =
        buildTree(rootElement);
      return(rootTreeNode);
    } catch(Exception e) {
      String errorMessage =
        "Error making root node: " + e;
      System.err.println(errorMessage);
      e.printStackTrace();
      return(new DefaultMutableTreeNode(errorMessage));
    }
  }

  private static DefaultMutableTreeNode
                              buildTree(Element rootElement) {
    // Make a JTree node for the root, then make JTree
    // nodes for each child and add them to the root node.
    // The addChildren method is recursive.
    DefaultMutableTreeNode rootTreeNode =
      new DefaultMutableTreeNode(treeNodeLabel(rootElement));
    addChildren(rootTreeNode, rootElement);
    return(rootTreeNode);
  }

  private static void addChildren
                       (DefaultMutableTreeNode parentTreeNode,
                        Node parentXMLElement) {
    // Recursive method that finds all the child elements
    // and adds them to the parent node. We have two types
    // of nodes here: the ones corresponding to the actual
    // XML structure and the entries of the graphical JTree.
    // The convention is that nodes corresponding to the
    // graphical JTree will have the word "tree" in the
    // variable name. Thus, "childElement" is the child XML
    // element whereas "childTreeNode" is the JTree element.
    // This method just copies the non-text and non-comment
    // nodes from the XML structure to the JTree structure.
    
    NodeList childElements =
      parentXMLElement.getChildNodes();
    for(int i=0; i
  // JTree Node:  blah
  // XML Element: 
  // JTree Node:  blah (foo=bar, baz=quux)

  private static String treeNodeLabel(Node childElement) {
    NamedNodeMap elementAttributes =
      childElement.getAttributes();
    String treeNodeLabel = childElement.getNodeName();
    if (elementAttributes != null &&
        elementAttributes.getLength() > 0) {
      treeNodeLabel = treeNodeLabel + " (";
      int numAttributes = elementAttributes.getLength();
      for(int i=0; i 0) {
          treeNodeLabel = treeNodeLabel + ", ";
        }
        treeNodeLabel =
          treeNodeLabel + attribute.getNodeName() +
          "=" + attribute.getNodeValue();
      }
      treeNodeLabel = treeNodeLabel + ")";
    }
    return(treeNodeLabel);
  }
}

XMLFrame.java Swing application to select an XML document and display in a JTree.

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

/** Invokes an XML parser on an XML document and displays
 *  the document in a JTree. Both the parser and the
 *  document can be specified by the user. The parser
 *  is specified by invoking the program with
 *  java -Djavax.xml.parsers.DocumentBuilderFactory=xxx XMLFrame
 *  If no parser is specified, the Apache Xerces parser is used.
 *  The XML document can be supplied on the command
 *  line, but if it is not given, a JFileChooser is used
 *  to interactively select the file of interest.
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */

public class XMLFrame extends JFrame {
  public static void main(String[] args) {
    String jaxpPropertyName =
      "javax.xml.parsers.DocumentBuilderFactory";
    // Pass the parser factory in on the command line with
    // -D to override the use of the Apache parser.
    if (System.getProperty(jaxpPropertyName) == null) {
      String apacheXercesPropertyValue =
        "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl";
      System.setProperty(jaxpPropertyName,
                         apacheXercesPropertyValue);
    }
    String filename;
    if (args.length > 0) {
      filename = args[0];
    } else {
      String[] extensions = { "xml", "tld" };
      WindowUtilities.setNativeLookAndFeel();
      filename = ExtensionFileFilter.getFileName(".",
                                                 "XML Files",
                                                 extensions);
      if (filename == null) {
        filename = "test.xml";
      }
    }
    new XMLFrame(filename);
  }

  public XMLFrame(String filename) {
    try {
      WindowUtilities.setNativeLookAndFeel();
      JTree tree = new XMLTree(filename);
      JFrame frame = new JFrame(filename);
      frame.addWindowListener(new ExitListener());
      Container content = frame.getContentPane();
      content.add(new JScrollPane(tree));
      frame.pack();
      frame.setVisible(true);
    } catch(IOException ioe) {
      System.out.println("Error creating tree: " + ioe);
    }
  }
}

ExtensionFileFilter.java Allows you to specify which file extensions will be displayed in a JFileChooser.

import java.io.File;
import java.util.*;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;

/** A FileFilter that lets you specify which file extensions 
 *  will be displayed. Also includes a static getFileName 
 *  method that users can call to pop up a JFileChooser for 
 *  a set of file extensions.
 *  


 *  Adapted from Sun SwingSet demo.
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */

public class ExtensionFileFilter extends FileFilter {
  public static final int LOAD = 0;
  public static final int SAVE = 1;
  private String description;
  private boolean allowDirectories;
  private Hashtable extensionsTable = new Hashtable();
  private boolean allowAll = false;

  public ExtensionFileFilter(boolean allowDirectories) {
    this.allowDirectories = allowDirectories;
  }

  public ExtensionFileFilter() {
    this(true);
  }
  
  
  public static String getFileName(String initialDirectory,
                                   String description,
                                   String extension) {
    String[] extensions = new String[]{ extension };
    return(getFileName(initialDirectory, description, 
                       extensions, LOAD));
  }  

  public static String getFileName(String initialDirectory,
                                   String description,
                                   String extension,
                                   int mode) {
    String[] extensions = new String[]{ extension };
    return(getFileName(initialDirectory, description, 
                       extensions, mode));
  }

  public static String getFileName(String initialDirectory,
                                   String description,
                                   String[] extensions) {
    return(getFileName(initialDirectory, description, 
                       extensions, LOAD));
  }


  /** Pops up a JFileChooser that lists files with the 
   *  specified extensions. If the mode is SAVE, then the 
   *  dialog will have a Save button; otherwise, the dialog 
   *  will have an Open button. Returns a String corresponding
   *  to the file's pathname, or null if Cancel was selected.
   */

  public static String getFileName(String initialDirectory,
                                   String description,
                                   String[] extensions,
                                   int mode) {
    ExtensionFileFilter filter = new ExtensionFileFilter();
    filter.setDescription(description);
    for(int i=0; i


WindowUtilities.java

import javax.swing.*;
import java.awt.*;   // For Color and Container classes.

/** A few utilities that simplify using windows in Swing. 
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 * 
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class WindowUtilities {

  /** Tell system to use native look and feel, as in previous
   *  releases. Metal (Java) LAF is the default otherwise.
   */

  public static void setNativeLookAndFeel() {
    try {
     UIManager.setLookAndFeel(
       UIManager.getSystemLookAndFeelClassName());
    } catch(Exception e) {
      System.out.println("Error setting native LAF: " + e);
    }
  }

  public static void setJavaLookAndFeel() {
    try {
     UIManager.setLookAndFeel(
       UIManager.getCrossPlatformLookAndFeelClassName());
    } catch(Exception e) {
      System.out.println("Error setting Java LAF: " + e);
    }
  }

   public static void setMotifLookAndFeel() {
    try {
      UIManager.setLookAndFeel(
        "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
    } catch(Exception e) {
      System.out.println("Error setting Motif LAF: " + e);
    }
  }

  /** A simplified way to see a JPanel or other Container. Pops
   *  up a JFrame with specified Container as the content pane.
   */

  public static JFrame openInJFrame(Container content,
                                    int width,
                                    int height,
                                    String title,
                                    Color bgColor) {
    JFrame frame = new JFrame(title);
    frame.setBackground(bgColor);
    content.setBackground(bgColor);
    frame.setSize(width, height);
    frame.setContentPane(content);
    frame.addWindowListener(new ExitListener());
    frame.setVisible(true);
    return(frame);
  }

  /** Uses Color.white as the background color. */

  public static JFrame openInJFrame(Container content,
                                    int width,
                                    int height,
                                    String title) {
    return(openInJFrame(content, width, height,
                        title, Color.white));
  }

  /** Uses Color.white as the background color, and the
   *  name of the Container's class as the JFrame title.
   */

  public static JFrame openInJFrame(Container content,
                                    int width,
                                    int height) {
    return(openInJFrame(content, width, height,
                        content.getClass().getName(),
                        Color.white));
  }
}



EXITListener.java

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

/** A listener that you attach to the top-level JFrame of
 *  your application, so that quitting the frame exits the 
 *  application.
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 *  
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */
public class ExitListener extends WindowAdapter {
  public void windowClosing(WindowEvent event) {
    System.exit(0);
  }
}

Simple example illustrating the use of check boxes

JCheckBoxTest.java Simple example illustrating the use of check boxes. 
import javax.swing.*; 
import java.awt.event.*;

 */

public class JCheckBoxTest extends JPanel 
                           implements ItemListener, 
                                      ActionListener{
  JCheckBox checkBox1, checkBox2;
   
  public JCheckBoxTest() {
    checkBox1 = new JCheckBox("Java Servlets");
    checkBox2 = new JCheckBox("JavaServer Pages");
    checkBox1.setContentAreaFilled(false);
    checkBox2.setContentAreaFilled(false);
   
    checkBox1.addItemListener(this);
    checkBox2.addActionListener(this);
      
    add(checkBox1);
    add(checkBox2);
  }
   
  public void actionPerformed(ActionEvent event) {
    System.out.println("JavaServer Pages selected: " + 
                        checkBox2.isSelected());
  }
   
  public void itemStateChanged(ItemEvent event) {
    JCheckBox checkbox = (JCheckBox)event.getItem();
      
    if (event.getStateChange() == ItemEvent.SELECTED) {
      System.out.println(checkbox.getText() + " selected.");
    } else {
      System.out.println(checkbox.getText() + " deselected.");
    }
  }  
   
  public static void main(String[] args) {
    JPanel panel = new JCheckBoxTest();
    WindowUtilities.setNativeLookAndFeel();
    WindowUtilities.openInJFrame(panel, 300, 75);
  }   
}

Basic tool bar for holding multiple buttons.

BrowserToolBar.java A basic tool bar for holding multiple buttons. 
import java.awt.*;
import javax.swing.*;

/** Part of a small example showing basic use of JToolBar.
 *  Creates a small dockable toolbar that is supposed to look
 *  vaguely like one that might come with a Web browser.
 *  Makes use of ToolBarButton, a small extension of JButton
 *  that shrinks the margins around the icon and puts text 
 *  label, if any, below the icon. 
 *
  */
 
public class BrowserToolBar extends JToolBar {
  public BrowserToolBar() { 
    String[] imageFiles =
      { "Left.gif", "Right.gif", "RotCCUp.gif",
        "TrafficRed.gif", "Home.gif", "Print.gif", "Help.gif" };
    String[] toolbarLabels =
      { "Back", "Forward", "Reload", "Stop", 
        "Home", "Print", "Help" };
    Insets margins = new Insets(0, 0, 0, 0);
    for(int i=0; i                               

Demonstrates the use of a JColorChooser which presents a dialog with three different tabbed panes to allow the user to select a color preference

Demonstrates the use of a JColorChooser which presents a dialog with three different tabbed panes to allow the user to select a color preference. The dialog returns a Color object based on the user's selection or null if the user entered Cancel.

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

/** Simple example illustrating the use of JColorChooser. 
 *
 *  .
 */

public class JColorChooserTest extends JFrame
                               implements ActionListener {
  public static void main(String[] args) {
    new JColorChooserTest();
  }

  public JColorChooserTest() {
    super("Using JColorChooser");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    content.setBackground(Color.white);
    content.setLayout(new FlowLayout());
    JButton colorButton
      = new JButton("Choose Background Color");
    colorButton.addActionListener(this);
    content.add(colorButton);
    setSize(300, 100);
    setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {
    // Args are parent component, title, initial color.
    Color bgColor
      = JColorChooser.showDialog(this,
                                 "Choose Background Color",
                                 getBackground());
    if (bgColor != null)
      getContentPane().setBackground(bgColor);
  }
}

WebClient – Client application that can talk interactively to Web servers. Requires the components listed below

import java.awt.*; // For BorderLayout, GridLayout, Font, Color.
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

/** A graphical client that lets you interactively connect to
 *  Web servers and send custom request lines and
 *  request headers.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class WebClient extends JPanel
    implements Runnable, Interruptible, ActionListener {
  public static void main(String[] args) {
    WindowUtilities.setNativeLookAndFeel();
    WindowUtilities.openInJFrame(new WebClient(), 600, 700,
                                 "Web Client",
                                 SystemColor.control);
  }

  private LabeledTextField hostField, portField,
          requestLineField;
  private JTextArea requestHeadersArea, resultArea;
  private String host, requestLine;
  private int port;
  private String[] requestHeaders = new String[30];
  private JButton submitButton, interruptButton;
  private boolean isInterrupted = false;

  public WebClient() {
    setLayout(new BorderLayout(5, 30));
    int fontSize = 14;
    Font labelFont =
      new Font("Serif", Font.BOLD, fontSize);
    Font headingFont =
      new Font("SansSerif", Font.BOLD, fontSize+4);
    Font textFont =
      new Font("Monospaced", Font.BOLD, fontSize-2);
    JPanel inputPanel = new JPanel();
    inputPanel.setLayout(new BorderLayout());
    JPanel labelPanel = new JPanel();
    labelPanel.setLayout(new GridLayout(4,1));
    hostField = new LabeledTextField("Host:", labelFont,
                                     30, textFont);
    portField = new LabeledTextField("Port:", labelFont,
                                     "80", 5, textFont);
    // Use HTTP 1.0 for compatibility with the most servers.
    // If you switch this to 1.1, you *must* supply a
    // Host: request header.
    requestLineField =
      new LabeledTextField("Request Line:", labelFont,
                           "GET / HTTP/1.0", 50, textFont);
    labelPanel.add(hostField);
    labelPanel.add(portField);
    labelPanel.add(requestLineField);
    JLabel requestHeadersLabel =
      new JLabel("Request Headers:");
    requestHeadersLabel.setFont(labelFont);
    labelPanel.add(requestHeadersLabel);
    inputPanel.add(labelPanel, BorderLayout.NORTH);
    requestHeadersArea = new JTextArea(5, 80);
    requestHeadersArea.setFont(textFont);
    JScrollPane headerScrollArea =
      new JScrollPane(requestHeadersArea);
    inputPanel.add(headerScrollArea, BorderLayout.CENTER);
    JPanel buttonPanel = new JPanel();
    submitButton = new JButton("Submit Request");
    submitButton.addActionListener(this);
    submitButton.setFont(labelFont);
    buttonPanel.add(submitButton);
    inputPanel.add(buttonPanel, BorderLayout.SOUTH);
    add(inputPanel, BorderLayout.NORTH);
    JPanel resultPanel = new JPanel();
    resultPanel.setLayout(new BorderLayout());
    JLabel resultLabel =
      new JLabel("Results", JLabel.CENTER);
    resultLabel.setFont(headingFont);
    resultPanel.add(resultLabel, BorderLayout.NORTH);
    resultArea = new JTextArea();
    resultArea.setFont(textFont);
    JScrollPane resultScrollArea =
      new JScrollPane(resultArea);
    resultPanel.add(resultScrollArea, BorderLayout.CENTER);
    JPanel interruptPanel = new JPanel();
    interruptButton = new JButton("Interrupt Download");
    interruptButton.addActionListener(this);
    interruptButton.setFont(labelFont);
    interruptPanel.add(interruptButton);
    resultPanel.add(interruptPanel, BorderLayout.SOUTH);
    add(resultPanel, BorderLayout.CENTER);
  }

  public void actionPerformed(ActionEvent event) {
    if (event.getSource() == submitButton) {
      Thread downloader = new Thread(this);
      downloader.start();
    } else if (event.getSource() == interruptButton) {
      isInterrupted = true;
    }
  }

  public void run() {
    isInterrupted = false;
    if (hasLegalArgs())
      new HttpClient(host, port, requestLine,
             requestHeaders, resultArea, this);
  }

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

  private boolean hasLegalArgs() {
    host = hostField.getTextField().getText();
    if (host.length() == 0) {
      report("Missing hostname");
      return(false);
    }
    String portString =
      portField.getTextField().getText();
    if (portString.length() == 0) {
      report("Missing port number");
      return(false);
    }
    try {
      port = Integer.parseInt(portString);
    } catch(NumberFormatException nfe) {
      report("Illegal port number: " + portString);
      return(false);
    }
    requestLine =
      requestLineField.getTextField().getText();
    if (requestLine.length() == 0) {
      report("Missing request line");
      return(false);
    }
    getRequestHeaders();
    return(true);
  }

  private void report(String s) {
    resultArea.setText(s);
  }

  private void getRequestHeaders() {
    for(int i=0; i
   *    LabeledTextField ltf = new LabeledTextField(...);
   *    ltf.getLabel().someLabelMethod(...);
   *

*/ public JLabel getLabel() { return(label); } /** The TextField at the right side of the * LabeledTextField. */ public JTextField getTextField() { return(textField); } } Interruptible.java Polls to see if the user choose to interrupt the current network download. /** An interface for classes that can be polled to see * if they've been interrupted. Used by HttpClient * and WebClient to allow the user to interrupt a network * download. * * Taken from Core Web Programming from * Prentice Hall and Sun Microsystems Press, * . * © 2001 Marty Hall and Larry Brown; * may be freely used or adapted. */ public interface Interruptible { public boolean isInterrupted(); } NetworkClient.java Starting point for a network client to communicate with a remote computer. import java.net.*; import java.io.*; /** A starting point for network clients. You'll need to * override handleConnection, but in many cases connect can * remain unchanged. It uses SocketUtil to simplify the * creation of the PrintWriter and BufferedReader. * * Taken from Core Web Programming from * Prentice Hall and Sun Microsystems Press, * © 2001 Marty Hall and Larry Brown; * may be freely used or adapted. */ public class NetworkClient { protected String host; protected int port; /** Register host and port. The connection won't * actually be established until you call * connect. */ public NetworkClient(String host, int port) { this.host = host; this.port = port; } /** Establishes the connection, then passes the socket * to handleConnection. */ public void connect() { try { Socket client = new Socket(host, port); handleConnection(client); } catch(UnknownHostException uhe) { System.out.println("Unknown host: " + host); uhe.printStackTrace(); } catch(IOException ioe) { System.out.println("IOException: " + ioe); ioe.printStackTrace(); } } /** This is the method you will override when * making a network client for your task. * The default version sends a single line * ("Generic Network Client") to the server, * reads one line of response, prints it, then exits. */ protected void handleConnection(Socket client) throws IOException { PrintWriter out = SocketUtil.getWriter(client); BufferedReader in = SocketUtil.getReader(client); out.println("Generic Network Client"); System.out.println ("Generic Network Client:\n" + "Made connection to " + host + " and got '" + in.readLine() + "' in response"); client.close(); } /** The hostname of the server we're contacting. */ public String getHost() { return(host); } /** The port connection will be made on. */ public int getPort() { return(port); } } SocketUtil.java: Provides utilities for wrapping a BufferedReader and PrintWriter around the Socket's input and output streams, respectively. import java.net.*; import java.io.*; /** A shorthand way to create BufferedReaders and * PrintWriters associated with a Socket. * * Taken from Core Web Programming from * Prentice Hall and Sun Microsystems Press, * . * © 2001 Marty Hall and Larry Brown; * may be freely used or adapted. */ public class SocketUtil { /** Make a BufferedReader to get incoming data. */ public static BufferedReader getReader(Socket s) throws IOException { return(new BufferedReader( new InputStreamReader(s.getInputStream()))); } /** Make a PrintWriter to send outgoing data. * This PrintWriter will automatically flush stream * when println is called. */ public static PrintWriter getWriter(Socket s) throws IOException { // Second argument of true means autoflush. return(new PrintWriter(s.getOutputStream(), true)); } } WindowUtilities.java Simplifies the setting of native look and feel. import javax.swing.*; import java.awt.*; // For Color and Container classes. /** A few utilities that simplify using windows in Swing. * * Taken from Core Web Programming from * Prentice Hall and Sun Microsystems Press, * © 2001 Marty Hall and Larry Brown; * may be freely used or adapted. */ public class WindowUtilities { /** Tell system to use native look and feel, as in previous * releases. Metal (Java) LAF is the default otherwise. */ public static void setNativeLookAndFeel() { try { UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch(Exception e) { System.out.println("Error setting native LAF: " + e); } } public static void setJavaLookAndFeel() { try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName()); } catch(Exception e) { System.out.println("Error setting Java LAF: " + e); } } public static void setMotifLookAndFeel() { try { UIManager.setLookAndFeel( "com.sun.java.swing.plaf.motif.MotifLookAndFeel"); } catch(Exception e) { System.out.println("Error setting Motif LAF: " + e); } } /** A simplified way to see a JPanel or other Container. Pops * up a JFrame with specified Container as the content pane. */ public static JFrame openInJFrame(Container content, int width, int height, String title, Color bgColor) { JFrame frame = new JFrame(title); frame.setBackground(bgColor); content.setBackground(bgColor); frame.setSize(width, height); frame.setContentPane(content); frame.addWindowListener(new ExitListener()); frame.setVisible(true); return(frame); } /** Uses Color.white as the background color. */ public static JFrame openInJFrame(Container content, int width, int height, String title) { return(openInJFrame(content, width, height, title, Color.white)); } /** Uses Color.white as the background color, and the * name of the Container's class as the JFrame title. */ public static JFrame openInJFrame(Container content, int width, int height) { return(openInJFrame(content, width, height, content.getClass().getName(), Color.white)); } } ExitListener.java WindowListener for applications in this chapter. import java.awt.*; import java.awt.event.*; /** A listener that you attach to the top-level JFrame of * your application, so that quitting the frame exits the * application. * * Taken from Core Web Programming from * Prentice Hall and Sun Microsystems Press, * © 2001 Marty Hall and Larry Brown; * may be freely used or adapted. */ public class ExitListener extends WindowAdapter { public void windowClosing(WindowEvent event) { System.exit(0); } }

EchoServer.java A simple HTTP server that creates a Web page showing all data sent from the client (browser), including all HTTP request headers sent form the client. Uses the following classes

EchoServer.java  A simple HTTP server that creates a Web page showing all data sent from the client (browser), including all HTTP request headers sent form the client. Uses the following classes:

 

import java.net.*;
import java.io.*;
import java.util.StringTokenizer;

/** A simple HTTP server that generates a Web page showing all
 *  of the data that it received from the Web client (usually
 *  a browser). To use this server, start it on the system of
 *  your choice, supplying a port number if you want something
 *  other than port 8088. Call this system server.com. Next,
 *  start a Web browser on the same or a different system, and
 *  connect to http://server.com:8088/whatever. The resultant
 *  Web page will show the data that your browser sent. For
 *  debugging in servlet or CGI programming, specify
 *  http://server.com:8088/whatever as the ACTION of your HTML
 *  form. You can send GET or POST data; either way, the
 *  resultant page will show what your browser sent.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class EchoServer extends NetworkServer {
  protected int maxRequestLines = 50;
  protected String serverName = "EchoServer";

  /** Supply a port number as a command-line
   *  argument. Otherwise, use port 8088.
   */

  public static void main(String[] args) {
    int port = 8088;
    if (args.length > 0) {
      try {
        port = Integer.parseInt(args[0]);
      } catch(NumberFormatException nfe) {}
    }
    new EchoServer(port, 0);
  }

  public EchoServer(int port, int maxConnections) {
    super(port, maxConnections);
    listen();
  }

  /** Overrides the NetworkServer handleConnection method to
   *  read each line of data received, save it into an array
   *  of strings, then send it back embedded inside a PRE
   *  element in an HTML page.
   */

  public void handleConnection(Socket server)
      throws IOException{
    System.out.println
        (serverName + ": got connection from " +
         server.getInetAddress().getHostName());
    BufferedReader in = SocketUtil.getReader(server);
    PrintWriter out = SocketUtil.getWriter(server);
    String[] inputLines = new String[maxRequestLines];
    int i;
    for (i=0; i\n" +
       "\n" +
       "\n" +
       "  \n" +
       "\n" +
       "\n" +
       "\n" +
       "
" + serverName +
         " Results
\n" +
       "Here is the request line and request headers\n" +
       "sent by your browser:\n" +
       "

");
  }

  // Print bottom of a standard Web page.

  private void printTrailer(PrintWriter out) {
    out.println
      ("

\n" +
       "\n" +
       "\n");
  }

  // Normal Web page requests use GET, so this server can simply
  // read a line at a time. However, HTML forms can also use
  // POST, in which case we have to determine the number of POST
  // bytes that are sent so we know how much extra data to read
  // after the standard HTTP headers.

  private boolean usingPost(String[] inputs) {
    return(inputs[0].toUpperCase().startsWith("POST"));
  }

  private void readPostData(String[] inputs, int i,
                            BufferedReader in)
      throws IOException {
    int contentLength = contentLength(inputs);
    char[] postData = new char[contentLength];
    in.read(postData, 0, contentLength);
    inputs[++i] = new String(postData, 0, contentLength);
  }

  // Given a line that starts with Content-Length,
  // this returns the integer value specified.

  private int contentLength(String[] inputs) {
    String input;
    for (int i=0; iOverride this method in servers
   *  you write.
   *  


   *  This generic version simply reports the host that made
   *  the connection, shows the first line the client sent,
   *  and sends a single line in response.
   */

  protected void handleConnection(Socket server)
      throws IOException{
    BufferedReader in = SocketUtil.getReader(server);
    PrintWriter out = SocketUtil.getWriter(server);
    System.out.println
      ("Generic Network Server: got connection from " +
       server.getInetAddress().getHostName() + "\n" +
       "with first line '" + in.readLine() + "'");
    out.println("Generic Network Server");
    server.close();
  }

  /** Gets the max connections server will handle before
   *  exiting. A value of 0 indicates that server should run
   *  until explicitly killed.
   */

  public int getMaxConnections() {
    return(maxConnections);
  }

  /** Sets max connections. A value of 0 indicates that server
   *  should run indefinitely (until explicitly killed).
   */

  public void setMaxConnections(int maxConnections) {
    this.maxConnections = maxConnections;
  }

  /** Gets port on which server is listening. */

  public int getPort() {
    return(port);
  }

  /** Sets port. You can only do before "connect" is
   *  called. That usually happens in the constructor.
   */

  protected void setPort(int port) {
    this.port = port;
  }
}


SocketUtil.java  Simplifies the creation of a PrintWriter and BufferedReader.

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

/** A shorthand way to create BufferedReaders and
 *  PrintWriters associated with a Socket.
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */

public class SocketUtil {
  /** Make a BufferedReader to get incoming data. */

  public static BufferedReader getReader(Socket s)
      throws IOException {
    return(new BufferedReader(
       new InputStreamReader(s.getInputStream())));
  }

  /** Make a PrintWriter to send outgoing data.
   *  This PrintWriter will automatically flush stream
   *  when println is called.
   */

  public static PrintWriter getWriter(Socket s)
      throws IOException {
    // Second argument of true means autoflush.
    return(new PrintWriter(s.getOutputStream(), true));
  }
}

StoppableThread.java A template to place a thread in a RUN, WAIT, or STOP state.

/** A template to control the state of a thread through setting
 *  an internal flag.

public class StoppableThread extends Thread {

   public static final int STOP    = 0;
   public static final int RUN     = 1;
   public static final int WAIT    = 2;
   private int state = RUN;

  /** Public method to permit setting a flag to stop or
   *  suspend the thread.  The state is monitored through the
   *  corresponding checkState method.
   */

   public synchronized void setState(int state) {
      this.state = state;
      if (state==RUN) {
         notify();
      }
   }

  /** Returns the desired state of the thread (RUN, STOP, WAIT).
   *  Normally, you may want to change the state or perform some
   *  other task if an InterruptedException occurs.
   */

   private synchronized int checkState() {
      while (state==WAIT) {
        try {
          wait();
        } catch (InterruptedException e) { }
      }
      return state;
   }

  /** An example of thread that will continue to run until
   *  the creating object tells the thread to STOP.
   */

   public void run() {
      while (checkState()!=STOP) {
         ...
      }
   }
}

mall example showing the basic use of a JToolBar

mall example showing the basic use of a JToolBar

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

/** Small example showing basic use of JToolBar. 
 *
 * 
 */

public class JToolBarExample extends JFrame
                             implements ItemListener {
  private BrowserToolBar toolbar;
  private JCheckBox labelBox;

  public static void main(String[] args) {
    new JToolBarExample();
  }

  public JToolBarExample() {
    super("JToolBar Example");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    content.setBackground(Color.white);
    
    JPanel panel = new JPanel(new BorderLayout());
    labelBox = new JCheckBox("Show Text Labels?");
    labelBox.setHorizontalAlignment(SwingConstants.CENTER);
    labelBox.addItemListener(this);
    panel.add(new JTextArea(10,30), BorderLayout.CENTER);
    panel.add(labelBox, BorderLayout.SOUTH);

    toolbar = new BrowserToolBar();
    content.add(toolbar, BorderLayout.NORTH);
    content.add(panel, BorderLayout.CENTER);

    pack();
    setVisible(true);
  }

  public void itemStateChanged(ItemEvent event) {
    toolbar.setTextLabels(labelBox.isSelected());
    pack();
  }
}

UrlRetriever2.java Illustrates how the URL class can simplify communication to an HTTP server.

UrlRetriever2.java  Illustrates how the URL class can simplify communication to an HTTP server.

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

/** Read a remote file using the standard URL class
 *  instead of connecting explicitly to the HTTP server.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class UrlRetriever2 {
  public static void main(String[] args) {
    checkUsage(args);
    try {
      URL url = new URL(args[0]);
      BufferedReader in = new BufferedReader(
        new InputStreamReader(url.openStream()));
      String line;
      while ((line = in.readLine()) != null) {
        System.out.println("> " + line);
     }
      in.close();
    } catch(MalformedURLException mue) { // URL constructor
        System.out.println(args[0] + "is an invalid URL: " + mue);
    } catch(IOException ioe) { // Stream constructors
      System.out.println("IOException: " + ioe);
    }
  }

  private static void checkUsage(String[] args) {
    if (args.length != 1) {
      System.out.println("Usage: UrlRetriever2 ");
      System.exit(-1);
    }
  }
}

RMI Example – Message, illustrates retrieving a message from an object located on a remote server. Requires the following classes

Rem.java  Establishes which methods the client can access in the remote object. 





import java.rmi.*;

/** The RMI client will use this interface directly. The RMI
 *  server will make a real remote object that implements this,
 *  then register an instance of it with some URL.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public interface Rem extends Remote {
  public String getMessage() throws RemoteException;
}


RemClient.java  The client application which communicates to the remote object and retrieves the message. 

import java.rmi.*; // For Naming, RemoteException, etc.
import java.net.*; // For MalformedURLException
import java.io.*;  // For Serializable interface

/** Get a Rem object from the specified remote host.
 *  Use its methods as though it were a local object.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class RemClient {
  public static void main(String[] args) {
    try {
      String host =
        (args.length > 0) ? args[0] : "localhost";
      // Get the remote object and store it in remObject:
      Rem remObject =
        (Rem)Naming.lookup("rmi://" + host + "/Rem");
      // Call methods in remObject:
      System.out.println(remObject.getMessage());
    } catch(RemoteException re) {
      System.out.println("RemoteException: " + re);
    } catch(NotBoundException nbe) {
      System.out.println("NotBoundException: " + nbe);
    } catch(MalformedURLException mfe) {
      System.out.println("MalformedURLException: " + mfe);
    }
  }
}


RemImpl.java  The concrete, remote object that implements the methods in Rem.java. 

import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

/** This is the actual implementation of Rem that the RMI
 *  server uses. The server builds an instance of this, then
 *  registers it with a URL. The client accesses the URL and
 *  binds the result to a Rem (not a RemImpl; it doesn't
 *  have this).
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class RemImpl extends UnicastRemoteObject
                     implements Rem {
  public RemImpl() throws RemoteException {}

  public String getMessage() throws RemoteException {
    return("Here is a remote message.");
  }
}


RemServer.java  Creates an instance of RemImpl on the remote server and binds the object in the registry for lookup by the client. 

import java.rmi.*;
import java.net.*;

/** The server creates a RemImpl (which implements the Rem
 *  interface), then registers it with the URL Rem, where
 *  clients can access it.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class RemServer {
  public static void main(String[] args) {
    try {
      RemImpl localObject = new RemImpl();
      Naming.rebind("rmi:///Rem", localObject);
    } catch(RemoteException re) {
      System.out.println("RemoteException: " + re);
    } catch(MalformedURLException mfe) {
      System.out.println("MalformedURLException: " + mfe);
    }
  }
}

Creates three common types of sliders

Creates three common types of sliders: one without tick marks, one with tick marks, and one with both tick marks and labels. 

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

/** Simple example illustrating the use of JSliders, especially
 *  the ability to specify tick marks and labels.
 *
 *   
 */

public class JSliders extends JFrame {
  public static void main(String[] args) {
    new JSliders();
  }

  public JSliders() {
    super("Using JSlider");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    Container content = getContentPane();
    content.setBackground(Color.white);
    
    JSlider slider1 = new JSlider();
    slider1.setBorder(BorderFactory.createTitledBorder
                        ("JSlider without Tick Marks"));
    content.add(slider1, BorderLayout.NORTH);
    
    JSlider slider2 = new JSlider();
    slider2.setBorder(BorderFactory.createTitledBorder
                        ("JSlider with Tick Marks"));
    slider2.setMajorTickSpacing(20);
    slider2.setMinorTickSpacing(5);
    slider2.setPaintTicks(true);
    content.add(slider2, BorderLayout.CENTER);

    JSlider slider3 = new JSlider();
    slider3.setBorder(BorderFactory.createTitledBorder
                        ("JSlider with Tick Marks & Labels"));
    slider3.setMajorTickSpacing(20);
    slider3.setMinorTickSpacing(5);
    slider3.setPaintTicks(true);
    slider3.setPaintLabels(true);
    content.add(slider3, BorderLayout.SOUTH);
    
    pack();
    setVisible(true);
  }
}

Basic Swing Details

  • WindowUtilities.java Utility class that simplifies creating a window and setting the look and feel.
  • ExitListener.java A WindowListener with support to close the window.
  • JAppletExample.java A simple applet (JApplet) created in Swing. Illustrates setting the look and feel, adding components to the content pane, and changing the layout to FlowLayout (default is BorderLayout). See JAppletExample.html (requires the Java Plug-In or a Java 2 compliant browser, for example, Netscape 6.x).
  • JFrameExample.java Demonstrates creating a simple Swing application using a JFrame. As with a JApplet, components must be added to the content pane, instead of the window directly.
  • JLabels.java Illustrates creating labels in Swing. A nice feature of JLabels is that the label text can contain HTML markup. Uses image JHUAPL.gif
  • JButtons.java Creates various buttons. In Swing, buttons can contain text only, an image only, or a combination of both an image and a label. Uses image cup.gif.
  • JPanels.java A simple example that illustrates creating panels. In Swing, a JPanel can contain custom borders. Typically, utility methods in the BorderFactory class are used to create a border for the panel. Uses the following class:
    o SixChoicePanel.java A JPanel that displays six radio buttons with labels.
  • JSliders.java Creates three common types of sliders: one without tick marks, one with tick marks, and one with both tick marks and labels.
  • JColorChooserTest.java Demonstrates the use of a JColorChooser which presents a dialog with three different tabbed panes to allow the user to select a color preference. The dialog returns a Color object based on the user's selection or null if the user entered Cancel.
  • JInternalFrames.java Illustrates the ability to create a Multiple Document Interface (MDI) application by placing internal frames (JInternalFrame) in a desktop pane (JDesktopPane).
  • JToolBarExample.java Small example showing the basic use of a JToolBar. Uses the following classes and images:
    o ToolBarButton.java A simple button that contains an image and a label for use in a toolbar.
    o BrowserToolBar.java A basic tool bar for holding multiple buttons.
    o Images used in the toolbar buttons: Help.gif, Home.gif, Left.gif, Print.gif, Right.gif, RotCCUp.gif, TrafficRed.gif.
  • Browser.java Implementation of a simple browser in Swing. The user can specify a URL to load into the browser (JEditorPane). By attaching an HyperlinkListener, the editor pane is responsive to hyperlinks selected by the user. Uses the following class and image:
    o JIconButton.java A simple button that the user can select to load the entered URL.
    o home.gif Image used in the button.
  • JCheckBoxTest.java Simple example illustrating the use of check boxes.
  • JRadioButtonTest.java Creates three radio buttons and illustrates handling ItemEvents in response to selecting a radio button.
  • JOptionPaneExamples.java Creates various modal dialogs to show messages. Uses the follwoing classes:
    o JLabeledTextField.java A simple JPanel that combines a JLabel and a JTextField.
    o RadioButtonPanel.java Groups several radio buttons in a single row, with a label on the left.
    o DisableListener.java A listener that toggles the enabled status of some other component.

UrlRetriever.java Accepts an URL from the command line, parses the host, port, and URI components from the URL and then retrieves the document. Requires the following classes

UrlRetriever.java  Accepts an URL from the command line, parses the host, port, and URI components from the URL and then retrieves the document. Requires the following classes: 


import java.util.*;

/** This parses the input to get a host, port, and file, then
 *  passes these three values to the UriRetriever class to
 *  grab the URL from the Web.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class UrlRetriever {
  public static void main(String[] args) {
    checkUsage(args);
    StringTokenizer tok = new StringTokenizer(args[0]);
    String protocol = tok.nextToken(":");
    checkProtocol(protocol);
    String host = tok.nextToken(":/");
    String uri;
    int port = 80;
    try {
      uri = tok.nextToken("");
      if (uri.charAt(0) == ':') {
        tok = new StringTokenizer(uri);
        port = Integer.parseInt(tok.nextToken(":/"));
        uri = tok.nextToken("");
      }
    } catch(NoSuchElementException nsee) {
      uri = "/";
    }
    UriRetriever uriClient = new UriRetriever(host, port, uri);
    uriClient.connect();
  }

  /** Warn user if the URL was forgotten. */

  private static void checkUsage(String[] args) {
    if (args.length != 1) {
      System.out.println("Usage: UrlRetriever ");
      System.exit(-1);
    }
  }

  /** Tell user that this can only handle HTTP. */

  private static void checkProtocol(String protocol) {
    if (!protocol.equals("http")) {
      System.out.println("Don't understand protocol " + protocol);
      System.exit(-1);
    }
  }
}




UriRetriever.java  Given a host, port, and URI, retrieves the document from the HTTP server. 

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

/** Retrieve a URL given the host, port, and file as three 
 *  separate command-line arguments. A later class 
 *  (UrlRetriever) supports a single URL instead.
 *
 *  Taken from Core Web Programming from 
 *  Prentice Hall and Sun Microsystems Press,
 
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted. 
 */

public class UriRetriever extends NetworkClient {
  private String uri;

  public static void main(String[] args) {
    UriRetriever uriClient
      = new UriRetriever(args[0], Integer.parseInt(args[1]),
                         args[2]);
    uriClient.connect();
  }

  public UriRetriever(String host, int port, String uri) {
    super(host, port); 
    this.uri = uri;
  }

  /** Send one GET line, then read the results one line at a
   *  time, printing each to standard output.
   */

  // It is safe to use blocking IO (readLine), since
  // HTTP servers close connection when done, resulting
  // in a null value for readLine.
  
  protected void handleConnection(Socket uriSocket)
      throws IOException {
    PrintWriter out = SocketUtil.getWriter(uriSocket);
    BufferedReader in = SocketUtil.getReader(uriSocket);
    out.println("GET " + uri + " HTTP/1.0\r\n");
    String line;
    while ((line = in.readLine()) != null) {
      System.out.println("> " + line);
    }
  }
}





NetworkClient.java

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

/** A starting point for network clients. You'll need to
 *  override handleConnection, but in many cases connect can
 *  remain unchanged. It uses SocketUtil to simplify the
 *  creation of the PrintWriter and BufferedReader.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class NetworkClient {
  protected String host;
  protected int port;

  /** Register host and port. The connection won't
   *  actually be established until you call
   *  connect.
   */

  public NetworkClient(String host, int port) {
    this.host = host;
    this.port = port;
  }

  /** Establishes the connection, then passes the socket
   *  to handleConnection.
   */

  public void connect() {
    try {
      Socket client = new Socket(host, port);
      handleConnection(client);
    } catch(UnknownHostException uhe) {
      System.out.println("Unknown host: " + host);
      uhe.printStackTrace();
    } catch(IOException ioe) {
      System.out.println("IOException: " + ioe);
      ioe.printStackTrace();
    }
  }

  /** This is the method you will override when
   *  making a network client for your task.
   *  The default version sends a single line
   *  ("Generic Network Client") to the server,
   *  reads one line of response, prints it, then exits.
   */

  protected void handleConnection(Socket client)
    throws IOException {
    PrintWriter out = SocketUtil.getWriter(client);
    BufferedReader in = SocketUtil.getReader(client);
    out.println("Generic Network Client");
    System.out.println
      ("Generic Network Client:\n" +
       "Made connection to " + host +
       " and got '" + in.readLine() + "' in response");
    client.close();
  }

  /** The hostname of the server we're contacting. */

  public String getHost() {
    return(host);
  }

  /** The port connection will be made on. */

  public int getPort() {
    return(port);
  }
}

SocketUtil.java  Provides utilities for wrapping a BufferedReader  and PrintWriter around the Socket's input and output streams, respectively. 

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

/** A shorthand way to create BufferedReaders and
 *  PrintWriters associated with a Socket.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class SocketUtil {
  /** Make a BufferedReader to get incoming data. */

  public static BufferedReader getReader(Socket s)
      throws IOException {
    return(new BufferedReader(
       new InputStreamReader(s.getInputStream())));
  }

  /** Make a PrintWriter to send outgoing data.
   *  This PrintWriter will automatically flush stream
   *  when println is called.
   */

  public static PrintWriter getWriter(Socket s)
      throws IOException {
    // Second argument of true means autoflush.
    return(new PrintWriter(s.getOutputStream(), true));
  }
}

AddressVerifier.java Connects to an SMTP server and issues a expn request to display details about a mailbox on the server. Uses the following classes

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

/** Given an e-mail address of the form user@host,
 *  connect to port 25 of the host and issue an
 *  'expn' request for the user. Print the results.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class AddressVerifier extends NetworkClient {
  private String username;

  public static void main(String[] args) {
    if (args.length != 1) {
      usage();
   }
    MailAddress address = new MailAddress(args[0]);
    AddressVerifier verifier
      = new AddressVerifier(address.getUsername(),
                            address.getHostname(), 25);
    verifier.connect();
  }

  public AddressVerifier(String username, String hostname,
                         int port) {
    super(hostname, port);
    this.username = username;
  }

  /** NetworkClient, the parent class, automatically establishes
   *  the connection and then passes the Socket to
   *  handleConnection. This method does all the real work
   *  of talking to the mail server.
   */

  // You can't use readLine, because it blocks. Blocking I/O
  // by readLine is only appropriate when you know how many
  // lines to read. Note that mail servers send a varying
  // number of lines when you first connect or send no line
  // closing the connection (as HTTP servers do), yielding
  // null for readLine. Also, we'll assume that 1000 bytes
  // is more than enough to handle any server welcome
  // message and the actual EXPN response.

  protected void handleConnection(Socket client) {
    try {
      PrintWriter out = SocketUtil.getWriter(client);
      InputStream in = client.getInputStream();
      byte[] response = new byte[1000];
      // Clear out mail server's welcome message.
      in.read(response);
      out.println("EXPN " + username);
      // Read the response to the EXPN command.
      int numBytes = in.read(response);
      // The 0 means to use normal ASCII encoding.
      System.out.write(response, 0, numBytes);
      out.println("QUIT");
      client.close();
    } catch(IOException ioe) {
      System.out.println("Couldn't make connection: " + ioe);
    }
  }

  /** If the wrong arguments, thn warn user. */

  public static void usage() {
    System.out.println ("You must supply an email address " +
       "of the form 'username@hostname'.");
    System.exit(-1);
  }
}


MailAddress.java  Separates the user and host components of an email address. 

import java.util.*;

/** Takes a string of the form "user@host" and
 *  separates it into the "user" and "host" parts.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class MailAddress {
  private String username, hostname;

  public MailAddress(String emailAddress) {
    StringTokenizer tokenizer
      = new StringTokenizer(emailAddress, "@");
    this.username = getArg(tokenizer);
    this.hostname = getArg(tokenizer);
  }

  private static String getArg(StringTokenizer tok) {
    try { return(tok.nextToken()); }
    catch (NoSuchElementException nsee) {
      System.out.println("Illegal email address");
      System.exit(-1);
      return(null);
    }
  }

  public String getUsername() {
    return(username);
  }

  public String getHostname() {
    return(hostname);
  }
}


NetworkClient.java  Starting point for a network client to communicate with a remote computer.

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

/** A starting point for network clients. You'll need to
 *  override handleConnection, but in many cases connect can
 *  remain unchanged. It uses SocketUtil to simplify the
 *  creation of the PrintWriter and BufferedReader.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class NetworkClient {
  protected String host;
  protected int port;

  /** Register host and port. The connection won't
   *  actually be established until you call
   *  connect.
   */

  public NetworkClient(String host, int port) {
    this.host = host;
    this.port = port;
  }

  /** Establishes the connection, then passes the socket
   *  to handleConnection.
   */

  public void connect() {
    try {
      Socket client = new Socket(host, port);
      handleConnection(client);
    } catch(UnknownHostException uhe) {
      System.out.println("Unknown host: " + host);
      uhe.printStackTrace();
    } catch(IOException ioe) {
      System.out.println("IOException: " + ioe);
      ioe.printStackTrace();
    }
  }

  /** This is the method you will override when
   *  making a network client for your task.
   *  The default version sends a single line
   *  ("Generic Network Client") to the server,
   *  reads one line of response, prints it, then exits.
   */

  protected void handleConnection(Socket client)
    throws IOException {
    PrintWriter out = SocketUtil.getWriter(client);
    BufferedReader in = SocketUtil.getReader(client);
    out.println("Generic Network Client");
    System.out.println
      ("Generic Network Client:\n" +
       "Made connection to " + host +
       " and got '" + in.readLine() + "' in response");
    client.close();
  }

  /** The hostname of the server we're contacting. */

  public String getHost() {
    return(host);
  }

  /** The port connection will be made on. */

  public int getPort() {
    return(port);
  }
}


SocketUtil.java  Provides utilities for wrapping a BufferedReader  and PrintWriter around the Socket's input and output streams, respectively. 

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

/** A shorthand way to create BufferedReaders and
 *  PrintWriters associated with a Socket.
 *
 *  Taken from Core Web Programming from
 *  Prentice Hall and Sun Microsystems Press,
 *  .
 *  © 2001 Marty Hall and Larry Brown;
 *  may be freely used or adapted.
 */

public class SocketUtil {
  /** Make a BufferedReader to get incoming data. */

  public static BufferedReader getReader(Socket s)
      throws IOException {
    return(new BufferedReader(
       new InputStreamReader(s.getInputStream())));
  }

  /** Make a PrintWriter to send outgoing data.
   *  This PrintWriter will automatically flush stream
   *  when println is called.
   */

  public static PrintWriter getWriter(Socket s)
      throws IOException {
    // Second argument of true means autoflush.
    return(new PrintWriter(s.getOutputStream(), true));
  }
}

Buggy Counter Applet.java Demonstrates that data shared by multiple threads is candidate for a potential race condition

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

/** Emulates the Counter and Counter2 classes, but this time
 *  from an applet that invokes multiple versions of its own run
 *  method. This version is likely to work correctly
 *  except when  an important customer is visiting.

public class BuggyCounterApplet extends Applet
                                implements Runnable{
  private int totalNum = 0;
  private int loopLimit = 5;

  // Start method of applet, not the start method of the thread. 
  // The applet start method is called by the browser after init is
  // called. 
  public void start() {
    Thread t;
    for(int i=0; i<3; i++) {
      t = new Thread(this);
      t.start();
    }
  }

  private void pause(double seconds) {
    try { Thread.sleep(Math.round(1000.0*seconds)); }
    catch(InterruptedException ie) {}
  }

  public void run() {
    int currentNum = totalNum;
    System.out.println("Setting currentNum to " + currentNum);
    totalNum = totalNum + 1;
    for(int i=0; i

SplitTest.java Illustrates parsing a string with a String.split

SplitTest.java  Illustrates parsing a string with a String.split


/** Prints the tokens resulting from treating the first
 *  command-line argument as the string to be tokenized
 *  and the second as the delimiter set. Uses
 *  String.split instead of StringTokenizer.
 */

public class SplitTest {
  public static void main(String[] args) {
    if (args.length == 2) {
      String input = args[0], delimiters = args[1];
      String[] tokens = args[0].split(delimiters);
      for(int i=0; i<tokens.length; i++)="" {="" string="" token="tokens[i];" if="" (token.length()="" !="0)" 
      system.out.println(token);="" }="" else="" system.out.println="" ("usage:="" java="" splittest="" 
      delimeters");="" <="" pre="">