Waite Group¿s Java 1.2 How-To

Overview

The Waite Group's Java 1.2 How-To is the definitive problem solver - designed to answer your "How do I" questions. It is intended to be a reference for Java programmers. Organized by individual questions, this exhaustive reference addresses practical, real-world programming issues in a clear, easy-to-follow language. Professional Java developer Steve Potts presents definitive answers in a step-by-step format followed by concise descriptions of the outcome of each step. The Waite Group's Java 1.2 How-To covers the...
See more details below
Available through our Marketplace sellers.
Other sellers (Paperback)
  • All (7) from $1.99   
  • New (1) from $87.60   
  • Used (6) from $0.00   
Close
Sort by
Page 1 of 1
Showing All
Note: Marketplace items are not eligible for any BN.com coupons and promotions
$87.60
Seller since 2008

Feedback rating:

(210)

Condition:

New — never opened or used in original packaging.

Like New — packaging may have been opened. A "Like New" item is suitable to give as a gift.

Very Good — may have minor signs of wear on packaging but item works perfectly and has no damage.

Good — item is in good condition but packaging may have signs of shelf wear/aging or torn packaging. All specific defects should be noted in the Comments section associated with each item.

Acceptable — item is in working order but may show signs of wear such as scratches or torn packaging. All specific defects should be noted in the Comments section associated with each item.

Used — An item that has been opened and may show signs of wear. All specific defects should be noted in the Comments section associated with each item.

Refurbished — A used item that has been renewed or updated and verified to be in proper working condition. Not necessarily completed by the original manufacturer.

New

Ships from: Chicago, IL

Usually ships in 1-2 business days

  • Standard, 48 States
  • Standard (AK, HI)
Page 1 of 1
Showing All
Close
Sort by
Sending request ...

Overview

The Waite Group's Java 1.2 How-To is the definitive problem solver - designed to answer your "How do I" questions. It is intended to be a reference for Java programmers. Organized by individual questions, this exhaustive reference addresses practical, real-world programming issues in a clear, easy-to-follow language. Professional Java developer Steve Potts presents definitive answers in a step-by-step format followed by concise descriptions of the outcome of each step. The Waite Group's Java 1.2 How-To covers the vital areas, including new areas like JFC for creating interfaces and Java Media Framework for multimedia programming.
Read More Show Less

Product Details

  • ISBN-13: 9781571691576
  • Publisher: Sams
  • Publication date: 6/26/1998
  • Edition description: REV
  • Edition number: 1
  • Pages: 672
  • Product dimensions: 7.45 (w) x 9.19 (h) x 1.73 (d)

Table of Contents

Introduction 1
Ch. 1 Java Explained 3
Ch. 2 Getting Started 13
Ch. 3 Basic Graphics 53
Ch. 4 Threads 103
Ch. 5 Events and Parameters 155
Ch. 6 User Interface Development 189
Ch. 7 Advanced Graphics 249
Ch. 8 JFC 311
Ch. 9 Multimedia 347
Ch. 10 Networking 383
Ch. 11 Miscellaneous and Advanced Topics 425
App. A Java Platform Core Packages 469
App. B Deprecated APIS 475
App. C JDK 1.2 API Description 493
Index 641
Read More Show Less

First Chapter

[Figures are not included in this sample chapter]

The Waite Group's Java 1.2 How-To
- 3 -
Basic Graphics

How do I...

  • 3.1 Draw a line?
  • 3.2 Add color?
  • 3.3 Draw shapes?
  • 3.4 Fill shapes?
  • 3.5 Draw text?
  • 3.6 Use fonts?
  • 3.7 Handle screen updates?
  • 3.8 Print applet status messages?

All the examples in Chapter 2, "Getting Started," are text-only applications.In this chapter, basic graphics are demonstrated as applets and applications. Graphicsmake programs more aesthetically appealing and are almost a requirement in modernend-user software. Applets are small programs that can be downloaded to client machinesvia popular Web browsers such as Netscape Navigator. Applets are embedded in Webpages through HTML tags. When a Java-enabled browser reaches a page with such a tag,it downloads the applet code and executes it on the client machine. By default, appletsare somewhat constrained with respect to access of the client system resources, withthe goal that they will not present a security risk. These constraints are modestand allow the programmer enough freedom to explore a variety of interactive ideas.Java graphics require a familiarity with several classes:

  • A frame is an object that is capable of containing a title bar and a menu bar. A frame cannot be contained by another object.
  • A panel is a generic container that can hold other graphical controls. A panel can be assigned its own layout manager.

Java supports many different types of graphics objects. Many of the simple onesare included in the Abstract Windowing Toolkit (AWT). Java2D, a new addition in Java1.2, adds user defined coordinates, gradient fills, and patterns to the list of Javagraphics.

3.1 Draw a Line

The first step in creating graphics is drawing lines and points on the screen.In this example a sine curve is plotted on a graph with axes. It demonstrates theuse of basic classes contained in the AWT and the basic parts of an applet.

3.2 Add Color

The next step in creating attractive graphics is adding color. This example draws"flying" lines that continuously change color.

3.3 Draw Shapes

The Java API includes methods for drawing rectangles, ovals, arcs, and polygons.You can use variations of these basic shapes to create other shapes such as circles,squares, and triangles. In this example you will read a file containing shape descriptionrecords and draw them. This example can be used only as an application because itmust read files from a local disk.

3.4 Fill Shapes

Java supports drawing of filled shapes. This example shows how to fill severalshapes by defining classes for plotting bar charts and pie charts. These classescould be used in other applets and applications.

3.5 Draw Text

Drawing text is fundamental to graphics toolkits. In this example, classes aredefined to create scrolling text. This type of animation is currently used in manyWeb pages.

3.6 Use Fonts

Text in Java programs can be displayed in multiple fonts and styles. This examplelists the available fonts and styles and demonstrates their use.

3.7 Handle Screen Updates

Screen updates in Java are handled by the update() method. If no update() methodis declared, the default method is used. The default method sometimes performs anoperation that is not desired. This example shows how to create a custom update()method to avoid flickering.

3.8 Print Applet Status Messages

You can access the status bar in the Appletviewer, Netscape browser, or anotherJava-enabled application. Java includes a method that causes a message to be printedin the status bar. This example demonstrates how to print in the status bar.

3.1 How do I... Draw a line?


COMPLEXITY: BEGINNING

Problem

I'd like to draw lines to the screen and be able to plot a mathematical functionlike the sine curve. I also want to plot both x and y axes. This can be done by drawinglines only. I know how to access math functions and generate values for plotting,but I don't know how to draw lines. How do I draw lines?

Technique

The Java graphics API, known as the AWT, supports many of the graphics primitivesprogrammers expect, the simplest being drawLine(). The drawLine() method is containedin the Graphics class and takes four integers as arguments. These integers are thex and y values of the starting and the ending points of the line. Figure 3.1 showsan example of the running applet.

FIGURE 3.1 The Sine applet demonstrates the use of simple graphics.

Steps

1. Create the applet source file. Create a new file called Sine.java and enter the following source:
import java.applet.Applet;import java.awt.*;/** * Sine curve applet/application * Draws one cycle of a sine curve. */public class Sine extends Applet {/* * width and height of the applet panel */int width, height;/* * init() is called when the applet is loaded * just get the width and height and save it */public void init () {       setLayout(null);       width = 300;       height = 300;       setSize(width, height);}/** * paint() does the drawing of the axes and sine curve * @param g - destination graphics object */public void paint (Graphics g) {       int x, x0;       double y0, y, A, f, t, offset;              A = (double) height / 4;        f = 2;       offset = (double) height / 2;       x0 = 0;       y0 = offset;              g.drawLine (x0, (int) y0, width, (int) y0);       g.drawLine (width/2, 0, width/2, height);       for (x=0; x<width; x+=1) {              t = (double) x / ((double) width);              y = offset - A * Math.sin (2 * Math.PI * f * t);              g.drawLine (x0, (int) y0, x, (int) y);              x0 = x;              y0 = y;       }}}
2. Create an HTML document that contains the applet. Create a new file called howto31.html that contains the following code:
<html><head><title>Sine curve</title></head><applet code="Sine.class" width=300 height=300></applet><hr size=4></html>
3. Co mpile and test the applet. Compile the source by using javac or the makefile provided. Test the applet by using the Appletviewer; enter the following command:
APPLETVIEWER howto31.html
You can also run Sine.java as an application by typing
java Sine
When Sine is executed, a window will pop up with a sine curve drawn on a set of axes.

How It Works

All classes that are to be used in an applet must be subclasses of the Appletclass. The Appletviewer, Web browser, or another application that supports appletscan load an applet class and execute it. Execution of an applet begins with the init()method. After return from init(), the applet start() method is called. One or bothof these methods may be defined (that is, overridden). The init() method is calledwhen an applet is first loaded; typically this is used for initialization purposes.The start() method is called after the init() method and whenever the user returnsto a previously visited page in a Web browser. A stop() method, which is called whena user leaves a Web browser page, may also be defined. This method is typically usedto stop threads and perform cleanup actions. The destroy() method is called by thebrowser or Appletviewer to inform this applet that it is being destroyed. This givesyou a chance to clean up your code.

If an applet is executed as a standalone application, as are the examples fromChapter 2, the Java interpreter produces an error noting that a main() method wasnot found. To make an applet run as a standalone application, all that is neededis the addition of a main() method, which creates a window for the applet and aninstance of the applet. This is what the main() method does in the preceding example.When the main() method is called, it creates a window frame by calling the Frame()constructor with the window title as an argument. An instance of the applet itselfis created by the call to the Sine() constructor. The instance of Sine() is placedin the center of the window frame by the add() method. This can be done because Appletis a subclass of Panel. This is discussed in greater detail in later chapters.

The init() method assigns a width and height. If the program is used as an applet,the size will be the dimensions specified by the width and height attributes of the<applet> tag in the associated HTML file.

The paint() method is called asynchronously by the Java runtime. It is actuallycalled from the update() method, which itself is called in response to update eventssuch as initialization and window expose events. Each time a Java window is createdor exposed, all update() methods of all panels within that window are called. Inthis case, a sine curve with axes is plotted.

The x and y axes are plotted first, each with a call to drawLine(). The argumentsto drawLine() are the x and y coordinates of the starting and ending points of theline. The coordinate system is like most other windowing systems; that is, 0,0 isthe top left, with increasing values moving down and right. Figure 3.2 shows an exampleof the Java screen coordinate system.

FIGURE 3.2 The Java screen coordinate system uses the top left as its origin.

The axes are drawn in the center of the window by using the width and height tocalculate the coordinates.

The sine curve is plotted by using the sin() method, from the Math class, anddrawLine(). The sin() and drawLine() methods are called within a for loop that variesthe value of x from 0 to the panel width. The sin() method computes the value ofy. The sin() method returns a double between -1.0 and 1.0, which is scaled and translatedappropriately to the window coordinates. The call to drawLine() in this case drawsa line from the previous calculated value to the current calculated value. This ineffect draws several small lines that look like a continuous sine curve.

Comments

In many cases, applets may be used as applications by the mechanism describedin this example. There are, of course, cases in which both execution environmentscannot be supported. These are explored in later examples.

The argument g to the paint() method is similar to a graphics or device contextfound in other windowing systems such as X Window, Macintosh, and Windows. It containsall the information you might expect, such as foreground color and font.

In effect, a device context holds a set of current settings for all drawing objects.If you change the stroke width of the device context, all lines drawn will be drawnwith that stroke until you change it.

The main() method could have been placed in a separate class and could have performedthe same function. However, the name of the class containing the main() method, ratherthan the Applet class name, would have to be specified to the Java interpreter.

Note that the Appletviewer provided in the Sun JDK is itself written in Java.Based on this example, you can speculate about how some of it works.

3.2 How do I... Add color?


COMPLEXITY: BEGINNING

Problem

Whenever graphics are displayed or created, adding color is important. In today'sworld of multimedia and high-impact documents, understanding how to use color isespecially important. I want to demonstrate the use of color by drawing "flying"lines that continuously change color similarly to many screensaver programs thatare in use today. I learned how to draw lines in the previous example. How do I addcolor?

Technique

The Graphics class passed to the paint() method controls the current color usedwhen drawing to the screen. The foreground color is changed by calling the setColor()method from the Graphics class. The argument to setColor() is a Color object. TheColor class has several fixed colors defined, but it also contains methods to allocatearbitrary colors given red, green, and blue component values.

In this example, 24 different colors are allocated. These colors are used to setthe foreground color of the flying lines. Figure 3.3 shows an example of the runningapplet.

FIGURE 3.3 This applet creates colored lines.

Steps

1. Create the applet source file. Create a new file called Lines.java and enter the following source:
import java.applet.Applet;import java.awt.*;/** * class LineColors holds 24 color values */class LineColors {/** * color[] array holds the colors to be used */Color color[];/** * class constructor * initializes the color array using an arbitrary algorithm */public LineColors () {       color = new Color[24];       int i, rgb;       rgb = 0xff;       for (i=0; i<24; i+=1) {              color[i] = new Color (rgb);              rgb <<= 1;              if ((rgb & 0x1000000) != 0) {                     rgb |= 1;                     rgb &= 0xffffff;              }       }}}/** * class describing one line segment */class Segment {/* * x1, y1 - starting coordinates for this segment * x2, y2 - ending coordinates for this segment * dx1,...dy2 - velocities for the endpoints* whichcolor - the current index into color array * width, height - width and height of bounding panel * LC - instance of LineColors class */double x1, y1, x2, y2;double dx1, dy1, dx2, dy2;int whichcolor, width, height;LineColors LC;/** * class constructor * initialize endpoints and velocities to random values * @param w - width of bounding panel * @param h - height of bounding panel * @param c - starting color index * @param lc - instance of LineColors class */public Segment (int w, int h, int c, LineColors lc) {       whichcolor = c;       width = w;       height = h;       LC = lc;       x1 = (double) w * Math.random ();       y1 = (double) h * Math.random ();       x2 = (double) w * Math.random ();       y2 = (double) h * Math.random ();       dx1 = 5 - 10 * Math.random ();       dy1 = 5 - 10 * Math.random ();       dx2 = 5 - 10 * Math.random ();       dy2 = 5 - 10 * Math.random ();}/* * increment color index * calculate the next endpoint position for this segment */void compute () {       whichcolor += 1;       whichcolor %= 24;              x1 += dx1;       y1 += dy1;       x2 += dx2;       y2 += dy2;       if (x1 < 0 || x1 > width) dx1 = -dx1;       if (y1 < 0 || y1 > height) dy1 = -dy1;       if (x2 < 0 || x2 > width) dx2 = -dx2;       if (y2 < 0 || y2 > h eight) dy2 = -dy2; }/** * draw the line segment using the current color * @param g - destination graphics object */void paint (Graphics g) {       g.setColor (LC.color [whichcolor]);       g.drawLine ((int) x1, (int) y1, (int) x2, (int) y2);}}/** * The applet/application proper */public class Lines extends Applet {/* * Nlines - number of line segments to be displayed * lines - array of instances of Segment class * LC - instance of LineColors class */int width,height;final int NLines = 4;Segment lines[] = new Segment[NLines];LineColors LC = new LineColors ();/** * init is called when the applet is loaded * save the width and height * create instances of Segment class */public void init () {       setLayout(null);       width = 300;       height = 300;       setSize(width, height);              int i;       for (i=0; i<NLines; i+=1)              lines[i] = new Segment (width, height, (2*i) % 24, LC);}/** * recompute the next endpoint coordinates for each line * invoke paint() method for each line * call repaint() to force painting 50ms. later * @param g - destination graphics object */public void paint (Graphics g) {       int i;       for (i=0; i<NLines; i+=1) {              lines[i].compute ();              lines[i].paint (g);       }       repaint (50); }}
2. Create an HTML document that contains the applet. Create a new file called howto32.html that contains the following code:
<html><head><title>Flying Lines</title></head><applet code="Lines.class" width=300 height=300></applet><hr size=4></html>
3. Compile and test the applet. Compile the source by using javac or the makefile provided. Test the applet by using the Appletviewer; enter the following command:
APPLETVIEWER howto32.html
When Lines is executed, a window pops up with four lines that bounce around while continuously changing color.

How It Works

Two classes are defined in addition to the applet itself: LineColors and Segment.LineColors contains an array of 24 colors. The color values are initialized by theLineColors constructor, which uses the Color() constructor to allocate new colors.One of the Color constructors takes a single-integer argument, which specifies thered, green, and blue (RGB) color components in the lower 24 bits: the red componentin bits 16-23, the green component in bits 8-15, and the blue component in bits 0-7(the least significant byte). The colors allocated in this example blend from blueto green to red in 24 steps. The algorithm rotates a full saturation bit patternto generate the RGB values.

The Segment class describes a single line segment. It contains the endpoints ofthe segment, their velocities, an instance of LineColors, and an index to the currentcolor of the segment. In addition to the constructor, a compute() method and a paint()method are defined. The constructor initializes the endpoints and velocities to randomvalues using the Math.random() method. Math.random() returns a positive double between0 and 1, which is scaled appropriately. The compute() method advances the color indexand integrates the endpoints of the segment, implementing ideal reflection at theboundary. This gives the effect of bouncing. The paint() method sets the foregroundcolor to the current color index using setColor() and draws the line.

< P>The applet creates four line segments and stores them in an array. When the applet'spaint() method is called in response to an update, it calls the compute() and paint()methods of the respective line segments in the array. In effect, these methods telleach line segment to compute and paint itself.

An applet can force an update by calling repaint(). This is what the example doesto repeatedly draw the line segments in an animated fashion. repaint() queues updaterequests, which are later serviced by update(). Figure 3.4 shows the relationshipbetween repaint(), update(), and paint(). The default update() method fills the appletpanel with its background color and calls paint(). repaint() can take an integerargument, which specifies the time in milliseconds when the next update should occur.In this example the value 50 milliseconds is used. The final result is that the applet'spaint() method is called approximately 20 times per second, producing the illusionof smooth motion.

FIGURE 3.4 repaint(), update(), and paint() work together to display graphics.

Comments

The Color class contains several predefined colors. Their types are defined asstatic final Color(), so they can be used without creating an instance of Color.For example, the following code fragment sets the foreground color to magenta:

void paint (Graphics g) {    g.setColor (Color.magenta);...}

The predefined colors are listed in Table 3.1.

TABLE 3.1  Java Predefined Colors

PREDEFINED COLOR RGB VALUES
black (0,0,0)
blue (0,0,255)
cyan (0,255,255)
darkGray (64,64,64)
gray (128,128,128)
green (0,255,0)
lightGray (192,192,192)
magenta (255,0,255)
orange (255,200,0)
pink (255,175,175)
red (255,0,0)
white (255,255,255)
yellow (255,255,0)


The Color class contains several constructors, which take color values in a varietyof formats. In addition, useful utility methods are also included. Table 3.2 liststhe constructors and methods contained in class Color.

TABLE 3.2  Color Constructors and Methods

METHOD DESCRIPTION
Color(int, int, int)
(Constructor) Creates a color with the specified red, green, and blue values in the range 0-255
Color(int)
(Constructor) Creates a color with the specified combined RGB value consisting of the red component in bits 16-23, the green component in bits 8-15, and the blue component in bits 0-7
Color(float, float, float)
(Constructor) Creates a color with the specified red, green, and blue values in the range 0.0-1.0
HSBtoRGB(float, float, float)
Returns the RGB value, defined by the default RGB ColorModel, of the color corresponding to the given HSB (hue, saturation, brightness) color components
RGBtoHSB(int, int, int, float[])
Returns the HSB values corresponding to the color defined by the red, green, and blue components
brighter()
Returns a brighter version of this color
darker()
Returns a darker version of this color
equals(Object)
Compares this object against the specified object
getBlue()
Gets the blue component
getColor(String)
Gets the specified Color property
getColor(String, Color)
Gets the specified Color property of the specified color
getColor(String, int)
Gets the specified Color property of the color value
GetGreen()
Gets the green component
GetHSBColor(float, float, float)
A static color factory for generating a Color object from HSB values
getRGB()
Gets the RGB value representing the color in the default RGB ColorModel
getRed()
Gets the red component
HashCode()
Computes the hash code
toString()
Returns the String representation of this color's values


Colors allocated in Java are not necessarily exact. The runtime attempts to finda color that is closest to the one requested. This, of course, is platform dependent.

The repeated calls to paint() and repaint() may appear to be recursive, but theyare not. repaint() queues update requests and issues them asynchronously. In fact,there may not necessarily be a one-to-one correspondence between calls to repaint()and calls to update(). update() is called at the next convenient time.

3.3 How do I... Draw shapes?


COMPLEXITY: BEGINNING

Problem

I want to write a simple interpreter capable of drawing standard shapes such asrectangles, ovals, and polygons. I want the program to accept input from a text fileand interpret the text to draw the objects specified. I know how to read lines froma file and break them up into tokens, but how do I draw shapes?

Technique

This example combines many aspects discussed in Chapter 2, such as reading filesand string tokenizing, with an example of how to draw shapes. The Java AWT supportsall the graphic primitives mentioned earlier. Similarly to drawLine(), (example 3.1),additional graphics primitives are contained in the Graphics class. They may be calledfrom an application's paint() method as before.

The text file contains one shape definition per line, with parameters separatedby spaces. The grammar of a line of the text file is as follows:

<color>    <shape>

Where <color> is one of the following:

WHITE | LIGHTGRAY | GRAY | DARKGRAY | BLACK | RED | PINK | ORANGE | YELLOW | GREEN| MAGENTA | CYAN | BLUE

and <shape> is one of the following shapes along with necessary parameters:

RECT top-left width heightOVAL top-left width heightARC top-left width height startangle arcanglePOLY x1 y1 x2 y2 x3 y3 [ x4 y4 ...]

Each line in the input file is read and split into tokens by using StringTokenizer(),as shown in Chapter 2. Each line is then checked to ensure that it is valid and inproper format. A valid line is used to create a Shape object described by the parametersin that line. An array of shape objects is maintained and painted in response toan update.

Applets cannot directly access disk files, so this example can be run only asan application. Figure 3.5 shows an example of the output.

FIGURE 3.5 The DrawApp application shows the use of predefined shapes in applets.

Steps

1. Create the application source file. Create a new file called DrawApp.java and enter the following source:
import java.applet.Applet;import java.awt.*;import java.awt.event.*;import java.io.*;import java.util.StringTokenizer;/** * class describing a shape */class Shape {/** * constants for the shape type */static final int rectType = 1;static final int ovalType = 2;static final int arcType = 3;static final int polyType = 4;/* * the shape type */int type;/* * color for this shape */Color color;static final int MaxPoints = 10;/* * arrays of x and y points for this shape */int xp[] = new int[MaxPoints];int yp[] = new int[MaxPoints];/* * the number of points in this shape */int npoints;/** * shape constructor * saves parameters * @param tp - shape type * @param n - number of points * @param pts[] - array of endpoints * @param c - color of the shape */public Shape (int tp, int n, int pts[], Color c) {       int i;      type = tp;      color = c;      npoints = n < MaxPoints ? n : MaxPoints;      if (type == polyType) {            npoints >>= 1;            for (i=0; i<npoints; i+=1) {                  xp[i] = pts[i << 1];                  yp[i] = pts[(i << 1) +1];            }      } else {            for (i=0; i<npoints; i+=1)                  xp[i] = pts[i];      }}/** * draw the shape * @param g - destination graphics object */void paint (Graphics g) {      g.setColor (color);      switch (type) {      case rectType:            g.drawRect (xp[0], xp[1], xp[2], xp[3]);            break;      case ovalType:            g.drawOval (xp[0], xp[1], xp[2], xp[3]);            break;      case arcType:             g.drawArc (xp[0], xp[1], xp[2], xp[3], xp[4], xp[5]);break;      case polyType:            g.drawPolygon (xp, yp, npoints);            break;      }}}/** * application class proper */public class DrawApp extends Panel {/* * the maximum number of shapes allowed */static final int MaxShapes = 25;/* * nshapes - the number of shapes read in * nlines - the line number in the input file */static int nshapes, nlines = 0;/* * array of instances of class shape */static Shape shapes[] = new Shape[MaxShapes];/** * invoke paint() method for each shape * @param g - destination graphics object */public void paint (Graphics g) {      int i;      for (i=0; i<nshapes; i+=1)            shapes[i].paint (g);}/** * application entry point * @param args - command-line arguments */public static void main (String args[]) {      String buf;      FileInputStream fs=null;      int i, type = 0;      if (args.length != 1) {            System.out.println ("usage: java DrawApp <file>");            System.exit (1);      }/* * Try to open the file specified by args[0] */      try {            fs = new FileInputStream (args[0]);      } catch (Exception e) {            System.out.println (e);            System.exit (1);      }/* * Create a DataInputStream BufferedReader  * associated with FileInputStream fs*/      BufferedReader ds = new BufferedReader(new InputStreamReader(fs));String token;      Color color = Color.white;      int pts[] = new int[2 * Shape.MaxPoints];/* * loop until end of file or error * read a line and parse it */      while (true) {            try {                  buf = ds.readLine ();      // read 1 line                  if (buf == null) break;            } catch (IOException e) {                  System.out.println (e);      break;            }            nlines += 1;            StringTokenizer st = new StringTokenizer (buf);             token = st.nextToken ();            if (token.equals ("white")) {                  color = Color.white;                  token = st.nextToken ();            } else if (token.equals ("lightgray")) {                  color = Color.lightGray;                  token = st.nextToken ();            } else if (token.equals ("gray")) {                  color = Color.gray;                  token = st.nextToken ();            } else if (token.equals ("darkgray")) {                  color = Color.darkGray;                  token = st.nextToken ();            } else if (token.equals ("black")) {                  color = Color.black;                  token = st.nextToken () ;            } else if (token.equals ("red")) {                  color = Color.red;                  token = st.nextToken ();            } else if (token.equals ("pink")) {                  color = Color.pink;                  token = st.nextToken ();            } else if (token.equals ("orange")) {                  color = Color.orange;                  token = st.nextToken ();            } else if (token.equals ("yellow")) {                  color = Color.yellow;                  token = st.nextToken ();            } else if (token.equals ("green")) {                  color = Color.green;                  token = st.nextToken ();            } else if (token.equals ("magenta")) {                  color = Color.magenta;                  token = st.nextToken ();            } else if (token.equals ("cyan")) {                  color = Color.cyan;                  token = st.nextToken ();            } else if (token.equals ("blue")) {                  color = Color.blue;                  token = st.nextToken ();            } else {                  System.out.println ("Unknown color: "+token);                  System.out.println ("line "+nlines);                  System.exit (1);            }            int npoints = 0;            if (token.equals ("rect")) {                  npoints = getInt (st, pts, 4);                   type = Shape.rectType;            } else if (token.equals ("oval")) {                  npoints = getInt (st, pts, 4);                  type = Shape.ovalType;            } else if (token.equals ("arc")) {                  npoints = getInt (st, pts, 6);              type = Shape.arcType;            } else if (token.equals ("poly")) {                  npoints = getInt (st, pts, Shape.MaxPoints);                  type = Shape.polyType;            } else {                  System.out.println ("Unknown shape: "+token);                  System.out.println ("line "+nlines);                  System.exit (1);            }            shapes[nshapes++] = new Shape (type, npoints, pts, color);}/* * close can throw an exception also; catch it for completeness */      try {            fs.close ();      } catch (IOException e) {            System.out.println (e);      }      Frame f = new Frame ("Drawing shapes");      DrawApp drawApp = new DrawApp ();      f.setSize(410, 430);      f.addWindowListener(new WindowCloser());      f.add ("Center", drawApp);      f.show ();}/** * parse points * @param st - StringTokenizer for current line * @param pts[] - array of points to be returned * @param nmax - maximum number of points to accept */static int getInt (StringTokenizer st, int pts[], int nmax) {      int i;      String token;      for (i=0; i<nmax; i+=1) {            if (st.hasMoreTokens () == false) break;            token = st.nextToken ();            try {                  pts[i] = Integer.valueOf (token).intValue ();            } catch (NumberFormatException e) {                  System.out.println (e);                  System.out.println ("line "+nlines);                  System.exit (1);            }      }      return i;}}class WindowCloser extends WindowAdapter{    public void windowClosing(WindowEvent e)    {        Window win = e.getWindow();        win.setVisible(false);        win.dispose( );        System.exit(0);    }//windowClosing}//class WindowCloser
2. Create the text file containing the shape definitions. Create a new file called testfile and enter the following text:
red rect 10 10 100 50green oval 50 50 50 30blue arc 75 75 60 70 45 90cyan poly 100 100 200 200 300 100 100 100
3. Compile and test the application. Compile the application with javac. DrawApp.java is an application and cannot be run as an applet because it must open and read files from local disks. Test the application by typing
java DrawApp [
filename]
When the application is started, a window opens, and a red rectangle, green oval, blue arc, and cyan polygon are drawn.

4. Try editing testfile by changing colors, adding new shapes, or moving the shapes around. Then run DrawApp again without recompiling. See if you can specify shapes in testfile that actually draw a picture.

How It Works

Unlike previous examples, class DrawApp extends class Panel. As discussed in How-To3.1, Applet is a subclass of Panel and is only needed if a program is to be usedas an applet. This example is used as an application exclusively; therefore, it issufficient to create a subclass of Panel.

The class Shape contains all the information necessary for a given shape. Thisincludes the type of shape, its color, two integer arrays, and the number of pointsin the arrays. The array xp is used to hold the coordinates, width, and height ifthe shape is a rectangle or oval. If the shape is an arc, two more parameters areused: the arc starting angle in degrees, and the number of degrees in the arc relati veto the starting angle. If the shape is a polygon, the xp array holds the x coordinatesof the polygon vertices, and the yp array holds the y coordinates. The number ofvertices in a polygon is stored in the variable npoints. The yp array and variablenpoints are not used if the shape describes anything other than a polygon.

The main() method borrows some techniques used in Chapter 2. It checks command-linearguments for a filename and uses this to open the input file. Upon success, a BufferedReaderis created in order to read from the input file. The file is read one line at a time.Each line is parsed using StringTokenizer() to split a line into tokens. The defaultdelimiters for StringTokenizer() (spaces, tabs, and newlines) are sufficient, sothey are not explicitly defined.

After a valid color is found, the program looks for one of the four possible shapenames in the parameter and then reads the necessary number of points for the givenshape. Rectangles and ovals require four points, whereas arcs require six. Polygonscan take a variable number of points. All these cases are handled by the getInt()method. getInt() reads up to nmax points and returns the number of points actuallyfound. After this is done, a new shape is created with the information parsed fromthe input line and then stored in an array of shapes.

The class Shape contains the paint() method in addition to its constructor. TheShape.paint() method is called from the paint() method in DrawApp, similarly to previousexamples. Shape.paint() sets the foreground color and draws the shape described inthe class.

Comments

Rectangles are described by the top-left corner, width, and height. It is bestto use positive values for width and height in order to avoid anomalous behaviorthat may occur on some platforms. Ovals are described the same way as rectangles;the oval is drawn inside the specified rectangle. Arcs are described by a boundingrectangle along with a starting angle in degrees and the number of degrees in thearc relative to the starting angle. Angles start from the positive x-axis (3 o'clockposition), consistent with standard conventions. Positive arc angles indicate counterclockwiserotations; negative arc angles are drawn clockwise. Arcs are actually sections ofovals. The following code fragments draw the same shape:

drawOval (10, 10, 75, 90);...drawArc (10, 10, 75, 90, 0, 360);...

Polygons are defined by an array of x points and y points. They can be drawn open,meaning that the first and last vertices are not connected. (See Table 3.3.)

TABLE 3.3  Methods for Unfilled Shapes

METHOD DESCRIPTION
draw3DRect(int, int, int, int, boolean)
Draws a highlighted 3D rectangle
drawOval(int, int, int, int)
Draws an oval inside the specified rectangle using the current color
drawPolygon(int[], int[], int)
Draws a polygon defined by an array of x points and y points
drawRect(int, int, int, int)
Draws the outline of the specified rectangle using the current color
drawRoundRect(int,int,int,int,int,int)
Draws an outlined rounded-corner rectangle using the current color
drawArc(int,int,int,int,int,int)
Draws the outline of an arc covering the specified rectangle, starting at startAngle and extending for arcAngle degrees, using the current color
DrawPolyLine(int[],int[],int)
Draws a sequence of connected lines defined by arrays of x coordinates and y coordinates, using the current color


DrawApp can be easily extended to support all the shapes described earlier. Inaddition, filled shapes described in the following example can be added along witharbitrary color support. Other features such as nonuniform rational B-splines (NURBS)could be implemented as line segments.

3.4 How do I... Fill shapes?


COMPLEXITY: BEGINNING

Problem

I want to create classes that can draw bar and pie charts. The two types of chartsshare many similar features, so I want them to share a common superclass. I wantto pass an array of values and colors along with coordinates and dimensions to achart's constructor.

I have a good idea of how to lay out the classes using unfilled shapes, but Iwant these charts to use filled shapes similarly to the graphing utility in manyspreadsheet programs. How do I fill shapes?

Technique

The class Graphics contains filled-shape counterparts to the unfilled shapes describedin the previous example. They are used to do the drawing (Figure 3.6).

FIGURE 3.6 Charts can be drawn using Java classes.

Steps

1. Create the applet source file. Create a new file called ChartApp.java and enter the following source:
import java.applet.Applet;import java.awt.*;/** * parent class */class Chart {/* * x and y positions of the upper-left of the chart * nvalues - number of values for this chart */int xpos, ypos, nvalues;/* * width and height of this chart */int width, height;/* * maximum number of values allowed */final int MaxValues = 10;/* * data values for this chart */double values[] = new double[MaxValues];/* * color associated with each value */Color colors[] = new Color[MaxValues];/* * sum total of values, used for scaling purposes */double total;/** * class constructor * save values and normalizes them so that the max. value is 1.0 * @param x, y - top-left coordinates * @param w, h - width and height * @param n - number of points * @param val[] - array of values * @param c[] - a rray of colors corresponding to values */public Chart (int x, int y, int w, int h, int n, double val[], Color c[]) {      int i;      double extreme;             xpos = x;      ypos = y;      width = w;      height = h;      nvalues = n;      if (nvalues > MaxValues) nvalues = MaxValues;      extreme = 0.0;      for (i=0; i<nvalues; i+=1) {            if (Math.abs (val[i]) > extreme)                  extreme = Math.abs (val[i]);            colors[i] = c[i];       }      extreme = 1/extreme;      total = 0;      for (i=0; i<nvalues; i+=1) {            values[i] = extreme * val[i];            total += values[i];      }}}/** * class implements a bar chart */class BarChart extends Chart {/** * constructor just calls Chart constructor * @param x, y - top left coordinates * @param w, h - width and height * @param n - number of points * @param val[] - array of values * @param c[] - array of colors corresponding to values */public BarChart (int x, int y, int w, int h, int n, double val[], Color c[]) {      super (x, y, w, h, n, val, c);}/** * need to add a paint method * draws the bar chart using fill3DRect * @param g - destination graphics object */void paint (Graphics g) {      int i;      int barwidth = 3 * width / (4 * nvalues);      int bardx = width / nvalues;      int x, y, h;      g.setColor (Color.black);      g.fillRect (xpos, ypos-height, width, height);      for (i=0; i<nvalues; i+=1) {            g.setColor (colors[i]);            x = xpos + bardx*i;            h = (int) (values[i] * height);            y = ypos - h;            g.fill3DRect (x, y, barwidth, h, true);      }}}/** * class implements a pie chart */class PieChart extends Chart {/** * class constructor just calls Char t constructor * @param x, y - top-left coordinates * @param w, h - width and height * @param n - number of points * @param val[] - array of values * @param c[] - array of colors corresponding to values */public PieChart (int x, int y, int w, int h, int n, double val[], Color c[]) {      super (x, y, w, h, n, val, c); }/** * need to add a paint method * draws the pie chart using fillArc * @param g - destination graphics object */void paint (Graphics g) {      int i, y;      int startAngle, arcAngle;            startAngle = 0;      y = ypos - height;      for (i=0; i<nvalues; i+=1) {            arcAngle = (int) (360.0 * values[i] / total);            g.setColor (colors[i]);            g.fillArc (xpos, y, width, height, startAngle, arcAngle); startAngle += arcAngle;      }}}/** * the applet/application  proper */public class ChartApp extends Applet {/* * width and height of the bounding panel */int width, height;/* * instances of BarChart and PieChart */BarChart bc1;PieChart pc1;/* * called when applet is loaded * generate random values and plot them */public void init () {      int i;      double values[] = new double[5];      Color colors[] = new Color[5];            width = 410;       height = 230;      colors[0] = Color.blue;      colors[1] = Color.orange;      colors[2] = Color.yellow;      colors[3] = Color.green;      colors[4] = Color.magenta;      for (i=0; i<5; i+=1) values[i] = Math.random () + 0.001;      int w = (width-40)/2;      int h = height-20;      bc1 = new BarChart (10, height-10, w, h, 5, values, colors);pc1 = new PieChart (width/2, height-10, w, h, 5, values, colors); }/** * invoke the chart paint methods * @param g - destination graphics object */public void paint (Graphic s g) {      bc1.paint (g);      pc1.paint (g);}/** * application entry point * create a window frame and add the applet inside * @param args[] - command-line arguments */public static void main (String args[]) {      Frame f = new Frame ("Charts");      ChartApp chart = new ChartApp ();            f.setSize (410, 230);      f.add ("Center", chart);      f.show ();      chart.init ();      chart.start ();}}
2. Create an HTML document that contains the applet. Create a new file called howto34.html that contains the following code:
<html><head><title>Charts</title></head><applet code="ChartApp.class" width=400 height=230></applet><hr size=4></html>
3. Compile and test the applet. Compile the source by using javac. Test the applet by using the Appletviewer; enter the following command:
APPLETVIEWER howto34.html
You can also run ChartApp.java as an application by typing
java ChartApp
When the applet is executed, a window with a bar chart and pie chart drawn inside it opens, as shown in Figure 3.6.

How It Works

The class Chart is the superclass for both bar and pie charts. Its constructorstores the array of values along with their corresponding colors. The values arenormalized such that the largest value is 1.0. This makes the code more efficientbecause the paint() method needs only scale the values to the specified width andheight. The total value is also computed, as it is needed for the pie chart.

The class BarChart extends class Chart so that it can inherit the variables andconstructor . The constructor for BarChart simply passes its arguments to the Chartconstructor by invoking its super() method. The paint() method is unique to eachtype of chart, so it must be defined in BarChart. BarChart.paint() scales the arrayof values to the specified height and draws the chart.

The class PieChart is similar. Its constructor also calls the Chart constructorby invoking super(). The paint() method draws the pie chart.

Comments

In addition to the filled shapes demonstrated, the AWT supports several otherssuch as arcs, 3D rectangles, and rounded rectangles.

3.5 How do I ... Draw text?


COMPLEXITY: INTERMEDIATE

Problem

In Chapter 2, I printed text to the screen with println(). This method will notwork to draw text in a graphics window. I would like to create a scrolling text marqueewith the capability of moving the text in various directions. How do I draw textin a graphics window?

Technique

The Graphics class contains the method drawString(). This method is used to drawtext in a graphics window. The drawString() method takes the string to be drawn andthe position of the starting point of the baseline of the string as arguments. Figure3.7 shows an example of the running applet.

FIGURE 3.7 Text may be scrolled in many directions.

Steps

1. Create the applet source file. Create a new file called ScrollApp.java and enter the following source code:
import java.applet.Applet;import java.awt.*;/** * a class that handles scrolling text */class Scroll {/* * x and y coordinates of starting point */int xstart, ystart;/* * width and height of bounding panel */int width, height;/* * text to be scrolled */String text; /* * x and y velocities, respectively */int deltaX, deltaY;/* * current x and y position of the text */int xpos, ypos;/* * the color of the text */Color color;/** * class constructor just saves arguments * @param x, y - starting coordinates * @param dx, dy - x and y velocities * @param w, h - width and height of bounding panel * @param t - the text string * @param c - color of the text */public Scroll (int x, int y, int dx, int dy, int w, int h, String t, Color c) {      xstart = x;      ystart = y;      width = w;      height = h;      text = t;      deltaX = dx;      deltaY = dy;      color = c;      xpos = xstart;      ypos = ystart;}/* * draw the text at the current position * advance the position and reinitialize outside bounding panel * @param g - destination graphics object */void paint (Graphics g) {      g.setColor (color);      g.drawString (text, xpos, ypos);      xpos += deltaX;      ypos += deltaY;      FontMetrics fm = g.getFontMetrics ();      int textw = fm.stringWidth (text);      int texth = fm.getHeight ();      if (deltaX < 0 && xpos < -textw) xpos = xstart;      if (deltaX > 0 && xpos > width) xpos = xstart;      if (deltaY < 0 && ypos < 0) ypos = ystart;      if (deltaY > 0 && ypos > height+texth) ypos = ystart;}}/** * the applet/application proper */public class ScrollApp extends Applet {/* * width and height of the bounding panel */int width, height;/* * instances of Scroll for demonstration */Scroll left, right, up, down, diag;/* * called when the applet is loaded * create new instances of Scrol l */      public void init () {      width = 410;      height = 230;      left = new Scroll (400, 50, -5, 0, width, height,            "Moving left", Color.red);      right = new Scroll (0, 150, 5, 0, width, height,            "Moving right", Color.green);      up = new Scroll (100, 200, 0, -5, width, height,            "Moving up", Color.blue);      down = new Scroll (200, 0, 0, 5, width, height,            "Moving down", Color.cyan);      diag = new Scroll (0, 0, 7, 3, width, height,            "Moving diagonally", Color.magenta); }/* * invoke the paint method of each scrolling text instance * force a repaint 50ms later */public void paint (Graphics g) {      left.paint (g);      right.paint (g);      up.paint (g);      down.paint (g);      diag.paint (g);      repaint (50);}/* * Application entry point * @param args - command-line arguments */public static void main (String args[]) {      Frame f = new Frame ("Scrolling text");      ScrollApp scrollApp = new ScrollApp ();            f.setSize (410, 230);      f.add ("Center", scrollApp);      f.show ();      scrollApp.init ();}}
2. Create an HTML document that contains the applet. Create a new file called howto35.html that contains the following code:
<html><head><title>Scrolling Text </title></head><applet code="ScrollApp.class" width=410 height=230></applet><hr size=4></html>
3. Compile and test the applet. Compile the source by using javac. Test the applet by using the Appletviewer; enter the following command:
AppletViewer howto35.html
You can also run ScrollApp as an application by typing
Java ScrollApp
When the applet is started, a window opens, with five text strings scrolling in different directions. There is one of each string scrolling left, right, up, down, and diagonally.

How It Works

The class Scroll maintains all the information necessary to draw scrolling text.xpos and ypos are the initial positions of the text. When the text scrolls completelyoff the screen, it is moved back to the initial position. deltaX and deltaY are thevelocities in the x and y directions. Positive and negative values are allowed, sothe text can scroll in any direction. width and height are the width and height ofthe bounding panel; these are used to determine whether the text has scrolled offthe panel that contains the applet. text is the text to be scrolled, and color isthe color of the text.

You draw the text in this example without specifying a font; therefore, the defaultfont is used. The discussion of using fonts in Java is included in How-To 3.6. Theclass FontMetrics is used to determine the width and height of the text. stringWidth()and getHeight() perform exactly these functions.

Table 3.4 lists the methods for filled shapes.

TABLE 3.4  FontMetrics Methods

METHOD DESCRIPTION
fill3DRect(int, int, int, int, boolean)
Paints a highlighted 3D rectangle using the current color.
fillArc(int, int, int, int, int, int)
Fills an arc using the current color.
fillPolygon(int[], int[], int)
Fills a polygon with the current color using an even-odd fill rule (otherwise known as an alternating rule).
fillRect(int, int, int, int)
Fills the specified rectangle with the current color.
fillOval(int,int,int,int)
Fills an oval bounded by the specified rectangle with the current color.
FillRoundRect(int,int,int,int,int,int)
Fills the specified rounded corner rectangle with the current color.
FontMetrics(Font)
Creates a new FontMetrics object with the specified font.
charWidth(int)
Returns the width of the specified character in this font.
charWidth(char)
Returns the width of the specified character in this font.
getAscent()
Gets the font ascent.
getDescent()
Gets the font descent.
getFont()
Gets the font.
getHeight()
Gets the total height of the font.
getMaxAdvance()
Gets the maximum advance width of any character in this font.
getMaxAscent()
Gets the maximum ascent of all characters in this font.
getMaxDescent()
Gets the maximum descent of all characters in this font. No character will descend further below the baseline than this distance.
getWidths()
Gets the widths of the first 256 characters in the font.
stringWidth(String)
Returns the width of the specified string in this font.
toString()
Returns the string repres entation of this FontMetric's values.


When this marquee is running, you may notice a considerable flickering of thetext. The flickering can be eliminated with the use of double buffering. This isdiscussed in Chapter 6, "User Interface."

Comments

The getAscent() method returns the font ascent, which is the distance from thebaseline to the top of the characters. The getDescent() method returns the distancefrom the baseline to the bottom of the characters. Figure 3.7 shows the appearanceof this applet.

3.6 How do I... Use fonts?


COMPLEXITY: INTERMEDIATE

Problem

Programs are more visually interesting when different fonts and text styles areused. I want to write a utility that prints text in all the fonts available in normal,bold, and italic styles. I know how to draw text, but I need to change the font andtext style. How do I find out what fonts and styles are available? How do I implementthese fonts and styles?

Technique

When text is drawn in a given graphics context, the current font, style, and sizeare used. To draw text with a different font, the current font must be changed byusing Graphics.setFont(). Graphics.setFont() takes a Font object as an argument.The style and size of the font are supplied as parameters to the Font constructor.

To determine which fonts are available, the method getFontList() is used. It returnsan array of strings that are the names of available fonts. To create a font, youinvoke the Font with the name, style, and size as arguments. Figure 3.8 shows theoutput of the code.

FIGURE 3.8 Several fonts and styles are displayed together on the screen.

Steps

1. Create the applet source file. Create a new file called Fonts.java and enter the following source:
import java.applet.Applet;import java.awt.*;/** * Class that determines which fonts are available */public class Fonts extends Applet {/* * Maximum number of fonts to display */final int MaxFonts = 10;/* * Width and height of bounding panel */int width, height;/* * Array of font names */String fontName[];/* * Array of fonts * Holds plain, italic, and bold for each font */Font theFonts[] = new Font[3 * MaxFonts];/* * The number of fonts found */int nfonts = 0;/* * Applet entry point */public void init () {    int i;    Dimension d = getSize ();    width = d.width;    height = d.height;        theFonts[0] = new Font ("Courier", Font.PLAIN, 12) ;        theFonts[1] = new Font ("System", Font.BOLD, 16);        theFonts[2] = new Font ("Helvetica", Font.BOLD, 18);     }/* * Draw the font names. * @param g - destination graphics object */public void paint (Graphics g) {    int i;        g.setFont (theFonts[0]);        g.drawString ("Courier", 10, 30);        g.setFont (theFonts[1]);        g.drawString ("System", 70, 70);        g.setFont (theFonts[2]);        g.drawString ("Helvetica", 150, 90);}/* * Application entry point * Creates a window frame and adds the applet inside * @param args[] - command-line arguments */public static void main (String args[]) {    Frame f = new Frame ("Fonts");    Fonts fonts = new Fonts ();    f.setSize (250, 200);    f.add ("Center", fonts);    f.show ();    fonts.init ();}}
2. Create an HTML document that contains the applet. Create a new file called howto36.html that contains the following code:
<html><head><title>Fonts</title></head><applet code="Fonts.class" width=250 height=200></applet><hr size=4></html>
3. Compile and test the applet. Compile the source by using javac or the makefile provided. Test the applet by using the Appletviewer; enter the following command:
APPLETVIEWER howto36.html
You can also run Fonts.java as an application by typing
java Fonts
When Fonts is executed, a window pops up, with the different font styles printed in plain, bold, and italic. Figure 3.8 shows an example of the running applet.

How It Works

The init() metho d sets the array of fonts. The paint() method then sets the currentfont and writes the name of that font in that font, for each of the three fonts.

An array is created that holds each of the fonts in plain, bold, and italic styles.You initialize the array by using the Font constructor with the font name, style,and size as arguments. A fixed size of 12 is used in this example. The font stylesare constants defined in class Font; they are summarized in Table 3.5. The styleconstants can be added to produce combined styles.

The method paint()goes through the array of fonts, sets the font using Graphics.setFont(),and draws the name of the font and the text bold and italic, usingthe appropriate styles.

TABLE 3.5  The Three Font Styles

CONSTANT DESCRIPTION
BOLD
The bold style constant
ITALIC
The italicized style constant
PLAIN
The plain style constant


Comments

Methods exist to obtain various properties of the font being used, such as width,height, and line spac ing. The methods are contained in the FontMetrics class. Figure3.8 shows the appearance of this applet.

3.7 How do I... Handle screen updates?


COMPLEXITY: ADVANCED

Problem

I want to create an applet that draws text that jumps around in different colorswithout erasing the previously drawn text. The previous examples show me how to domost of what I want, but they all erase the panel before drawing. I don't want todo that. I want to give the effect of the text growing on top of itself. How do Ihandle screen updates, or the lack thereof?

Technique

In all of the previous examples, the paint() method is used exclusively to dothe drawing. The paint() method is called from the update() method. The default update()method fills the panel with the background color and then calls paint(). The resultis that any previously drawn graphics and text are erased. To prevent previouslydrawn graphics and text from being erased, the default update() method must be overriddenand replaced with a method that does not erase the panel.

The rest of the applet uses many of the techniques described previously (see Figure3.9).

FIGURE 3.9 The update() method is overridden to produce a buildup effect.

Steps

1. Create the applet source file. Create a new file called CrazyText.java and enter the following source:
import java.applet.Applet;import java.awt.*;/* * application/applet class */public class CrazyText extends Applet {String text = "Java";  // string to be displayedint delta = 5;         // "craziness" factor: max pi xel offsetString fontName = "TimesRoman";int fontSize = 36;char chars[];          // individual chars in `text'int positions[];       // base horizontal position for each charFontMetrics fm;/* * called when the applet is loaded * creates a font and initializes positions of characters */public void init() {      int fontStyle = Font.BOLD + Font.ITALIC;      setFont(new Font(fontName, fontStyle, fontSize));      fm = getFontMetrics(getFont());      chars = new char[text.length()];      text.getChars(0, text.length(), chars, 0);      positions = new int[text.length()];      for (int i = 0; i < text.length(); i++) {            positions[i] = fm.charsWidth(chars, 0, i) + 20;      }}/* * draws the characters and forces a repaint 100ms later * @param g - destination graphics object */public void paint (Graphics g) {      int x, y;      g.setColor (new Color((float) Math.random(),                  (float) Math.random(),                  (float) Math.random()));      for (int i = 0; i < text.length(); i++) {            x = (int)(Math.random() * delta * 2) + positions[i];            y = (int)(Math.random() * delta * 2) + fm.getAscent() - 1;g.drawChars (chars, i, 1, x, y);       }      repaint (100);}/* * override default update() method to eliminate * erasing of the panel */   public void update (Graphics g) {      paint (g); }/* * application entry point * create a window frame and add the applet inside * @param args[] - command line arguments */public static void main (String args[]) {      Frame f = new Frame ("Crazy");      CrazyText crazy = new CrazyText ();            f.setSize (130, 80);      f.add ("Center", crazy);      f.show ();      crazy.init ();}}
2. Create an HTML document that contains the applet. Create a new file called howto37.html that contains the following code:
<html><head><title>Crazy Text</title></head><applet code="CrazyText" width=200 height=200></applet><hr size=2></html>
3. Compile and test the applet. Compile the source by using javac. Test the applet by using the Appletviewer; enter the following command:
Appletviewer howto37.html
When CrazyText is executed, a window pops up, with Java printed. As the applet is running, Java is repeatedly printed in different colors, and each character is moved slightly in a direction independent of the other characters. However, each time the characters are printed, the screen is not updated, and the previously printed characters are not erased. This produces an interesting effect, as shown in Figure 3.9.

How It Works

The method paint() sets the foreground color to a random value by using the Math.random()method. The characters are drawn, one at a time, with random variation in positionby using the Graphics.drawChars() method. Graphics.drawChars() is similar to Graphics.drawText(),but it takes an array of characters instead of a string as an argument.

Comments

It might occur to you that the code in the paint() method could be moved to theupdate() method, and the paint() method eliminated entirely. This, however, willnot work. When an applet or application is stated, the paint() method, not the update()method, is called. If no paint() method is provided, the default paint() method,which does n othing, is called. The calling of the update() method is platform dependentand therefore not reliable.

3.8 How do I... Print applet status messages?


COMPLEXITY: INTERMEDIATE

Problem

I liked the line-drawing applet that draws lines in shifting colors. What I wantto do is add the necessary code to print the values of the red, green, and blue componentsof the foreground color as they change. I don't want to put this in the panel wherethe lines are bouncing. Rather, I want to print the color values in the status barin the browser or in the Appletviewer. I know how to get the color component values,but how to I print applet status messages?

Technique

The status bar in the Appletviewer or browser can be accessed by the Applet.showStatus()method. This method takes as an argument a string that is to be printed in the statusbar. In this example, the string comprises hard-coded text concatenated with methodsthat return integer values. The current foreground red, green, and blue color componentscan be determined by calling the Graphics.getColor().getRed(),Graphics.getColor().getGreen(),and Graphics.getColor().getBlue() methods, respectively. See Figure 3.10.

FIGURE 3.10 The ShowStatus() method can provide text information to the user.

Steps

1. Create the applet source file. Create a new file called Status.java and enter the following source code:
import java.applet.Applet;import java.awt.*;/* * class to hold color values */class LineColors {/* * an array of colors proper */Color color[];/* * the constructor initial izes the color array by  * using an arbitrary algorithm */public LineColors () {        color = new Color[24];        int i, rgb;        rgb = 0xff;        for (i=0; i<24; i+=1) {                color[i] = new Color (rgb);                rgb <<= 1;                if ((rgb & 0x1000000) != 0) {                        rgb |= 1;                        rgb &= 0xffffff;                }        }}} // class LineColors/* * class to handle the drawing of one line segment */class Segment {/* * x1, y1 - x and y position of first endpoint * x2, y2 - x and y position of second endpoint */double x1, y1, x2, y2;/* * velocities of the endpoints, respectively */double dx1, dy1, dx2, dy2;/* * whichcolor - color index for this segment */int whichcolor; /* * width and height of bounding panel */int width, height;/* * instance of LineColors */LineColors LC;/* * class constructor * saves arguments and initializes position and velocities * to random values * @param w, h - width and height of bounding panel * @param c - starting color * @param lc - instance of LineColor */public Segment (int w, int h, int c, LineColors lc) {        whichcolor = c;        width = w;        height = h;         LC = lc;        x1 = (double) w * Math.random ();        y1 = (double) h * Math.random ();        x2 = (double) w * Math.random ();        y2 = (double) h * Math.random ();        dx1 = 5 - 10 * Math.random ();        dy1 = 5 - 10 * Math.random ();        dx2 = 5 - 10 * Math.random ();        dy2 = 5 - 10 * Math.random ();}/* * increments color index and calculates new endpoint positions */void compute () {        whichcolor += 1;        whichcolor %= 24;                x1 += dx1;        y1 += dy1;        x2 += dx2;      y2 += dy2;        if (x1 < 0 || x1 > width) dx1 = -dx1;        if (y1 < 0 || y1 > height) dy1 = -dy1;        if (x2 < 0 || x2 > width) dx2 = -dx2;        if (y2 < 0 || y2 > height) dy2 = -dy2; }/** * prints status message showing the different colors* @param g - destination graphics object */void paint (Graphics g) {        g.setColor (LC.color [whichcolor]);        g.drawLine ((int) x1, (int) y1, (int) x2, (int) y2);}} // class Segmentpublic class Status extends Applet {/* * width and height of bounding panel */int width, height;/* * The number of lines will be set to 1 because the color values * displayed will be valid for only one line */final int NLines = 1;/* * array of instances of Segment */Segment lines[] = new Segment[NLines];/* * instance of LineColor */LineColors LC = new LineColors ();/* * called when applet is loaded * save panel dimensions and create instance of Segment */public void init () {               width = 200;        height = 200;                 int i;        for (i=0; i<NLines; i+=1)                lines[i] = new Segment (width, height, (2*i) % 24, LC);}/** * draw the line and print status message * @param g - destination graphics object */public void paint (Graphics g) {        int i;         for (i=0; i<NLines; i+=1) {                lines[i].compute ();                lines[i].paint (g);        }        showStatus("red = "+g.getColor().getRed() + "  green = " +                g.getColor().getGreen() + "  blue = " +                g.getColor().getBlue());        repaint (50);}}
2. Create an HTML document named howto38.html that contains the following code:
<html><hea d><title>Crazy Text</title></head><applet code="Status" width=200 height=200></applet><hr size=2></html>
3. Compile and test the applet by using javac. Test the applet by using the Appletviewer; enter the following:
Appletviewer howto38.html
Status.java cannot be run as an application and does not support the printing of status messages.
When Status is executed, a window pops up, with a "flying line" bouncing around while changing colors. This is identical to the example in How-To 3.2, except that only one line is used. One line is used because the multiple lines all had different colors; the color status being printed can indicate only the color of one line. Figure 3.10 shows a snapshot of the running applet. This illustrates the power and usefulness of the showStatus() method.

How It Works

Most of the code in this example is identical to that of How-To 3.2. The differenceis the addition of calls to showStatus() in Status.paint(). ShowStatus() takes astring as an argument and is straightforward.

Read More Show Less

Customer Reviews

Be the first to write a review
( 0 )
Rating Distribution

5 Star

(0)

4 Star

(0)

3 Star

(0)

2 Star

(0)

1 Star

(0)

Your Rating:

Your Name: Create a Pen Name or

Barnes & Noble.com Review Rules

Our reader reviews allow you to share your comments on titles you liked, or didn't, with others. By submitting an online review, you are representing to Barnes & Noble.com that all information contained in your review is original and accurate in all respects, and that the submission of such content by you and the posting of such content by Barnes & Noble.com does not and will not violate the rights of any third party. Please follow the rules below to help ensure that your review can be posted.

Reviews by Our Customers Under the Age of 13

We highly value and respect everyone's opinion concerning the titles we offer. However, we cannot allow persons under the age of 13 to have accounts at BN.com or to post customer reviews. Please see our Terms of Use for more details.

What to exclude from your review:

Please do not write about reviews, commentary, or information posted on the product page. If you see any errors in the information on the product page, please send us an email.

Reviews should not contain any of the following:

  • - HTML tags, profanity, obscenities, vulgarities, or comments that defame anyone
  • - Time-sensitive information such as tour dates, signings, lectures, etc.
  • - Single-word reviews. Other people will read your review to discover why you liked or didn't like the title. Be descriptive.
  • - Comments focusing on the author or that may ruin the ending for others
  • - Phone numbers, addresses, URLs
  • - Pricing and availability information or alternative ordering information
  • - Advertisements or commercial solicitation

Reminder:

  • - By submitting a review, you grant to Barnes & Noble.com and its sublicensees the royalty-free, perpetual, irrevocable right and license to use the review in accordance with the Barnes & Noble.com Terms of Use.
  • - Barnes & Noble.com reserves the right not to post any review -- particularly those that do not follow the terms and conditions of these Rules. Barnes & Noble.com also reserves the right to remove any review at any time without notice.
  • - See Terms of Use for other conditions and disclaimers.
Search for Products You'd Like to Recommend

Recommend other products that relate to your review. Just search for them below and share!

Create a Pen Name

Your Pen Name is your unique identity on BN.com. It will appear on the reviews you write and other website activities. Your Pen Name cannot be edited, changed or deleted once submitted.

 
Your Pen Name can be any combination of alphanumeric characters (plus - and _), and must be at least two characters long.

Continue Anonymously

    If you find inappropriate content, please report it to Barnes & Noble
    Why is this product inappropriate?
    Comments (optional)