Tag Archives: code

CheckboxGroups

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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.

Huge Sell on Popular Electronics

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.

Huge Sell on Popular Electronics

**************
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

Huge Sell on Popular Electronics

# 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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Message.java Applet that reads customization parameters from an HTML file

Huge Sell on Popular Electronics

*******************
Message.java Applet that reads customization parameters from an HTML file
*******************
import java.applet.Applet;
import java.awt.*;

****************
 
public class Message extends Applet {
  private int fontSize;
  private String message;
  
  public void init() {
    setBackground(Color.black);
    setForeground(Color.white);
    
    // Base font size on window height.
    fontSize = getSize().height - 10;
    
    setFont(new Font("SansSerif", Font.BOLD, fontSize));

    // Read heading message from PARAM entry in HTML.
    message = getParameter("MESSAGE");
  }

  public void paint(Graphics g) {
    if (message != null) {
      g.drawString(message, 5, fontSize+5);
    }
  }
}
*******************

Accesses methods in a Ship2 object

Huge Sell on Popular Electronics

*********************************************
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

Huge Sell on Popular Electronics

###############
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.

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

######################
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

Huge Sell on Popular Electronics

#################
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

Huge Sell on Popular Electronics

#######################
# 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

Huge Sell on Popular Electronics

# 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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

******************
# 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.

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

/./././././././././.
// 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.

Huge Sell on Popular Electronics

>>>>>>>>>>>>>>>>>
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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

/././././././
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

Huge Sell on Popular Electronics

# 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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

   *
          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

Huge Sell on Popular Electronics

**********************
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.

Huge Sell on Popular Electronics

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.

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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.)

Huge Sell on Popular Electronics

জা
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.

Huge Sell on Popular Electronics

/** 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.

Huge Sell on Popular Electronics

** 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

Huge Sell on Popular Electronics

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.

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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.

Huge Sell on Popular Electronics

/** 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.

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

//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

Huge Sell on Popular Electronics

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.

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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.

Huge Sell on Popular Electronics

/** 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

Huge Sell on Popular Electronics

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.

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

  • 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.

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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

Huge Sell on Popular Electronics

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="">

TokTest.java Illustrates parsing a string with a StringTokenizer.

Huge Sell on Popular Electronics

TokTest.java  Illustrates parsing a string with a StringTokenizer. 

import java.util.StringTokenizer;

/** Prints the tokens resulting from treating the first
 *  command-line argument as the string to be tokenized
 *  and the second as the delimiter set.
 *
 *  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 TokTest {
  public static void main(String[] args) {
    if (args.length == 2) {
      String input = args[0], delimiters = args[1];
      StringTokenizer tok =
        new StringTokenizer(input, delimiters);
      while (tok.hasMoreTokens()) {
        System.out.println(tok.nextToken());
      }
    } else {
      System.out.println
        ("Usage: java TokTest string delimeters");
    }
  }
}

NetworkClientTest.java Makes a simple connection to the host and port specified on the command line. Uses the following classes

Huge Sell on Popular Electronics

NetworkClientTest.java  Makes a simple connection to the host and port specified on the command line. Uses the following classes:

/** Make simple connection to host and port specified.
 *
 *  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 NetworkClientTest {
  public static void main(String[] args) {
    String host = "localhost";
    int port = 8088;
    if (args.length > 0) {
      host = args[0];
    }
    if (args.length > 1) {
      port = Integer.parseInt(args[1]);
    }
    NetworkClient nwClient = new NetworkClient(host, port);
    nwClient.connect();
  }
}



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 around the Socket's input stream and a PrintWriter  around the Socket's output stream

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

ShowSession.java Servlet that uses session tracking to determine if the client is a repeat visitor. Uses the ServletUtilities class to simplify the DOCTYPE and HEAD output.

Huge Sell on Popular Electronics

ShowSession.java  Servlet that uses session tracking to determine if the client is a repeat visitor. Uses the ServletUtilities  class to simplify the DOCTYPE and HEAD output.


package cwp;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.net.*;
import java.util.*;

/** Simple example of session tracking.
 *

* Taken from Core Web Programming Java 2 Edition * from Prentice Hall and Sun Microsystems Press, * . * May be freely used or adapted. */ public class ShowSession extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Session Tracking Example"; HttpSession session = request.getSession(true); String heading; Integer accessCount = (Integer)session.getAttribute("accessCount"); if (accessCount == null) { accessCount = new Integer(0); heading = "Welcome, Newcomer"; } else { heading = "Welcome Back"; accessCount = new Integer(accessCount.intValue() + 1); } // Use setAttribute instead of putValue in version 2.2. session.setAttribute("accessCount", accessCount); out.println(ServletUtilities.headWithTitle(title) + "\n" + "

" + heading + "

\n" +
                "

Information on Your Session:

\n" +
                "\n" +
                "\n" +
                "  \n" +
                "  \n" +
                "  \n" +
                "  \n" +
                "
Info Type Value\n" + "
ID\n" + " " + session.getId() + "\n" + "
Creation Time\n" + " " + new Date(session.getCreationTime()) + "\n" + "
Time of Last Access\n" + " " + new Date(session.getLastAccessedTime()) + "\n" + "
Number of Previous Accesses\n" + " " + accessCount + "\n" + "
\n" +
                "");

  }

  /** Handle GET and POST requests identically. */

  public void doPost(HttpServletRequest request,
                     HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}

LongLivedCookie.java Subclass of Cookie that automatically sets the max age to one year.

Huge Sell on Popular Electronics

LongLivedCookie.java  Subclass of Cookie that automatically sets the max age to one year. 

package cwp;

import javax.servlet.http.*;

/** Cookie that persists 1 year. Default Cookie doesn't
 *  persist past current session.
 *  


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

public class LongLivedCookie extends Cookie {
  public static final int SECONDS_PER_YEAR = 60*60*24*365;

  public LongLivedCookie(String name, String value) {
    super(name, value);
    setMaxAge(SECONDS_PER_YEAR);
  }
}


SearchEngines.java Servlet that redirects requests to various search engines. Uses the SearchSpec helper class. Accessed by means of SearchEngines.html.

Huge Sell on Popular Electronics

SearchEngines.java  Servlet that redirects requests to various search engines. Uses the SearchSpec  helper class. Accessed by means of SearchEngines.html. 

package cwp;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.net.*;

/** Servlet that takes a search string, number of results per
 *  page, and a search engine name, sending the query to
 *  that search engine. Illustrates manipulating
 *  the response status line. It sends a 302 response
 *  (via sendRedirect) if it gets a known search engine,
 *  and sends a 404 response (via sendError) otherwise.
 *  


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

public class SearchEngines extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    String searchString = request.getParameter("searchString");
    if ((searchString == null) ||
        (searchString.length() == 0)) {
      reportProblem(response, "Missing search string.");
      return;
    }
    // The URLEncoder changes spaces to "+" signs and other
    // non-alphanumeric characters to "%XY", where XY is the
    // hex value of the ASCII (or ISO Latin-1) character.
    // Browsers always URL-encode form values, so the
    // getParameter method decodes automatically. But since
    // we're just passing this on to another server, we need to
    // re-encode it.
    searchString = URLEncoder.encode(searchString);
    String numResults = request.getParameter("numResults");
    if ((numResults == null) ||
        (numResults.equals("0")) ||
        (numResults.length() == 0)) {
      numResults = "10";
    }
    String searchEngine =
      request.getParameter("searchEngine");
    if (searchEngine == null) {
      reportProblem(response, "Missing search engine name.");
      return;
    }
    SearchSpec[] commonSpecs = SearchSpec.getCommonSpecs();
    for(int i=0; i" + message + "");
  }

  public void doPost(HttpServletRequest request,
                     HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}



SearchSpec.java

package cwp;

/** Small class that encapsulates how to construct a
 *  search string for a particular search engine.
 *  


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

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

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

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

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

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

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

SetCookies.java Servlet that sets a few persistent and session cookies. Uses the ServletUtilities class to simplify the DOCTYPE and HEAD output.

Huge Sell on Popular Electronics

SetCookies.java  Servlet that sets a few persistent and session cookies. Uses the ServletUtilities  class to simplify the DOCTYPE and HEAD output.

 

package cwp;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/** Sets six cookies: three that apply only to the current
 *  session (regardless of how long that session lasts)
 *  and three that persist for an hour (regardless of
 *  whether the browser is restarted).
 *  


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

public class SetCookies extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    for(int i=0; i<3; i++) {
      // Default maxAge is -1, indicating cookie
      // applies only to current browsing session.
      Cookie cookie = new Cookie("Session-Cookie-" + i,
                                 "Cookie-Value-S" + i);
      response.addCookie(cookie);
      cookie = new Cookie("Persistent-Cookie-" + i,
                          "Cookie-Value-P" + i);
      // Cookie is valid for an hour, regardless of whether
      // user quits browser, reboots computer, or whatever.
      cookie.setMaxAge(3600);
      response.addCookie(cookie);
    }
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String title = "Setting Cookies";
    out.println
      (ServletUtilities.headWithTitle(title) +
       "\n" +
       "
" + title + "
\n" +
       "There are six cookies associated with this page.\n" +
       "To see them, visit the\n" +
       "\n" +
       "ShowCookies servlet.\n" +
       "

\n" +
       "Three of the cookies are associated only with the\n" +
       "current session, while three are persistent.\n" +
       "Quit the browser, restart, and return to the\n" +
       "ShowCookies servlet to verify that\n" +
       "the three long-lived ones persist across sessions.\n" +
       "");
  }
}



ServletUtilities.java

package cwp;

import javax.servlet.*;
import javax.servlet.http.*;

/** Some simple time savers. Note that most are static methods.
 *  


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

public class ServletUtilities {
  public static final String DOCTYPE =
    "";

  public static String headWithTitle(String title) {
    return(DOCTYPE + "\n" +
           "\n" +
           "\n");
  }

  /** Read a parameter with the specified name, convert it
   *  to an int, and return it. Return the designated default
   *  value if the parameter doesn't exist or if it is an
   *  illegal integer format.
  */

  public static int getIntParameter(HttpServletRequest request,
                                    String paramName,
                                    int defaultValue) {
    String paramString = request.getParameter(paramName);
    int paramValue;
    try {
      paramValue = Integer.parseInt(paramString);
    } catch(NumberFormatException nfe) { // null or bad format
      paramValue = defaultValue;
    }
    return(paramValue);
  }

  /** Given an array of Cookies, a name, and a default value,
   *  this method tries to find the value of the cookie with
   *  the given name. If there is no cookie matching the name
   *  in the array, then the default value is returned instead.
   */

  public static String getCookieValue(Cookie[] cookies,
                                      String cookieName,
                                      String defaultValue) {
    if (cookies != null) {
      for(int i=0; i' with
   *  '>', and (to handle cases that occur inside attribute
   *  values), all occurrences of double quotes with
   *  '"' and all occurrences of '&' with '&'.
   *  Without such filtering, an arbitrary string
   *  could not safely be inserted in a Web page.
   */

  public static String filter(String input) {
    StringBuffer filtered = new StringBuffer(input.length());
    char c;
    for(int i=0; i') {
        filtered.append(">");
      } else if (c == '"') {
        filtered.append(""");
      } else if (c == '&') {
        filtered.append("&");
      } else {
        filtered.append(c);
      }
    }
    return(filtered.toString());
  }
}

EncodedPage.java Servlet that shows the bandwidth benefits of gzipping pages to browsers that can handle gzip. Uses the ServletUtilities class to simplify the DOCTYPE and HEAD output.

Huge Sell on Popular Electronics

EncodedPage.java  Servlet that shows the bandwidth benefits of gzipping pages to browsers that can handle gzip. Uses the ServletUtilities  class to simplify the DOCTYPE and HEAD output. 

package cwp;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.zip.*;

/** Example showing benefits of gzipping pages to browsers
 *  that can handle gzip.
 *  


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

public class EncodedPage extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/html");
    String encodings = request.getHeader("Accept-Encoding");
    String encodeFlag = request.getParameter("encoding");
    PrintWriter out;
    String title;
    if ((encodings != null) &&
        (encodings.indexOf("gzip") != -1) &&
        !"none".equals(encodeFlag)) {
      title = "Page Encoded with GZip";
      OutputStream out1 = response.getOutputStream();
      out = new PrintWriter(new GZIPOutputStream(out1), false);
      response.setHeader("Content-Encoding", "gzip");
    } else {
      title = "Unencoded Page";
      out = response.getWriter();
    }
    out.println(ServletUtilities.headWithTitle(title) +
                "\n" +
                "
" + title + "
\n");
    String line = "Blah, blah, blah, blah, blah. " +
                  "Yadda, yadda, yadda, yadda.";
    for(int i=0; i<10000; i++) {
      out.println(line);
    }
    out.println("");
    out.close();
  }
}

PrimeNumbers.java Servlet that processes a request to generate n prime numbers, each with at least m digits. If these results are not complete, it sends a Refresh header instructing the browser to ask for new results a little while later. Uses the Primes

Huge Sell on Popular Electronics

PrimeNumbers.java  Servlet that processes a request to generate n prime numbers, each with at least m digits. If these results are not complete, it sends a Refresh header instructing the browser to ask for new results a little while later. Uses the Primes, PrimeList, and ServletUtilities  classes.

 

package cwp;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

/** Servlet that processes a request to generate n
 *  prime numbers, each with at least m digits.
 *  It performs the calculations in a low-priority background
 *  thread, returning only the results it has found so far.
 *  If these results are not complete, it sends a Refresh
 *  header instructing the browser to ask for new results a
 *  little while later. It also maintains a list of a
 *  small number of previously calculated prime lists
 *  to return immediately to anyone who supplies the
 *  same n and m as a recent completed computation.
 *  


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

public class PrimeNumbers extends HttpServlet {
  private Vector primeListVector = new Vector();
  private int maxPrimeLists = 30;

  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    int numPrimes =
      ServletUtilities.getIntParameter(request,
                                       "numPrimes", 50);
    int numDigits =
      ServletUtilities.getIntParameter(request,
                                       "numDigits", 120);
    PrimeList primeList =
      findPrimeList(primeListVector, numPrimes, numDigits);
    if (primeList == null) {
      primeList = new PrimeList(numPrimes, numDigits, true);
      // Multiple servlet request threads share the instance
      // variables (fields) of PrimeNumbers. So
      // synchronize all access to servlet fields.
      synchronized(primeListVector) {
        if (primeListVector.size() >= maxPrimeLists)
          primeListVector.removeElementAt(0);
        primeListVector.addElement(primeList);
      }
    }
    Vector currentPrimes = primeList.getPrimes();
    int numCurrentPrimes = currentPrimes.size();
    int numPrimesRemaining = (numPrimes - numCurrentPrimes);
    boolean isLastResult = (numPrimesRemaining == 0);
    if (!isLastResult) {
      response.setHeader("Refresh", "5");
    }
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String title = "Some " + numDigits + "-Digit Prime Numbers";
    out.println(ServletUtilities.headWithTitle(title) +
                "\n" +
                "
" + title + "
\n" +
                "
Primes found with " + numDigits +
                " or more digits: " + numCurrentPrimes +
                ".
");
    if (isLastResult)
      out.println("Done searching.");
    else
      out.println("Still looking for " + numPrimesRemaining +
                  " more...");
    out.println("

    ");
        for(int i=0; i" + currentPrimes.elementAt(i));
        }
        out.println("

");
    out.println("");
  }

  public void doPost(HttpServletRequest request,
                     HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }

  // See if there is an existing ongoing or completed
  // calculation with the same number of primes and number
  // of digits per prime. If so, return those results instead
  // of starting a new background thread. Keep this list
  // small so that the Web server doesn't use too much memory.
  // Synchronize access to the list since there may be
  // multiple simultaneous requests.

  private PrimeList findPrimeList(Vector primeListVector,
                                  int numPrimes,
                                  int numDigits) {
    synchronized(primeListVector) {
      for(int i=0; i
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

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



PrimeList.java
package cwp;

import java.util.*;
import java.math.BigInteger;

/** Creates a Vector of large prime numbers, usually in
 *  a low-priority background thread. Provides a few small
 *  thread-safe access methods.
 *  


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

public class PrimeList implements Runnable {
  private Vector primesFound;
  private int numPrimes, numDigits;

  /** Finds numPrimes prime numbers, each of which are
   *  numDigits long or longer. You can set it to only
   *  return when done, or have it return immediately,
   *  and you can later poll it to see how far it
   *  has gotten.
   */

  public PrimeList(int numPrimes, int numDigits,
                   boolean runInBackground) {
    // Using Vector instead of ArrayList
    // to support JDK 1.1 servlet engines
    primesFound = new Vector(numPrimes);
    this.numPrimes = numPrimes;
    this.numDigits = numDigits;
    if (runInBackground) {
      Thread t = new Thread(this);
      // Use low priority so you don't slow down server.
      t.setPriority(Thread.MIN_PRIORITY);
      t.start();
    } else {
      run();
    }
  }

  public void run() {
    BigInteger start = Primes.random(numDigits);
    for(int i=0; i
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class ServletUtilities {
  public static final String DOCTYPE =
    "";

  public static String headWithTitle(String title) {
    return(DOCTYPE + "\n" +
           "\n" +
           "\n");
  }

  /** Read a parameter with the specified name, convert it
   *  to an int, and return it. Return the designated default
   *  value if the parameter doesn't exist or if it is an
   *  illegal integer format.
  */

  public static int getIntParameter(HttpServletRequest request,
                                    String paramName,
                                    int defaultValue) {
    String paramString = request.getParameter(paramName);
    int paramValue;
    try {
      paramValue = Integer.parseInt(paramString);
    } catch(NumberFormatException nfe) { // null or bad format
      paramValue = defaultValue;
    }
    return(paramValue);
  }

  /** Given an array of Cookies, a name, and a default value,
   *  this method tries to find the value of the cookie with
   *  the given name. If there is no cookie matching the name
   *  in the array, then the default value is returned instead.
   */

  public static String getCookieValue(Cookie[] cookies,
                                      String cookieName,
                                      String defaultValue) {
    if (cookies != null) {
      for(int i=0; i' with
   *  '>', and (to handle cases that occur inside attribute
   *  values), all occurrences of double quotes with
   *  '"' and all occurrences of '&' with '&'.
   *  Without such filtering, an arbitrary string
   *  could not safely be inserted in a Web page.
   */

  public static String filter(String input) {
    StringBuffer filtered = new StringBuffer(input.length());
    char c;
    for(int i=0; i') {
        filtered.append(">");
      } else if (c == '"') {
        filtered.append(""");
      } else if (c == '&') {
        filtered.append("&");
      } else {
        filtered.append(c);
      }
    }
    return(filtered.toString());
  }
}

ShowRequestHeaders.java Servlet that shows all request headers sent by browser in current request.

Huge Sell on Popular Electronics

ShowRequestHeaders.java  Servlet that shows all request headers sent by browser in current request. 

package cwp;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;

/** Shows all the request headers sent on this request.
 *
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class ShowRequestHeaders extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String title = "Servlet Example: Showing Request Headers";
    out.println(ServletUtilities.headWithTitle(title) +
                "\n" +
                "
" + title + "
\n" +
                "Request Method: " +
                request.getMethod() + "
\n" +
                "Request URI: " +
                request.getRequestURI() + "
\n" +
                "Request Protocol: " +
                request.getProtocol() + "

\n" +
                "\n" +
                "\n" +
                "
Header Name
Header Value");
    Enumeration headerNames = request.getHeaderNames();
    while(headerNames.hasMoreElements()) {
      String headerName = (String)headerNames.nextElement();
      out.println("
" + headerName);
      out.println("
" + request.getHeader(headerName));
    }
    out.println("
\n");
  }

  /** Let the same servlet handle both GET and POST. */

  public void doPost(HttpServletRequest request,
                     HttpServletResponse response)
      throws ServletException, IOException {
    doGet(request, response);
  }
}

ServletUtilities.java Utility class that, among other things, contains the static filter method that replaces special HTML characters with their HTML character entities.

Huge Sell on Popular Electronics

ServletUtilities.java  Utility class that, among other things, contains the static filter  method that replaces special HTML characters with their HTML character entities. 

package cwp;

import javax.servlet.*;
import javax.servlet.http.*;

/** Some simple time savers. Note that most are static methods.
 *  


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

public class ServletUtilities {
  public static final String DOCTYPE =
    "";

  public static String headWithTitle(String title) {
    return(DOCTYPE + "\n" +
           "\n" +
           "\n");
  }

  /** Read a parameter with the specified name, convert it
   *  to an int, and return it. Return the designated default
   *  value if the parameter doesn't exist or if it is an
   *  illegal integer format.
  */

  public static int getIntParameter(HttpServletRequest request,
                                    String paramName,
                                    int defaultValue) {
    String paramString = request.getParameter(paramName);
    int paramValue;
    try {
      paramValue = Integer.parseInt(paramString);
    } catch(NumberFormatException nfe) { // null or bad format
      paramValue = defaultValue;
    }
    return(paramValue);
  }

  /** Given an array of Cookies, a name, and a default value,
   *  this method tries to find the value of the cookie with
   *  the given name. If there is no cookie matching the name
   *  in the array, then the default value is returned instead.
   */

  public static String getCookieValue(Cookie[] cookies,
                                      String cookieName,
                                      String defaultValue) {
    if (cookies != null) {
      for(int i=0; i' with
   *  '>', and (to handle cases that occur inside attribute
   *  values), all occurrences of double quotes with
   *  '"' and all occurrences of '&' with '&'.
   *  Without such filtering, an arbitrary string
   *  could not safely be inserted in a Web page.
   */

  public static String filter(String input) {
    StringBuffer filtered = new StringBuffer(input.length());
    char c;
    for(int i=0; i') {
        filtered.append(">");
      } else if (c == '"') {
        filtered.append(""");
      } else if (c == '&') {
        filtered.append("&");
      } else {
        filtered.append(c);
      }
    }
    return(filtered.toString());
  }
}

ThreeParams.java Servlet that reads and displays three request (form) parameters. Uses the ServletUtilities class.

Huge Sell on Popular Electronics

ThreeParams.java  Servlet that reads and displays three request (form) parameters. Uses the ServletUtilities  class. 

package cwp;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/** Simple servlet that reads three parameters from the
 *  form data.
 *  


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

public class ThreeParams extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String title = "Reading Three Request Parameters";
    out.println(ServletUtilities.headWithTitle(title) +
                "\n" +
                "
" + title + "
\n" +
                "

    \n" +
                    "  
    param1: "
                    + request.getParameter("param1") + "\n" +
                    "  
    param2: "
                    + request.getParameter("param2") + "\n" +
                    "  
    param3: "
                    + request.getParameter("param3") + "\n" +
                    "

\n" +
                "");
  }
}

ShowMessage.java Servlet that demonstrates the use of initialization parameters.

Huge Sell on Popular Electronics

ShowMessage.java  Servlet that demonstrates the use of initialization parameters. Remember that, to use this servlet, you have to do three things:

    * Put the modified web.xml file in the WEB-INF directory.
    * Restart the server.
    * Use the registered servlet name (i.e., the URL http://host/servlet/ShowMsg), not the raw servlet name (i.e., the URL http://host/servlet/cwp.ShowMessage). 


package cwp;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/** Example using servlet initialization. Here, the message
 *  to print and the number of times the message should be
 *  repeated is taken from the init parameters.
 *  


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

public class ShowMessage extends HttpServlet {
  private String message;
  private String defaultMessage = "No message.";
  private int repeats = 1;

  public void init() throws ServletException {
    ServletConfig config = getServletConfig();
    message = config.getInitParameter("message");
    if (message == null) {
      message = defaultMessage;
    }
    try {
      String repeatString = config.getInitParameter("repeats");
      repeats = Integer.parseInt(repeatString);
    } catch(NumberFormatException nfe) {
      // NumberFormatException handles case where repeatString
      // is null *and* case where it is in an illegal format.
    }
  }

  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String title = "The ShowMessage Servlet";
    out.println(ServletUtilities.headWithTitle(title) +
                "\n" +
                "
" + title + "
");
    for(int i=0; i" + message + "
");
    }
    out.println("");
  }
}


web.xml



?

ShowMsg
cwp.ShowMessage
?

message
Shibboleth

?

repeats
5


ServletUtilities.java Utility class that simplifies the output of the DOCTYPE and HEAD in servlets, among other things. Used by most remaining servlets in the chapter.

Huge Sell on Popular Electronics

ServletUtilities.java  Utility class that simplifies the output of the DOCTYPE and HEAD  in servlets, among other things. Used by most remaining servlets in the chapter. 

package cwp;

import javax.servlet.*;
import javax.servlet.http.*;

/** Some simple time savers. Note that most are static methods.
 *  


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

public class ServletUtilities {
  public static final String DOCTYPE =
    "";

  public static String headWithTitle(String title) {
    return(DOCTYPE + "\n" +
           "\n" +
           "\n");
  }

  /** Read a parameter with the specified name, convert it
   *  to an int, and return it. Return the designated default
   *  value if the parameter doesn't exist or if it is an
   *  illegal integer format.
  */

  public static int getIntParameter(HttpServletRequest request,
                                    String paramName,
                                    int defaultValue) {
    String paramString = request.getParameter(paramName);
    int paramValue;
    try {
      paramValue = Integer.parseInt(paramString);
    } catch(NumberFormatException nfe) { // null or bad format
      paramValue = defaultValue;
    }
    return(paramValue);
  }

  /** Given an array of Cookies, a name, and a default value,
   *  this method tries to find the value of the cookie with
   *  the given name. If there is no cookie matching the name
   *  in the array, then the default value is returned instead.
   */

  public static String getCookieValue(Cookie[] cookies,
                                      String cookieName,
                                      String defaultValue) {
    if (cookies != null) {
      for(int i=0; i' with
   *  '>', and (to handle cases that occur inside attribute
   *  values), all occurrences of double quotes with
   *  '"' and all occurrences of '&' with '&'.
   *  Without such filtering, an arbitrary string
   *  could not safely be inserted in a Web page.
   */

  public static String filter(String input) {
    StringBuffer filtered = new StringBuffer(input.length());
    char c;
    for(int i=0; i') {
        filtered.append(">");
      } else if (c == '"') {
        filtered.append(""");
      } else if (c == '&') {
        filtered.append("&");
      } else {
        filtered.append(c);
      }
    }
    return(filtered.toString());
  }
}


SimplerHelloWWW.java Servlet that uses ServletUtilities to simplify the generation of the DOCTYPE and HEAD part of the servlet.

Huge Sell on Popular Electronics

SimplerHelloWWW.java  Servlet that uses ServletUtilities  to simplify the generation of the DOCTYPE and HEAD part of the servlet.

package cwp;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/** Simple servlet that generates HTML. This variation of
 *  HelloWWW uses the ServletUtilities utility class
 *  to generate the DOCTYPE, HEAD, and TITLE.
 *  


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

public class SimplerHelloWWW extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println(ServletUtilities.headWithTitle("Hello WWW") +
                "\n" +
                "
Hello WWW
\n" +
                "");
  }
}


Servlet Utilities

package cwp;

import javax.servlet.*;
import javax.servlet.http.*;

/** Some simple time savers. Note that most are static methods.
 *  


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

public class ServletUtilities {
  public static final String DOCTYPE =
    "";

  public static String headWithTitle(String title) {
    return(DOCTYPE + "\n" +
           "\n" +
           "\n");
  }

  /** Read a parameter with the specified name, convert it
   *  to an int, and return it. Return the designated default
   *  value if the parameter doesn't exist or if it is an
   *  illegal integer format.
  */
  
  public static int getIntParameter(HttpServletRequest request,
                                    String paramName,
                                    int defaultValue) {
    String paramString = request.getParameter(paramName);
    int paramValue;
    try {
      paramValue = Integer.parseInt(paramString);
    } catch(NumberFormatException nfe) { // null or bad format
      paramValue = defaultValue;
    }
    return(paramValue);
  }

  /** Given an array of Cookies, a name, and a default value,
   *  this method tries to find the value of the cookie with
   *  the given name. If there is no cookie matching the name
   *  in the array, then the default value is returned instead.
   */
  
  public static String getCookieValue(Cookie[] cookies,
                                      String cookieName,
                                      String defaultValue) {
    if (cookies != null) {
      for(int i=0; i' with
   *  '>', and (to handle cases that occur inside attribute
   *  values), all occurrences of double quotes with
   *  '"' and all occurrences of '&' with '&'.
   *  Without such filtering, an arbitrary string
   *  could not safely be inserted in a Web page.
   */

  public static String filter(String input) {
    StringBuffer filtered = new StringBuffer(input.length());
    char c;
    for(int i=0; i') {
        filtered.append(">");
      } else if (c == '"') {
        filtered.append(""");
      } else if (c == '&') {
        filtered.append("&");
      } else {
        filtered.append(c);
      }
    }
    return(filtered.toString());
  }
}

HelloWWW.java Servlet that generates HTML. This and all remaining servlets are in the cwp package and therefore should be installed in the cwp subdirectory.

Huge Sell on Popular Electronics

HelloWWW.java  Servlet that generates HTML. This and all remaining servlets are in the cwp package and therefore should be installed in the cwp subdirectory.

package cwp;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

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

public class HelloWWW extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String docType =
      "\n";
    out.println(docType +
                "\n" +
                "\n" +
                "\n" +
                "

ServletTemplate.java Starting point for servlets.

Huge Sell on Popular Electronics

ServletTemplate.java Starting point for servlets. 


import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

/** Servlet template.
 *  


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

public class ServletTemplate extends HttpServlet {
  public void doGet(HttpServletRequest request,
                    HttpServletResponse response)
      throws ServletException, IOException {

    // Use "request" to read incoming HTTP headers
    // (e.g., cookies) and query data from HTML forms.

    // Use "response" to specify the HTTP response status
    // code and headers (e.g. the content type, cookies).

    PrintWriter out = response.getWriter();
    // Use "out" to send content to browser
  }
}



StringBean.java Bean used to demonstrate jsp:useBean, etc. Remember to install it in the WEB-INF/classes/cwp directory.

Huge Sell on Popular Electronics

StringBean.java  Bean used to demonstrate jsp:useBean, etc. Remember to install it in the WEB-INF/classes/cwp directory. 

package cwp;

/** A simple bean that has a single String property
 *  called message.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class StringBean {
  private String message = "No message specified";

  public String getMessage() {
    return(message);
  }

  public void setMessage(String message) {
    this.message = message;
  }
}

PluginApplet.jsp Page that demonstrates the use of jsp:plugin.

Huge Sell on Popular Electronics

PluginApplet.jsp  Page that demonstrates the use of jsp:plugin. Requires you to compile and install PluginApplet.java, TextPanel.java, DrawingPanel.java, and WindowUtilities.java  Since these are classes sent to the client to used by applets, the .class files should be in the same directory as the JSP page, not in the WEB-INF/classes directory where classes the server uses go. Uses the JSP-Styles  style sheet. Warning: Allaire JRun 3.0 SP2 does not properly support jsp:plugin.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- 
Example of using jsp:plugin for an applet that uses Java 2. 

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:plugin</TITLE>
<LINK REL=STYLESHEET
      HREF="JSP-Styles.css"
      TYPE="text/css">
</HEAD>

<BODY>

<TABLE BORDER=5 ALIGN="CENTER">
  <TR><TH CLASS="TITLE">
      Using jsp:plugin</TABLE>
<P>
<CENTER>
<jsp:plugin type="applet" 
            code="PluginApplet.class"
            width="370" height="420">
</jsp:plugin>
</CENTER>

</BODY>
</HTML>

PluginApplet.java

import javax.swing.*;

/** An applet that uses Swing and Java 2D and thus requires
 *  the Java Plug-In.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class PluginApplet extends JApplet {
  public void init() {
    WindowUtilities.setNativeLookAndFeel();
    setContentPane(new TextPanel());
  }
}


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

/** JPanel that places a panel with text drawn at various angles
 *  in the top part of the window and a JComboBox containing
 *  font choices in the bottom part.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

public class TextPanel extends JPanel
                       implements ActionListener {
  private JComboBox fontBox;
  private DrawingPanel drawingPanel;

  public TextPanel() {
    GraphicsEnvironment env =
      GraphicsEnvironment.getLocalGraphicsEnvironment();
    String[] fontNames = env.getAvailableFontFamilyNames();
    fontBox = new JComboBox(fontNames);
    setLayout(new BorderLayout());
    JPanel fontPanel = new JPanel();
    fontPanel.add(new JLabel("Font:"));
    fontPanel.add(fontBox);
    JButton drawButton = new JButton("Draw");
    drawButton.addActionListener(this);
    fontPanel.add(drawButton);
    add(fontPanel, BorderLayout.SOUTH);
    drawingPanel = new DrawingPanel();
    fontBox.setSelectedItem("Serif");
    drawingPanel.setFontName("Serif");
    add(drawingPanel, BorderLayout.CENTER);
  }

  public void actionPerformed(ActionEvent e) {
    drawingPanel.setFontName((String)fontBox.getSelectedItem());
    drawingPanel.repaint();
  }
}


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

/** A window with text drawn at an angle. The font is
 *  set by means of the setFontName method.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  May be freely used or adapted.
 */

class DrawingPanel extends JPanel {
  private Ellipse2D.Double circle =
    new Ellipse2D.Double(10, 10, 350, 350);
  private GradientPaint gradient =
    new GradientPaint(0, 0, Color.red, 180, 180, Color.yellow,
                      true); // true means to repeat pattern
  private Color[] colors = { Color.white, Color.black };

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    g2d.setPaint(gradient);
    g2d.fill(circle);
    g2d.translate(185, 185);
    for (int i=0; i<16; i++) {
      g2d.rotate(Math.PI/8.0);
      g2d.setPaint(colors[i%2]);
      g2d.drawString("jsp:plugin", 0, 0);
    }
  }

  public void setFontName(String fontName) {
    setFont(new Font(fontName, Font.BOLD, 35));
  }
}


WindowUtilities.java

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

/** A few utilities that simplify using windows in Swing.
 *  <P>
 *  Taken from Core Web Programming Java 2 Edition
 *  from Prentice Hall and Sun Microsystems Press,
 *  .
 *  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));
  }
}

BGColor.jsp Page that demonstrates JSP scriptlets. Uses the JSP-Styles style sheet.

Huge Sell on Popular Electronics

BGColor.jsp  Page that demonstrates JSP scriptlets. Uses the JSP-Styles  style sheet.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!--    
Taken from Core Web Programming Java 2 Edition
from Prentice Hall and Sun Microsystems Press,
.
May be freely used or adapted.
-->
<HTML>
<HEAD>
  <TITLE>Color Testing</TITLE>
</HEAD>
<% 
String bgColor = request.getParameter("bgColor");
boolean hasExplicitColor = true;
if (bgColor == null) {
  hasExplicitColor = false;
  bgColor = "WHITE";
} 
%>
<BODY BGCOLOR="<%= bgColor %>">
<H2 ALIGN="CENTER">Color Testing</H2>
<%
if (hasExplicitColor) {
  out.println("You supplied an explicit background color of " +
              bgColor + ".");
} else {
  out.println("Using default background color of WHITE. " +
              "Supply the bgColor request attribute to try " +
              "a standard color or RRGGBB value, or to see " +
              "if your browser supports X11 color names.");
}
%>
</BODY>
</HTML>

Excel.jsp Page that demonstrates the use of JSP to build Excel spreadsheets

Huge Sell on Popular Electronics

Excel.jsp  Page that demonstrates the use of JSP to build Excel spreadsheets

First    Last    Email Address
Marty    Hall    hall@corewebprogramming.com
Larry    Brown    brown@corewebprogramming.com
Bill    Gates    gates@sun.com
Larry    Ellison    ellison@microsoft.com
<%@ page contentType="application/vnd.ms-excel" %>
<%-- There are tabs, not spaces, between columns. --%>

Expressions.jsp Page that demonstrates JSP expressions. Uses the JSP-Styles style sheet.

Huge Sell on Popular Electronics

Expressions.jsp  Page that demonstrates JSP expressions. Uses the JSP-Styles  style sheet. 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- 
Example of JSP Expressions. 
   
Taken from Core Web Programming Java 2 Edition
from Prentice Hall and Sun Microsystems Press,
.
May be freely used or adapted.
-->
<HTML>
<HEAD>
<TITLE>JSP Expressions</TITLE>
<META NAME="keywords"
      CONTENT="JSP,expressions,JavaServer,Pages,servlets">
<META NAME="description"
      CONTENT="A quick example of JSP expressions.">
<LINK REL=STYLESHEET
      HREF="JSP-Styles.css"
      TYPE="text/css">
</HEAD>

<BODY>
<H2>JSP Expressions</H2>
<UL>
  <LI>Current time: <%= new java.util.Date() %>
  <LI>Your hostname: <%= request.getRemoteHost() %>
  <LI>Your session ID: <%= session.getId() %>
  <LI>The <CODE>testParam</CODE> form parameter:
      <%= request.getParameter("testParam") %>
</UL>
</BODY>
</HTML>

ImportAttribute.jsp Page that demonstrates the import attribute of the page directive. Uses the ServletUtilities class

Huge Sell on Popular Electronics

ImportAttribute.jsp  Page that demonstrates the import attribute of the page directive. Uses the ServletUtilities class (Check Servlet Section)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!--
Example of the import attribute of the page directive.

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

<BODY>
<H2>The import Attribute</H2>
<%-- JSP page directive --%>
<%@ page import="java.util.*,cwp.*" %>

<%-- JSP Declaration --%>
<%!
private String randomID() {
int num = (int)(Math.random()*10000000.0);
return("id" + num);
}

private final String NO_VALUE = "<I>No Value</I>";
%>

<%-- JSP Scriptlet --%>
<%
Cookie[] cookies = request.getCookies();
String oldID =
ServletUtilities.getCookieValue(cookies, "userID", NO_VALUE);
if (oldID.equals(NO_VALUE)) {
String newID = randomID();
Cookie cookie = new Cookie("userID", newID);
response.addCookie(cookie);
}
%>

<%-- JSP Expressions --%>
This page was accessed on <%= new Date() %> with a userID
cookie of <%= oldID %>.

</BODY>
</HTML>

QueryViewer.java: An interactive database query viewer

Huge Sell on Popular Electronics

# QueryViewer.java  An interactive database query viewer. Connects to the specified Oracle or Sybase database, executes a query, and presents the results in a JTable. Uses the following file:

    * DBResultsTableModel.java Simple class that tells a JTable how to extract relevant data from a DBResults object (which is used to store the results from a database query). 
############################################################################

  package cwp;

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

/** An interactive database query viewer. Connects to
 *  the specified Oracle or Sybase database, executes a query,
 *  and presents the results in a JTable.
 *  


 */

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

  private JTextField hostField, dbNameField,
                     queryField, usernameField;
  private JRadioButton oracleButton, sybaseButton;
  private JPasswordField passwordField;
  private JButton showResultsButton;
  Container contentPane;
  private JPanel tablePanel;
  
  public QueryViewer () {
    super("Database Query Viewer");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    contentPane = getContentPane();
    contentPane.add(makeControlPanel(), BorderLayout.NORTH);
    pack();
    setVisible(true);
  }

  /** When the "Show Results" button is pressed or
   *  RETURN is hit while the query textfield has the
   *  keyboard focus, a database lookup is performed,
   *  the results are placed in a JTable, and the window
   *  is resized to accommodate the table.
   */
  
  public void actionPerformed(ActionEvent event) {
    String host = hostField.getText();
    String dbName = dbNameField.getText();
    String username = usernameField.getText();
    String password =
      String.valueOf(passwordField.getPassword());
    String query = queryField.getText();
    int vendor;
    if (oracleButton.isSelected()) {
      vendor = DriverUtilities.ORACLE;
    } else {
      vendor = DriverUtilities.SYBASE;
    }
    if (tablePanel != null) {
      contentPane.remove(tablePanel);
    }
    tablePanel = makeTablePanel(host, dbName, vendor,
                                username, password,
                                query);
    contentPane.add(tablePanel, BorderLayout.CENTER);
    pack();
  }

  // Executes a query and places the result in a
  // JTable that is, in turn, inside a JPanel.
  
  private JPanel makeTablePanel(String host,
                                String dbName,
                                int vendor,
                                String username,
                                String password,
                                String query) {
    String driver = DriverUtilities.getDriver(vendor);
    String url = DriverUtilities.makeURL(host, dbName, vendor);
    DBResults results =
      DatabaseUtilities.getQueryResults(driver, url,
                                        username, password,
                                        query, true);
    JPanel panel = new JPanel(new BorderLayout());
    if (results == null) {
      panel.add(makeErrorLabel());
      return(panel);
    }
    DBResultsTableModel model =
      new DBResultsTableModel(results);
    JTable table = new JTable(model);
    table.setFont(new Font("Serif", Font.PLAIN, 17));
    table.setRowHeight(28);
    JTableHeader header = table.getTableHeader();
    header.setFont(new Font("SansSerif", Font.BOLD, 13));
    panel.add(table, BorderLayout.CENTER);
    panel.add(header, BorderLayout.NORTH);
    panel.setBorder
      (BorderFactory.createTitledBorder("Query Results"));
    return(panel);
  }

  // The panel that contains the textfields, checkboxes,
  // and button.
  
  private JPanel makeControlPanel() {
    JPanel panel = new JPanel(new GridLayout(0, 1));
    panel.add(makeHostPanel());
    panel.add(makeUsernamePanel());
    panel.add(makeQueryPanel());
    panel.add(makeButtonPanel());
    panel.setBorder
      (BorderFactory.createTitledBorder("Query Data"));
    return(panel);
  }

  // The panel that has the host and db name textfield and
  // the driver radio buttons. Placed in control panel.
  
  private JPanel makeHostPanel() {
    JPanel panel = new JPanel();
    panel.add(new JLabel("Host:"));
    hostField = new JTextField(15);
    panel.add(hostField);
    panel.add(new JLabel("    DB Name:"));
    dbNameField = new JTextField(15);
    panel.add(dbNameField);
    panel.add(new JLabel("    Driver:"));
    ButtonGroup vendorGroup = new ButtonGroup();
    oracleButton = new JRadioButton("Oracle", true);
    vendorGroup.add(oracleButton);
    panel.add(oracleButton);
    sybaseButton = new JRadioButton("Sybase");
    vendorGroup.add(sybaseButton);
    panel.add(sybaseButton);
    return(panel);
  }

  // The panel that has the username and password textfields.
  // Placed in control panel.
  
  private JPanel makeUsernamePanel() {
    JPanel panel = new JPanel();
    usernameField = new JTextField(10);
    passwordField = new JPasswordField(10);
    panel.add(new JLabel("Username: "));
    panel.add(usernameField);
    panel.add(new JLabel("    Password:"));
    panel.add(passwordField);
    return(panel);
  }

  // The panel that has textfield for entering queries.
  // Placed in control panel.
  
  private JPanel makeQueryPanel() {
    JPanel panel = new JPanel();
    queryField = new JTextField(40);
    queryField.addActionListener(this);
    panel.add(new JLabel("Query:"));
    panel.add(queryField);
    return(panel);
  }

  // The panel that has the "Show Results" button.
  // Placed in control panel.
  
  private JPanel makeButtonPanel() {
    JPanel panel = new JPanel();
    showResultsButton = new JButton("Show Results");
    showResultsButton.addActionListener(this);
    panel.add(showResultsButton);
    return(panel);
  }

  // Shows warning when bad query sent.
  
  private JLabel makeErrorLabel() {
    JLabel label = new JLabel("No Results", JLabel.CENTER);
    label.setFont(new Font("Serif", Font.BOLD, 36));
    return(label);
  }
}

AccessCounts.jsp Page that demonstrates JSP declarations.

Huge Sell on Popular Electronics

AccessCounts.jsp  Page that demonstrates JSP declarations.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!--   
Taken from Core Web Programming Java 2 Edition
from Prentice Hall and Sun Microsystems Press,
.
May be freely used or adapted.
-->
<HTML>
<HEAD>
<TITLE>JSP Declarations</TITLE>
<META NAME="keywords"
      CONTENT="JSP,declarations,JavaServer,Pages,servlets">
<META NAME="description"
      CONTENT="A quick example of JSP declarations.">
<LINK REL=STYLESHEET
      HREF="JSP-Styles.css"
      TYPE="text/css">
</HEAD>

<BODY>
<H1>JSP Declarations</H1>

<%! private int accessCount = 0; %>
<H2>Accesses to page since server reboot: 
<%= ++accessCount %></H2>

</BODY>
</HTML>

PreparedStatements.java An example to test the timing differences resulting from repeated raw queries vs. repeated calls

Huge Sell on Popular Electronics

package cwp;

import java.sql.*;

/** An example to test the timing differences resulting
 *  from repeated raw queries vs. repeated calls to
 *  prepared statements. These results will vary dramatically
 *  among database servers and drivers. With my setup
 *  and drivers, Oracle prepared statements took only half
 *  the time that raw queries required when using a modem
 *  connection, and took only 70% of the time that
 *  raw queries required when using a fast LAN connection.
 *  Sybase times were identical in both cases.
 *  


 */

public class PreparedStatements {
  public static void main(String[] args) {
    if (args.length < 5) {
      printUsage();
      return;
    }
    String vendorName = args[4];
    int vendor = DriverUtilities.getVendor(vendorName);
    if (vendor == DriverUtilities.UNKNOWN) {
      printUsage();
      return;
    }
    String driver = DriverUtilities.getDriver(vendor);
    String host = args[0];
    String dbName = args[1];
    String url =
      DriverUtilities.makeURL(host, dbName, vendor);
    String username = args[2];
    String password = args[3];
    // Use "print" only to confirm it works properly,
    // not when getting timing results.
    boolean print = false;
    if ((args.length > 5) && (args[5].equals("print"))) {
      print = true;
    }
    Connection connection =
      getConnection(driver, url, username, password);
    if (connection != null) {
      doPreparedStatements(connection, print);
      doRawQueries(connection, print);
    }
  }

  private static void doPreparedStatements(Connection conn,
                                           boolean print) {
    try {
      String queryFormat =
        "SELECT lastname FROM employees WHERE salary > ?";
      PreparedStatement statement =
        conn.prepareStatement(queryFormat);
      long startTime = System.currentTimeMillis();
      for(int i=0; i<40; i++) {
        statement.setFloat(1, i*5000);
        ResultSet results = statement.executeQuery();
        if (print) {
          showResults(results);
        }
      }
      long stopTime = System.currentTimeMillis();
      double elapsedTime = (stopTime - startTime)/1000.0;
      System.out.println("Executing prepared statement " +
                         "40 times took " +
                         elapsedTime + " seconds.");
    } catch(SQLException sqle) {
      System.out.println("Error executing statement: " + sqle);
    }
  }

  public static void doRawQueries(Connection conn,
                                  boolean print) {
    try {
      String queryFormat =
        "SELECT lastname FROM employees WHERE salary > ";
      Statement statement = conn.createStatement();
      long startTime = System.currentTimeMillis();
      for(int i=0; i<40; i++) {
        ResultSet results =
          statement.executeQuery(queryFormat + (i*5000));
        if (print) {
          showResults(results);
        }
      }
      long stopTime = System.currentTimeMillis();
      double elapsedTime = (stopTime - startTime)/1000.0;
      System.out.println("Executing raw query " +
                         "40 times took " +
                         elapsedTime + " seconds.");
    } catch(SQLException sqle) {
      System.out.println("Error executing query: " + sqle);
    }
  } 

  private static void showResults(ResultSet results)
      throws SQLException {
    while(results.next()) {
      System.out.print(results.getString(1) + " ");
    }
    System.out.println();
  }
    
  private static Connection getConnection(String driver,
                                          String url,
                                          String username,
                                          String password) {
    try {
      Class.forName(driver);
      Connection connection =
        DriverManager.getConnection(url, username, password);
      return(connection);
    } catch(ClassNotFoundException cnfe) {
      System.err.println("Error loading driver: " + cnfe);
      return(null);
    } catch(SQLException sqle) {
      System.err.println("Error connecting: " + sqle);
      return(null);
    }
  }

  private static void printUsage() {
    System.out.println("Usage: PreparedStatements host " +
                       "dbName username password " +
                       "oracle|sybase [print].");
  }
}

EmployeeCreation.java: Make a simple “employees” table using the database utilities

Huge Sell on Popular Electronics

package cwp;

import java.sql.*;

/** Make a simple "employees" table using DatabaseUtilities.
 */

public class EmployeeCreation {
  public static Connection createEmployees(String driver,
                                           String url,
                                           String username,
                                           String password,
                                           boolean close) {
    String format =
      "(id int, firstname varchar(32), lastname varchar(32), " +
      "language varchar(16), salary float)";
    String[] employees =
      {"(1, 'Wye', 'Tukay', 'COBOL', 42500)",
       "(2, 'Britt', 'Tell',   'C++',   62000)",
       "(3, 'Max',  'Manager', 'none',  15500)",
       "(4, 'Polly', 'Morphic', 'Smalltalk', 51500)",
       "(5, 'Frank', 'Function', 'Common Lisp', 51500)",
       "(6, 'Justin', 'Timecompiler', 'Java', 98000)",
       "(7, 'Sir', 'Vlet', 'Java', 114750)",
       "(8, 'Jay', 'Espy', 'Java', 128500)" };
    return(DatabaseUtilities.createTable(driver, url,
                                         username, password,
                                         "employees",
                                         format, employees,
                                         close));    
  }

  public static void main(String[] args) {
    if (args.length < 5) {
      printUsage();
      return;
    }
    String vendorName = args[4];
    int vendor = DriverUtilities.getVendor(vendorName);
    if (vendor == DriverUtilities.UNKNOWN) {
      printUsage();
      return;
    }
    String driver = DriverUtilities.getDriver(vendor);
    String host = args[0];
    String dbName = args[1];
    String url =
      DriverUtilities.makeURL(host, dbName, vendor);
    String username = args[2];
    String password = args[3];
    createEmployees(driver, url, username, password, true);
  }

  private static void printUsage() {
    System.out.println("Usage: EmployeeCreation host dbName " +
                       "username password oracle|sybase.");
  }
}

extract relevant data from a DBResults

Huge Sell on Popular Electronics

# QueryViewer.java  An interactive database query viewer. Connects to the specified Oracle or Sybase database, executes a query, and presents the results in a JTable. Uses the following file:

    * DBResultsTableModel.java Simple class that tells a JTable how to extract relevant data from a DBResults object (which is used to store the results from a database query). 
############################################################################

  package cwp;

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

/** An interactive database query viewer. Connects to
 *  the specified Oracle or Sybase database, executes a query,
 *  and presents the results in a JTable.
 *  


 */

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

  private JTextField hostField, dbNameField,
                     queryField, usernameField;
  private JRadioButton oracleButton, sybaseButton;
  private JPasswordField passwordField;
  private JButton showResultsButton;
  Container contentPane;
  private JPanel tablePanel;
  
  public QueryViewer () {
    super("Database Query Viewer");
    WindowUtilities.setNativeLookAndFeel();
    addWindowListener(new ExitListener());
    contentPane = getContentPane();
    contentPane.add(makeControlPanel(), BorderLayout.NORTH);
    pack();
    setVisible(true);
  }

  /** When the "Show Results" button is pressed or
   *  RETURN is hit while the query textfield has the
   *  keyboard focus, a database lookup is performed,
   *  the results are placed in a JTable, and the window
   *  is resized to accommodate the table.
   */
  
  public void actionPerformed(ActionEvent event) {
    String host = hostField.getText();
    String dbName = dbNameField.getText();
    String username = usernameField.getText();
    String password =
      String.valueOf(passwordField.getPassword());
    String query = queryField.getText();
    int vendor;
    if (oracleButton.isSelected()) {
      vendor = DriverUtilities.ORACLE;
    } else {
      vendor = DriverUtilities.SYBASE;
    }
    if (tablePanel != null) {
      contentPane.remove(tablePanel);
    }
    tablePanel = makeTablePanel(host, dbName, vendor,
                                username, password,
                                query);
    contentPane.add(tablePanel, BorderLayout.CENTER);
    pack();
  }

  // Executes a query and places the result in a
  // JTable that is, in turn, inside a JPanel.
  
  private JPanel makeTablePanel(String host,
                                String dbName,
                                int vendor,
                                String username,
                                String password,
                                String query) {
    String driver = DriverUtilities.getDriver(vendor);
    String url = DriverUtilities.makeURL(host, dbName, vendor);
    DBResults results =
      DatabaseUtilities.getQueryResults(driver, url,
                                        username, password,
                                        query, true);
    JPanel panel = new JPanel(new BorderLayout());
    if (results == null) {
      panel.add(makeErrorLabel());
      return(panel);
    }
    DBResultsTableModel model =
      new DBResultsTableModel(results);
    JTable table = new JTable(model);
    table.setFont(new Font("Serif", Font.PLAIN, 17));
    table.setRowHeight(28);
    JTableHeader header = table.getTableHeader();
    header.setFont(new Font("SansSerif", Font.BOLD, 13));
    panel.add(table, BorderLayout.CENTER);
    panel.add(header, BorderLayout.NORTH);
    panel.setBorder
      (BorderFactory.createTitledBorder("Query Results"));
    return(panel);
  }

  // The panel that contains the textfields, checkboxes,
  // and button.
  
  private JPanel makeControlPanel() {
    JPanel panel = new JPanel(new GridLayout(0, 1));
    panel.add(makeHostPanel());
    panel.add(makeUsernamePanel());
    panel.add(makeQueryPanel());
    panel.add(makeButtonPanel());
    panel.setBorder
      (BorderFactory.createTitledBorder("Query Data"));
    return(panel);
  }

  // The panel that has the host and db name textfield and
  // the driver radio buttons. Placed in control panel.
  
  private JPanel makeHostPanel() {
    JPanel panel = new JPanel();
    panel.add(new JLabel("Host:"));
    hostField = new JTextField(15);
    panel.add(hostField);
    panel.add(new JLabel("    DB Name:"));
    dbNameField = new JTextField(15);
    panel.add(dbNameField);
    panel.add(new JLabel("    Driver:"));
    ButtonGroup vendorGroup = new ButtonGroup();
    oracleButton = new JRadioButton("Oracle", true);
    vendorGroup.add(oracleButton);
    panel.add(oracleButton);
    sybaseButton = new JRadioButton("Sybase");
    vendorGroup.add(sybaseButton);
    panel.add(sybaseButton);
    return(panel);
  }

  // The panel that has the username and password textfields.
  // Placed in control panel.
  
  private JPanel makeUsernamePanel() {
    JPanel panel = new JPanel();
    usernameField = new JTextField(10);
    passwordField = new JPasswordField(10);
    panel.add(new JLabel("Username: "));
    panel.add(usernameField);
    panel.add(new JLabel("    Password:"));
    panel.add(passwordField);
    return(panel);
  }

  // The panel that has textfield for entering queries.
  // Placed in control panel.
  
  private JPanel makeQueryPanel() {
    JPanel panel = new JPanel();
    queryField = new JTextField(40);
    queryField.addActionListener(this);
    panel.add(new JLabel("Query:"));
    panel.add(queryField);
    return(panel);
  }

  // The panel that has the "Show Results" button.
  // Placed in control panel.
  
  private JPanel makeButtonPanel() {
    JPanel panel = new JPanel();
    showResultsButton = new JButton("Show Results");
    showResultsButton.addActionListener(this);
    panel.add(showResultsButton);
    return(panel);
  }

  // Shows warning when bad query sent.
  
  private JLabel makeErrorLabel() {
    JLabel label = new JLabel("No Results", JLabel.CENTER);
    label.setFont(new Font("Serif", Font.BOLD, 36));
    return(label);
  }
}

EmployeeTest2.java: A test case for the database utilities. Prints results formatted as an HTML table.

Huge Sell on Popular Electronics

package cwp;

import java.sql.*;

/** Connect to Oracle or Sybase and print "employees" table
 *  as an HTML table.
 *  
 */

public class EmployeeTest2 {
  public static void main(String[] args) {
    if (args.length < 5) {
      printUsage();
      return;
    }
    String vendorName = args[4];
    int vendor = DriverUtilities.getVendor(vendorName);
    if (vendor == DriverUtilities.UNKNOWN) {
      printUsage();
      return;
    }
    String driver = DriverUtilities.getDriver(vendor);
    String host = args[0];
    String dbName = args[1];
    String url =
      DriverUtilities.makeURL(host, dbName, vendor);
    String username = args[2];
    String password = args[3];
    String query = "SELECT * FROM employees";
    DBResults results =
      DatabaseUtilities.getQueryResults(driver, url,
                                        username, password,
                                        query, true);
    System.out.println(results.toHTMLTable("CYAN"));
  }

  private static void printUsage() {
    System.out.println("Usage: EmployeeTest2 host dbName " +
                       "username password oracle|sybase.");
  }
}

DBResults.java: Class to store completed results of a JDBC Query. Differs from a ResultSet in several ways

Huge Sell on Popular Electronics

# DBResults.java  Class to store completed results of a JDBC Query. Differs from a ResultSet in several ways:

    * ResultSet doesn?t necessarily have all the data; reconnection to database occurs as you ask for later rows.
    * This class stores results as strings, in arrays.
    * This class includes DatabaseMetaData (database product name and version) and ResultSetMetaData (the column names).
    * This class has a toHTMLTable method that turns the results into a long string corresponding to an HTML table.

package cwp;

import java.sql.*;
import java.util.*;

/** Class to store completed results of a JDBC Query.
 *  Differs from a ResultSet in several ways:
 *  
     *    
    ResultSet doesn't necessarily have all the data;
     *        reconnection to database occurs as you ask for
     *        later rows.
     *    
    This class stores results as strings, in arrays.
     *    
    This class includes DatabaseMetaData (database product
     *        name and version) and ResultSetMetaData
     *        (the column names).
     *    
    This class has a toHTMLTable method that turns
     *        the results into a long string corresponding to
     *        an HTML table.
     *  
 *  
 */

public class DBResults {
  private Connection connection;
  private String productName;
  private String productVersion;
  private int columnCount;
  private String[] columnNames;
  private Vector queryResults;
  String[] rowData;

  public DBResults(Connection connection,
                   String productName,
                   String productVersion,
                   int columnCount,
                   String[] columnNames) {
    this.connection = connection;
    this.productName = productName;
    this.productVersion = productVersion;
    this.columnCount = columnCount;
    this.columnNames = columnNames;
    rowData = new String[columnCount];
    queryResults = new Vector();
  }

  public Connection getConnection() {
    return(connection);
  }
  
  public String getProductName() {
    return(productName);
  }

  public String getProductVersion() {
    return(productVersion);
  }

  public int getColumnCount() {
    return(columnCount);
  }

  public String[] getColumnNames() {
    return(columnNames);
  }

  public int getRowCount() {
    return(queryResults.size());
  }

  public String[] getRow(int index) {
    return((String[])queryResults.elementAt(index));
  }

  public void addRow(String[] row) {
    queryResults.addElement(row);
  }

  /** Output the results as an HTML table, with
   *  the column names as headings and the rest of
   *  the results filling regular data cells.
   */
  
  public String toHTMLTable(String headingColor) {
    StringBuffer buffer =
      new StringBuffer("\n");
    if (headingColor != null) {
      buffer.append("  \n    ");
    } else {
      buffer.append("  \n    ");
    }
    for(int col=0; col" + columnNames[col]);
    }
    for(int row=0; row\n    ");
      String[] rowData = getRow(row);
      for(int col=0; col" + rowData[col]);
      }
    }
    buffer.append("\n");
    return(buffer.toString());
  } 
}

DatabaseUtilities.java: Several general-purpose utilities discussed and used in the chapter.

Huge Sell on Popular Electronics

package cwp;

import java.sql.*;

/** Three database utilities:

 *   1) getQueryResults. Connects to a database, executes
 *      a query, retrieves all the rows as arrays
 *      of strings, and puts them inside a DBResults
 *      object. Also places the database product name,
 *      database version, and the names of all the columns
 *      into the DBResults object. This has two versions:
 *      one that makes a new connection and another that
 *      uses an existing connection. 


 *   2) createTable. Given a table name, a string denoting
 *      the column formats, and an array of strings denoting
 *      the row values, this method connects to a database,
 *      removes any existing versions of the designated
 *      table, issues a CREATE TABLE command with the
 *      designated format, then sends a series of INSERT INTO
 *      commands for each of the rows. Again, there are
 *      two versions: one that makes a new connection and
 *      another that uses an existing connection. 


 *   3) printTable. Given a table name, this connects to
 *      the specified database, retrieves all the rows,
 *      and prints them on the standard output.
 */

public class DatabaseUtilities {
  
  /** Connect to database, execute specified query,
   *  and accumulate results into DBRresults object.
   *  If the database connection is left open (use the
   *  close argument to specify), you can retrieve the
   *  connection via DBResults.getConnection.
   */
  
  public static DBResults getQueryResults(String driver,
                                          String url,
                                          String username,
                                          String password,
                                          String query,
                                          boolean close) {
    try {
      Class.forName(driver);
      Connection connection =
        DriverManager.getConnection(url, username, password);
      return(getQueryResults(connection, query, close));
    } catch(ClassNotFoundException cnfe) {
      System.err.println("Error loading driver: " + cnfe);
      return(null);
    } catch(SQLException sqle) {
      System.err.println("Error connecting: " + sqle);
      return(null);
    }
  }

  /** Retrieves results as in previous method, but uses
   *  an existing connection instead of opening a new one.
   */
  
  public static DBResults getQueryResults(Connection connection,
                                          String query,
                                          boolean close) {
    try {
      DatabaseMetaData dbMetaData = connection.getMetaData();
      String productName =
        dbMetaData.getDatabaseProductName();
      String productVersion =
        dbMetaData.getDatabaseProductVersion();
      Statement statement = connection.createStatement();
      ResultSet resultSet = statement.executeQuery(query);
      ResultSetMetaData resultsMetaData =
        resultSet.getMetaData();
      int columnCount = resultsMetaData.getColumnCount();
      String[] columnNames = new String[columnCount];
      // Column index starts at 1 (ala SQL) not 0 (ala Java).
      for(int i=1; i                                

EmployeeTest.java: A test case for the database utilities. Prints results in plain text.

Huge Sell on Popular Electronics

package cwp;

import java.sql.*;

/** Connect to Oracle or Sybase and print "employees" table.
 *  


 */

public class EmployeeTest {
  public static void main(String[] args) {
    if (args.length < 5) {
      printUsage();
      return;
    }
    String vendorName = args[4];
    int vendor = DriverUtilities.getVendor(vendorName);
    if (vendor == DriverUtilities.UNKNOWN) {
      printUsage();
      return;
    }
    String driver = DriverUtilities.getDriver(vendor);
    String host = args[0];
    String dbName = args[1];
    String url =
      DriverUtilities.makeURL(host, dbName, vendor);
    String username = args[2];
    String password = args[3];
    DatabaseUtilities.printTable(driver, url,
                                 username, password,
                                 "employees", 12, true);
  }

  private static void printUsage() {
    System.out.println("Usage: EmployeeTest host dbName " +
                       "username password oracle|sybase.");
  }
}