Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml

AspAutocadCDot netExcelFox proHtmlJava
LinuxMathcadPhotoshopPhpSqlVisual studioWindowsXml

Color, Font, Images, And Shapes

java



+ Font mai mare | - Font mai mic



Color, Font, Images, And Shapes

The Java API includes several classes designed to make Graphics rendering operations easier. Classes exist to represent colors, fonts, shapes, and images. Instances of these classes are passed, as parameters, to Graphics objects to facilitate rendering on a display surface.

Without these classes, specifying colors, fonts or simple shapes would require passing multiple parameters to Graphics methods; instead you can simply instantiate an instance of a particular graphical helper class and pass it to the Graphics object. For example, the Color class represents a color as three component color member variables: red, green and blue. Without this class, specifying a color to a Graphics object for rendering some geometric primitive, such as a line or oval, would require three parameters, one each for the red, green and blue color components.



The Graphics method for specifying the foreground color is Graphics.setColor(). The signature of setColor() is

public abstract class Graphics

Without the Color class, this single parameter would be replaced by three, making coding more complex:

public abstract class Graphics

In addition to encapsulating the data, the graphical helper classes also provide methods for common tasks associated with the data. For example, the Polygon class includes a getBoundingBox method which calculates the smallest rectangle that completely contains the polygon. As the project for this chapter, Doodle, demonstrates, Polygon.getBoundingBox comes in quite handy at times when you are working with Polygons. In addition, the implementations of common tasks in graphical helper class methods often cuts down on code size significantly.

The project for this chapter demonstrates use of the graphical helper classes by implementing a relatively simple Doodle application. In addition, the Doodle application demonstrates the use of peer-less Components, which I call "virtual Components," to manage overlapping rectangular areas of a window.

Colors

In Java, the default way to describe colors is by using the very common RGB color model. Color class instances assume colors will be presented that way. For those unfamiliar with this method of describing colors, here's a quick summary: Every color is described by a combination of red, green, and blue color components. Each component is given an absolute magnitude, from zero to some maximum. In Java, each color component is storable in an unsigned byte, and thus, is in the rangle 0-255. Each unique color is a unique point in the three-dimensional space illustrated in Figure 7-1. For example, absolute red is the point (255,0,0) in Java. The color white is represented as (255,255,255). And black is represented (0,0,0). (I was taught from a wee age that "black is not a color." If you, too, were subjected to this philosophy, you may have to realign a handful of synapses to deal with the fact that black is representable in the RGB color model, and so, is indeed a "color" for the purposes of this chapter.)


Figure 7-1  The RGB bounded color space

Java API's Color class has two ways of representing RGB color components to or from a Color object. Each of the three color components can be passed in a separate integer, as in the Color class constructor

public Color(int red, int green, int blue);

Alternatively, all three color components can be packed into a single integer. Since each color component may have only the values 0-255, each can be packed into a distinct byte of a four-byte integer. Packed RGB components are used in the Color methods, as shown here

public Color(int rgb); // Constructor taking packed RGB data
public int getRGB(); // Returns Color's packed components

When RGB color components are packed this way, the resultant integer is formulated like this: 0xFFrrggbb. That is, the top byte contains 0xFF. (Actually, it may contain any value. This value is ignored.) The next byte holds the red color component. The next holds green, and the bottom byte holds the blue color component. This listing shows how to build a packed integer of RGB color components from three distinct color component integer variables.

public int packComponents(int red, int green, int blue)

The Color class provides two RGB constructors, one of which is passed three distinct color component integer parameters for RGB values. The other RGB constructor takes a single packed integer of the color component data.

Color class instances also expose their RGB values through two types of methods. The getXXXmethods getRed, getGreen,and getBlue, each return a single integer indicating the Color's value for a single RGB color component. The getRGB method, as mentioned above, returns a packed integer holding all three color component values.

You may notice the similarities between the Color class packed component color format and the ColorModel packed RGBΑ format for representing colors in an Image. Although the formats are very similar, the chief difference is that the ColorModel has a fourth color component, "translucency" or "Α,", stored in the top byte of the packed integer. Java Color objects do not deal with translucency values, and thus ignore the values in the top byte of the packed RGB data

The HSB Color Model

Next to the RGB color model, the most commonly understood color model is the so-called HSB color model. The Color class provides some methods for automatically converting color component data between RGB and HSB color models. Figure 7-2 illustrates the HSB color space.


Figure 7-2  The HSB color space

HSB color model methods are provided in the Color class because some color based operations are better carried out using HSB data. For example, converting a Color to grayscale using HSB data involves only zeroing-out the S color component. This is a much harder operation in the RGB color model. On the other hand, it is generally much easier to recognize the RGB triplet (0,255,0) as the color green, as opposed to the HSB triplet (1,1,2π/3) which also represents green.

For readers unfamiliar with the HSB color model, here's a quick summary. The HSB color model breaks colors into three color components: "brightness," "saturation," and "hue." Brightness is easiest to understand as the grayscale value of a particular color. Saturation describes how bold the color is. Less saturated colors are more washed out. More saturated colors are more vibrant. Note that a color with 0 saturation is actually a grayscale color. Finally, hue indicates a point on the standard color wheel that is closest to a particular color.

Generally, HSB values are described on a scale of 0-1 for the brightness (B) and saturation (S) values. The hue is an angle around the central axis of the HSB color space (or around the standard color wheel, however you want to look at it). Hue values in Java are given in radians. All three values are passed as float valiables in the Color class.

The static Color class methods RGBtoHSB and HSBtoRGB provide a simple method for converting between the RGB and HSB color models. In addition, getHSBColor is a static method that will create a new Color object given the HSB color components. An HSB color model constructor is not provided by this class, probably to avoid coding confusion since it would be diffucult at first glance to tell whether a particular constructor call was invoking the RGB or HSB color model overloaded constructor version.

Using Colors

Color objects are generally used in AWT methods to refer to a Component object's foreground or background colors. Component.setForeground and setBackground each take a single Color object parameter. Similarly, Component.getForeground and getBackground return a Color object, representing the colors that the Component uses to draw in its update and paint methods.

To set the color a Graphics object uses when drawing to its display surface, use Graphics.setColor, passing it a Color object representing the color you want to use. The getColor method of the Graphics class returns the color it will use when drawing.

Note that several public, static Color object instances exist in the Color class. Each instance represents a common color, such as red, magenta, cyan, or white. These Color instances can be used as a shorthand instead of creating new Color objects to represent these common colors. The following listing shows how using these static instances can make coding a little bit easier: The class Palette presents a series of radio buttons. Each button uses a different background color. Such a panel is the basis for a decent "color chooser" toolbar for use in any application where the user chooses colors. Figure 7-3 shows an Applet that uses this Palette implementation.


Figure 7-3  The Palette panel allows users to select from one of the static Color members of the Color class

ublic class Palette extends Panel

Fonts: The Facts About Rendering Text

Font objects represent individual typefaces and styles used to render text on a drawing surface. Fonts are specified by a typeface name, and additional style and size indicators describe variations of the typeface. The Font class constructor is used to instantiate Font objects.

Font myFont = new Font("Helvetica", nStyleFlags, nPointSize);

The set of available typefaces is system-dependent. That is, font typefaces available on Windows 95 systems are not necessarily the same as those available on a Solaris or Macintosh. To get the list of available typeface names on any system, you must use the Toolkit's getFontList method. The getFontList method returns an array of String objects, each element of the array containing one typeface name available for AWT Graphics text rendering.

String[ ] astrFontList = Toolkit.getDefaultToolkit().getFontList();
for( int ii=0 ; ii<astrFontList.length ; ii++ )

The typeface can be modified by style attributes. There are three style attributes defined for all typefaces. The following Font class static members represent these style flags.

Typeface Style Flag

Description


Font.PLAIN

Unmodified typeface. The constant Font.PLAIN is defined as 0.

Font.ITALICS

Italicized version of the typeface.

Font.BOLD

Bold version of the typeface.


The Font's style is a bitwise ORing of these flags. Later versions of the Java API will, undoubtedly, include more Font style flags. For example, to create a Font object using both the bold and italics styles, you would use the Font constructor like this:

Font myFontObject = new Font("Helvetica", FGont.BOLD |
Font.ITALICS, nPointSize);

The size of a font is specified in "points", which is a typographic unit equal to (just about) 1/72 inch. This distance specifies the distance from the bottom of descending characters to the top of ascending characters of the typeface. Figure 7-4 illustrates the various metrics associated with a typeface, including the height, or point size, of the Font which is passed as the third parameter of the Font class constructor.


Figure 7-4  Typographical metrics that describe a font

Measuring a Font: The FontMetrics Class

The font metrics illustrated in Figure 7-4 are not directly available from a given Font object. Instead, you get a FontMetrics for a given Font object. The FontMetrics provides these metrics through its public class methods. The following lists the metrics of a Font available through the FontMetrics class, and the methods that provide access to those metrics.

Metric

Methods and Description of the Metric


Leading

The suggested distance between successive lines of rendered text. This is the distance between the bottom of the descending characters of the previous line and the top of the ascending characters of the next line. Another way to say this is that the distance between baselines of successive lines of text should be the Leading + Ascent + Descent. FontMetrics.getLeading() returns the Leading of the associated Font.

Ascent

The distance from the baseline to the top of asending chartacters. FontMetrics.getAscent() returns the Ascent of a given Font.

Descent

The distance from the baseline to the bottom of descending characters. FontMetrics.getDescent() returns the Descent of a given Font.

Height

The distance between baselines of successive lines of text, which is determined as Leading + Ascent + Descent. This is not the same thing as the font's typesize, which is simply Ascent + Descent, or the distance from the top of ascending characters to the bottom of descending characters. FontMetrics.getHeight() returns the Height of a given font.

Width

Fixed-width fonts have the same width for all characters. Variable-width fonts, such as the font used to display this sentence, have characters of different widths. The FontMetrics class includes methods to measure the width of a particular character, or of a string of characters. These methods are charWidth(), stringWidth(), charsWidths(), bytesWidth().


Why have a FontMetrics class at all? Why not have the Font object provide methods to access a font's metrics? The reason is, the same font may have different metrics when used to render text on different display surfaces. For example, a character of 10-point Helvetica font displayed on the screen may have a different actual size if displayed on a printer. If the printer must use an alternative font because it does not know the Helvetica typeface, then the sizes will most certainly be different. The FontMetrics class represents the metrics of a particular Font when used on a particular display surface.

The FontMetrics constructor accepts a Font object as its only parameter. The FontMetrics object which is created contains the metrics of the Font when used to render text on the default display surface (usually the screen), as shown here:

Font f = new Font("Helvetica", Font.ITALICS | Font.BOLD, 10);
FontMetrics fm = new FontMetrics(f);

// fm contains metrics of Font f when used to display text on
// the screen.

To get the metrics for text of a particular font when displayed on another display surface, you must use a Graphics object attached to that display surface. These are the steps:

1.  Get a Graphics object associated with the alternative display surface.

2.  Associate the Font you want to measure with the Graphics object using setFont.

3.  Get the FontMetrics for the Font when used to display text on the display surface using getFontMetrics. Here's how it looks:

Graphics g;

// Instantiate Graphics g by associating with display surface.

g.setFont(myFont);
FontMetrics fm = g.getFontMetrics();

The FontMetrics are very important for determining where to place text. The following listing is a method called getTextOrigin used to place text within a rectangle. That is, it accepts a String of text, a Graphics object which will be used to render the text, and a Rectangle to hold the text. The nFlags parameter is a bitwise ORing of the flags H_CENTER and V_CENTER. The method returns the x and y coordinates to use as the drawString method's x and y parameters to place the String within the Rectangle either horizontally or vertically centered (or both).

public static final int H_CENTER = 0x00000001;
public static final int V_CENTER = 0x00000002;

public static Point getTextOrigin(String text, Graphics g,
Rectangle r, int nFlags)

Figure 7-5 shows a simple Applet which demonstrates the use of getTextOrigin. In a two-by-two grid, the same text is displayed four times. The top left grid cell contains the text without any centering flags, so the text is left and top flushed. The bottom left cell uses only the H_CENTER flag, so the text is flush left but centered top-to-bottom. The text in the top right cell is flush with the top of the cell but centered left-to-right because only the V_CENTER flag is used. The bottom right cell uses both the H_CENTER and V_CENTER flags and the text is centered within the cell.


Figure 7-5  A getTextOrigin method to center rendered text within a rectangle horizonally or vertically

Geometric Helper Classes

A Rectangle is represented within the Java API by a size, measured in width and height, and a point of origin. The origin is usually the upper-left corner of the Rectangle, though if you allow for negative widths and heights the origin can be any one of the four corners. The Rectangle class internally stores four variables, which are exposed as public to make use of the Rectangle class easier: x, y, width and height. The x and y members describe the origin of the Rectangle, and the width and height parameters describe the size of the Rectangle. Positive widths extend to the right of the origin, and positive heights extend downwards from the origin.

The two accompanying classes to Rectangle are Point and Dimension. A Point is made up of an X and a Y distance, and represents a two-dimensional point (simple enough). A Dimension is a two-dimensional vector, and is represented by a width and a height public member variable.

Dimension objects are used almost exclusively by methods of the Component class to describe the size of a Component object on the screen. Component.size returns a Dimension indicating the width and height of the Component. You pass a Dimension object to a Component's resize method to change the width or height of the Component, as shown here:

// Make a Component large by 10 pixels in width and height
Dimension d = myComponent.size();
d.width += 10;
d.height += 10;
myComponent.resize(d);

An alternative, and easier, way to do the same thing is

Rectangle r = myComponent.bounds();
r.grow(10, 10);
myComponent.reshape(r.x, r.y, r.width, r.height);

The Rectangle class includes a rich set of methods to modify a Rectangle's point of origin, width, or height. The Rectangle class' move and translate methods modify a Rectangle by changing its point of origin without modifying its width or height. The move method simply changes the origin to the new x and y coordinates specified in its parameters. To move a Rectangle a relative distance from its current origin, use translate.The current origin of a Rectangle is always available by directly accessing its x and y public member variables, as follows:

// Move a Rectangle to the absolute point (10, 10)
Rectangle r = new Rectangle(initX, initY, initWidth, initHeight);
r.move(10, 10);

// Move a Rectangle 10 points to the right, and 10 points down
// from current position
Rectangle r = new Rectangle(initX, initY, initWidth, initHeight);
r.translate(10, 10);

The size of a rectangle is modified by Rectangle.resize() that changes the Rectangle's width and height to explicit new values. This is analogous to how Rectangle.move() changes the point of origin to an explicit new location.

Analogous to how translate changes the point of origin by a relative amount, grow makes the Rectangle wider and higher than its current size. The grow method is implemented to keep the Rectangle's center point exactly the same after the operation. The practical effect of growing a Rectangle by dX points in width and dY points in height is to move the origin dX points left and dY points up, and to add 2dX to the Rectangle's width and 2dY to the Rectangle's height. Note that positive dX and dY values passed to grow will actually shrink a Rectangle which has a negative width and height.

Rectangle.reshape takes both new coordinates for the Rectangle's origin, and new width and height values. That is, you can change any aspect of a Rectangle's placement or dimensions using reshape.

// Mirror the Rectangle about the x=y diagonal line
// by swapping x with y, and width with height
r.reshape(r.y, r.x, r.height, r.width);

The Rectangle class provides methods for performing two-dimensional unions and intersections of Rectangles. A union of Rectangles, performed by add, modifies the Rectangle object's origin and dimensions to encompass the smallest rectangular area that contains two different Rectangles. Actually, add does not perform a union in the strict mathematical sense. Figure 7-6 illustrates the difference between Java's add method and a mathematical union operation.


Figure 7-6  The operation performed by Rectangle.add compared to the result of a mathematical union

An add operation performed on two overlapping rectangles (A) produces a new rectangle (B) precisely sized to encompass both originals, while a mathematical union of the same two rectangles results in a new shape (C) that is not a rectangle at all. Similary, an add operation performed on two non-overlapping rectangles (D), produces another rectangle (E) just large enough to contain the first two, while a union of these rectangles is simply the two disjointed shapes taken together (F).

You can also add a Point to a Rectangle. This has the effect of modifying the Rectangle's origin and dimension to be the smallest rectangular area which encompasses both the origin Rectangle and the Point. Two different overloaded versions of add can be used to add a Point to a Rectangle: one takes a Point object as its only parameter, and the other takes the X and Y distances as two parameters.

The intersection operation, performed by intersection, modifies a Rectangle's origin and dimensions to encompass the rectangular area of overlap of two different Rectangles. Just as add does not perform a two-dimensional union in the strict sense, the Java intersection operation is not an intersection in the traditional mathematical sense. If there is no area of overlap between the two Rectangles, the resulting Rectangle values have an odd relationship to the original two Rectangles. The resulting rectangular area will have a negative width and height. The best way to describe its position is that it encompasses the area between the two non-overlapping rectangles.

Figure 7-7 shows the difference between Java's intersection operation and a mathematical intersection. For two overlapping Rectangles (A) there is no difference between the Rectangle resulting from Java's intersection operation (B) and the mathematical intersection (C). But for two non-overlapping Rectangles (D), Java's intersection operation results in a non-empty Rectangle (E), while a mathematical intersection would, of course, be the empty set (F).


Figure 7-7  The operation performed by Rectangle.intersection

It is also possible to intersect a Rectangle and a Point, although the process, shown in Figure 7-8, is a bit convoluted. To begin, you essentially negate the original Rectangle (A) by changing the sign of its width and height, and move its origin to the oppposite corner (B). This has the effect of maintaining the same rectangular area as the original Rectangle. Next, you use one of the overloaded versions of add to make a union of the Point with the modified Rectangle (C). Finally change the signs of the resulting rectangle's width and height and again move the origin to the opposite corner of the rectanglur area (D). Strange? No doubt. Here is an implementation of intersection(Point) as described in this paragraph.

public class RectangleEx extends Rectangle


Figure 7-8  Using the Java API to intersect a Rectangle and a Point

Graphical Object API Summaries

Table 7-1 lists the Java graphical object classes summarized in this section. Table 7-2 lists the methods for each of these classes, and a short description of each of them.

Table 7-1 The graphical helper classes


Class

Description


Color

Represents a color in the RGB color model. Methods are provided to easily translate colors between the RGB and HSB (brightness, saturation, hue) color model.

Font

Represents a font for rendering text on a display surface.

FontMetrics

Stores metrics, describing how a particular Font is rendered on a particular drawing surface. For example, the Font's ascending or descending distances from the baseline, or the width of characters rendered with that Font.

Image

An Image is generated from a graphical format file, or from data you provide through an ImageProducer. The Image class implements methods that allow you to draw on Images, just as you would any other display surface (with some restrictions). Informational methods are also provided to supply vital metrics about the image.

Point

Encapsulates a two-dimensional coordinate as an X and Y distance. Helper methods for changing the X and Y distances to either an absolute distance or a relative distance.

Rectangle

A Rectangle object describes a rectangle on the two-dimensional plane. A Rectangle is described by a point of origin, a width and a height. Several utility methods are provided with the Rectangle class implementation because the Component class-the basis for all Abstract Windows Toolkit (AWT) windowing classes-uses Rectangles quite a bit. There are several overloaded Rectangle constructors, as well as several methods for manipulating, comparing and combining rectangles via common geometric operations.

Polygon

A polygon is represented in Java by a Polygon class instance. A Polygon object stores an ordered set of vertices, describing a multipoint polygon in two dimensions. A couple of utility methods are provided with the Polygon class, although some methods you would expect to be included in the Java API were not. This chapter presents implementations for some of the missing functionality.



Table 7-2 Summary of the Color, Font, Images, and Shapes classes and methods


 

Class

Method

Description

 


 

Color

getRed, getGreen, getBlue

Gets the value of one of the principal color components.

getRGB

Gets the packed RGB representation of the color.

brighter

Gets a new Color object representing a color brighter than the original.

darker

Gets a new Color object representing a color darker than the original.

getColor

Creates a Color from a hexadecimal String representation of a packed RGB number.

getHSBColor

Creates a new Color object from HSB color component values.

RGBtoHSB

Converts a set of RGB color components to their equivalent HSB color components.

HSBtoRGB

Converts a set of HSB color components to their equivalent RGB color components.

 

Font

getFamily

Gets the text String describing the Font's font family.

getName

Gets the text String describing the Font's typeface.

getStyle

Returns a bitfield of flags indicating the additional typeface styles for the Font, such as bold or italics.

getSize

Gets the size of the Font, measured in points.

isPlain

Tells whether any typeface style flags are used by the Font.

isBold

Tells whether the Font is a boldface font.

isItalic

Tells whether the Font is an italics font.

getFont

Static method that creates a Font from just a typeface name.

 

FontMetrics

getFont

Gets the Font that this FontMetrics measures.

getLeading

Gets the suggested leading for the Font. The leading is the suggested spacing between successive lines of text, measured from the top of the tall characters which extend above the baseline (the "ascent") to the bottom of the characters which extend below the baseline (the "descent").

getAscent

Gets the height of characters above the baseline.

getDescent

Gets the distance below the baseline for characters which hang below the baseline, such as "p", "q", and "j".

getHeight

Gets the suggested distance between successive lines of text, measured baseline-to-baseline.

getMaxAscent

Gets the maximum extension of the tallest character above the baseline.

getMaxDescent

Gets the maximum descension of any character below the baseline.

charWidth

Gets the width in logical units (e.g., in pixels for most display surfaces) for a particular character.

stringWidth

Gets the width in logical units of a string of characters.

charsWidth

Gets the width in logical units of a set of characters presented as an array of chars.

bytesWidth

Gets the width in logical units of a set of characters presented as an array of bytes.

getWidths

Retrieves an array of widths for each character in the ASCII character set.

 

Image

getWidth

Gets the width in pixels of the Image.

getHeight

Gets the height in pixels of the Image.

getSource

Creates an ImageProducer which will deliver the pixel data and ColorModel of this Image to an ImageConsumer or ImageFilter.

getGraphics

Gets a Graphics object using this Image as its drawing surface. Only in-memory Images can successfully use this method.

getProperty

Each Image has an extensible set of properties telling particulars about the format, source, and filtering of the Image. Each property has a unique String name, and the property's value is returned as a human-readable String.

flush

Forces all pixel values for the Image to be forgotten. The next time Image pixel values are accessed, the Java system will reconstruct the Image from its source.

 

Point

move

Changes the X and/or Y position of the point.

translate

Moves the X and/or Y position of the point a specified distance along a particular axis.

 

Polygon

addPoint

Polygon instances are populated with vertices using this method. Note that once a vertex is added to a polygon it can not be removed without directly manipulating the xpoints and ypoints Polygon member arrays.

getBoundingBox

The smallest rectangle which can contain all the vertices of the Polygon is returned. Note that the Rectangle object returned is actually a member variable of the Polygon object. Direct manipulation of this Rectangle will corrupt it until a new vertex is added to the Polygon.

inside

Tells whether or not a point lies within the Polygon. Uses the even-odd insideness rule to calculate whether or not the point is within the polygon.

 

Rectangle

reshape

In a single method call, this method allows you to change the origin, width, and height of a Rectangle.

resize

Changes the width and height of the Rectangle without modifying the origin point.

move

Modifies the origin point without changing the width and height.

translate

Moves the origin point a specified distance in the X and Y directions without modifying the width nor height.

inside

Tests whether or not a point lies within the Rectangle.

intersects

Tests whether or not another Rectangle intersects this one.

intersection

Computes the rectangle which is an intersection of this one and another Rectangle object.

union

Computes the smallest Rectangle which contains both this Rectangle and another.

add

Adding a rectangle to another Rectangle is the same as a union. Adding a Point to the Rectangle computes the smallest rectangle which contains both this Rectangle and an external Point.

grow

Grows the Rectangle a specific distance in all four directions, such that the center point of the resultant rectangle is the same as the center point of the original.

isEmpty

Tests whether or not the Rectangle has a non-zero volume. That is, whether or not the width and height are both non-zero.

 

 

 

 

Color

Purpose

Represents a color as a red, green, and blue color component value.

Syntax

public class Color

Description

Color objects store the red, green, and blue color components for a single Color. The Graphics class uses Color objects to specify coloring of the foreground, background, and alternate-color (when the Graphics is in XOR mode). Figure 7-9 shows the class hierarchy of the Color class.


Figure 7-9  The class hierarchy of the Color class

PackageName

java.awt

Imports

java.io.*, java.lang.*

Constructors

public Color(int red, int green, int blue);
public Color(int rgb);
public Color(float flRed, float flGreen, float flBlue);
Specify the red, green, and blue color components separately as integers or as floats. Alternatively, specify the three color components in a packed int (0xFFrrggbb).

Example

Several public member variables of the Color class are static Color objects describing common colors. These members are used as a "shorthand" for specifying common Colors. For example, the two following lines of code are equivalent ways to change a Graphics object's foreground color to yellow.

Graphics g;

g.setColor(new Color(255, 255, 0)); // create new Color object.
g.setColor( Color.yellow ); // refer to static yellow Color.

The following table lists the 13 static Colors and their RGB values, expressed in hexadecimal values.

Color

RGB values


white

r: 0xFF; g: 0xFF; b: 0xFF

lightGray

r: 0xC0; g: 0xC0; b:0xC0

gray

r: 0x80; g:0x80; b: 0x80

darkGray

r: 0x40; g: 0x40; b: 0x40

black

r: 0x00; g: 0x00; b: 0x00

red

r: 0xFF; g: 0x00; b: 0x00

pink

r: 0xFF; g: 0xAF; b: 0xAF

orange

r: 0xFF; g: 0xC8; b: 0xC8

yellow

r: 0xFF; g: 0xFF; b: 0x00

green

r: 0x00; g: 0xFF; b: 0x00

magenta

r: 0xFF; g: 0x00; b: 0xFF

cyan

r: 0x00; g: 0xFF; b: 0xFF

blue

r: 0x00; g: 0x00; b: 0xFF


getRed

ClassName

Color

Purpose

Gets the value of the red color component of this Color.

Syntax

public int getRed();

Parameters

None.

Imports

None.

Description

Retrieves the value of the red color component of the Color object. This is the value originally passed as the red color component to the Color class contructor.

Returns

The value of the red color component in the range 0-255 is returned.

See Also

The getGreen, getBlue, and getRGB methods of the Color class

Example

This code sample creates a new Color object that is 75 percent as bright as the original. Each of the red, green, and blue color components are scaled by the value 0.75 (float) and converted to a float value 0-1, which is used by the normalized magnitude version of the Color constructor to create a new, dimmer Color object.

Color colorOriginal;

// colorOriginal is initialized to some color.

Color colorDimmer = new Color(
((float)colorOriginal.getRed() * 0.75) / 255,
((float)colorOriginal.getGreen() * 0.75) / 255,
((float)colorOriginal.getBlue() * 0.75) / 255);

getGreen

ClassName

Color

Purpose

Gets the value of the green color component of the Color.

Syntax

public int getGreen();

Parameters

None.

Imports

None.

Description

Retrieves the value of the green color component of the Color object. This is the value originally passed as the green color component to the Color class constructor.

Returns

The value of the green color component in the range 0-255 is returned.

See Also

The getRed, getBlue, and getRGB methods of the Color class

Example

See the code sample for getRed, which also demonstrates use of getGreen and getBlue.

getBlue

ClassName

Color

Purpose

Gets the value of the blue color component of the Color.

Syntax

public int getBlue();

Parameters

None.

Imports

None.

Description

Retrieves the value of the blue color component of the Color object. This is the value originally passed as the blue color component to the Color class constructor.

Returns

The value of the blue color component in the range 0-255 is returned.

See Also

The getRed, getGreen, and getRGB methods of the Color class

Example

See the sample for getRed, which also demonstrates use of getBlue and getGreen.

getRGB

ClassName

Color

Purpose

Gets a packed integer which contains the values of the red, green, and blue color component for this Color.

Syntax

public int getRGB();

Parameters

None.

Imports

None.

Description

Retrieves a 32-bit integer of packed bitfields describing the values of the red, green and blue color components of the Color object.

Returns

A 32-bit integer of packed bitfields describing the red, green, and blue color components is returned. The bitfields are described by this hexadecimal mask: 0x00rrggbb. That is, the red component mask is 0x00FF0000, the green mask is 0x0000FF00, and the blue mask is 0x000000FF.

Example

This method creates a new Color object from an original object, where the output Color is the same as the original Color with the red and blue color components switched. It would probably be even easier to implement this method using getRed and getBlue, but this code sample is sufficient for demonstrating the getRGB method.

public Color switchRAndG(Color colorIn)

brighter

ClassName

Color

Purpose

Creates a new Color object representing a color which is a brighter version of this Color.

Syntax

public Color brighter();

Parameters

None.

Imports

None.

Description

Creates a new Color object which is roughly one-and-a-half times as bright as this Color object. Within the Java API, this method is used to highlight beveled edges, such as the edge around a 3D rectangle.

Returns

A new Color object representing a color roughly one-and-a-half times as bright as this Color object. That is, each color component of this Color is multiplied by about 1.5 and used to create a new color object. Of course, the maximum of any color component in the new Color object is 255.

Example

The method demonstrated here uses arc segments to create a shaded oval on a Graphics object's drawing surface. The shaded oval is drawn with a beveled edge to look "raised" or "lowered" on the drawing surface, similar to draw3DRect. Brighter and darker are used to create colors, implying shaded versions of the Graphics object's foreground color. The draw3DOval method uses the nThickness parameter to indicate the thickness of the 3D oval's border.

public draw3dOval(Graphics g, Rectangle rectOval,
boolean fRasied, int nThickness)

darker

ClassName

Color

Purpose

Creates a new Color object representing a color which is a darker version of this Color.

Syntax

public Color darker();

Parameters

None.

Imports

None.

Description

Creates a new Color object which is roughly 70 percent as bright as this Color object. Within the Java API, this method is used to highlight beveled edges, such as the edge around a 3D rectangle.

Returns

A new Color object representing a color roughly 70 percent as bright as this Color object. That is, each color component of this Color is multiplied by about 0.7 and used to create a new color object.

Example

See the code sample for brighter.

getColor

ClassName

Color

Purpose

Creates a Color from a String representation of packed RGB information.

Syntax

public static Color getColor(String nm);
public static Color getColor(String nm, Color v);
public static Color getColor(String nm, int rgb);

Parameters

String nm

The text value of this String is the decimal or hexadecimal value of a 32-bit integer. This integer has 3 packed 8-bit bitfields representing each of the red, green, and blue color components. The bitfield format is 0x00rrggbb. For example, "00FFFFFF" represents the color white.

Color v

The default color to return if the nm parameter is incorrectly formatted. That is, if the nm parameter does not contain a valid number.

int rgb

An integer of 3 packed 8-bit bitfields representing the color components of the default Color to return if the nm parameter is incorrectly formatted. That is, if the nm parameter does not contain a valid number.

Imports

None.

Description

Allows you to create a Color object from a text String. The String is a text version of a 32-bit packed RGB value. Overloaded versions exist so you can specify an alternative color if the text String is ill-formated.

Returns

A new Color object representing the color components specified by the nm String parameter. If the first overloaded version of this method is used, and the nm parameter is incorrectly formatted, then null will be returned.

Example

The main method of this object prompts the user for a packed RGB integer value for a new Color object. The getColor method is used to build the Color object, and Color.toString is used to display what Color was actually created. "Null" will be displayed if the input text from the user does not represent a valid packed RGB value. Either decimal or hexadecimal notation may be used.

import java.awt.Color;

public class TestColorProgram
}

getHSBColor

ClassName

Color

Purpose

Creates a new Color object from HSB color components.

Syntax

public static Color getHSBColor(float h, float s, float b)

Parameters

float h

HSB hue color component for the new Color to create. This is measured in radians.

float s

0-1 value of the HSB saturation color component for the new Color to create.

float b

0-1 value of the HSB brightness color component for the new Color to create.

Imports

None.

Description

Creates a new Color object from HSB color components. "HSB" is a theoretical color model in which colors are measured by Hues, Saturation and Brightness. (Please refer to a textbook on color theory for a complete discussion of the HSB color model.) Instead of referring to colors in terms of their red, green, and blue color components, as most the other Color class methods do, this method uses hue, saturation, and brightness color components.

Returns

A new Color instance is returned, which represents a color with the specified hue, saturation, and brightness color components.

Example

This example takes an input Color object and uses it to create a new Color object with a change in the Hue color component of the HSB representation of the Color. Hue is an angle, measured in radians. This method flips the hue color component by π radians (180). Since hue is measured as an angle, the simplest method to invert the angle by π radians is to invert its sign.

public Color InvertHue(Color c)

RGBtoHSB

ClassName

Color

Purpose

Converts a set of RGB color components to their HSB equivalents.

Syntax

public static float[ ] RGBtoHSB(int r, int g, int b, float[ ] hsbvals);

Parameters

int r

The red color component of the color to convert to the HSB color model. Must be between 0-255.

int g

The green color component of the color to convert to the HSB color model. Must be between 0-255.

int b

The blue color component of the color to convert to the HSB color model. Must be between 0-255.

flaot[ ] hsbvals

An array of at least three elements. The return values of the conversion are returned in this array. If hsbvals is null, then an array of three float values is allocated on behalf of the calling code by Color.RGBtoHSB(). Note that there is no error checking by RGBtoHSB() to ensure the array is at least three elements long. An ArrayIndexOutOfBounds exception will be thrown if this array is not at least three elements long.

Imports

None.

Description

Converts a set of RGB color components to their equivalent HSB color components. Use this method to convert a color between the RGB and HSB color representation schemes.

Returns

The same value passed in the hsbvals parameter is returned. If null is passed for hsbvals, then the return value is a reference to an array allocated by this method on behalf of the calling code.

See Also

The HSBtoRGB method of the Color class

Example

See the example for the getHSBColor method.

HSBtoRGB

ClassName

Color

Purpose

Converts a set of HSB color components to their RGB equivalents.

Syntax

public static int HSBtoRGB(float hue, float saturation, float brightness);

Parameters

float hue

The hue color component of the color to be converted, measured in radians.

float saturation

The saturation color component of the color to be converted. This value is in the range 0-1.

float brightness

The brightness color component of the color to be converted. This value is in the range 0-1.

Description

Converts a set of HSB color components to their equivalent packed 32-bit integer of RGB color component values. Use this method to convert between the HSB and RGB color representation schemes.

Returns

A 32-bit integer of packed RGB color components. The red, green, and blue color components describe the same color as the input hue, saturation, and brightness parameters.

See Also

The RGBtoHSB method of the Color class

Example

See the example for the getHSBColor method.

Font

Purpose

Represents a Font with which to render text on display surfaces.

Syntax

public class Font

Description

Instances of the Font class describe a typesetting font for displaying text on a display surface. Fonts are described by a name, size and style. A Font on a particular display surface is measured by a FontMetrics, which tells the size of characters when they are displayed on that display surface.

Different Fonts are available for use on different desktops. The AWT Toolkit object provides the names of available Fonts through Toolkit.getFont.
Figure 7-10 shows the class hierarchy of the Font class.


Figure 7-10  The class hierarchy of the Font class

Package

java.awt

Imports

None.

Constructors

public Font(String name, int style, int size);
Specify a font typeface name, style flags ORed together bitwise, and the size of the font in points. The Toolkit class method getFont enumerates all the valid font typeface names.

Parameters

The Font class includes several static constants for specifying font styles. Generally, these style flags are ORed together bitwise to specify a series of style indicators for a Font. The following table lists those style constants.

Constant

Description


PLAIN

The absence of other style indicators.

BOLD

The boldface style indicator.

ITALICS

The italics style indicator.


Example

This example demonstrates how to create Fonts in Java.

public void SampleFonts(Graphics g)

getFamily

ClassName

Font

Purpose

Gets the name of the font family that this Font's typeface belongs to.

Syntax

public String getFamily();

Parameters

None.

Imports

None.

Description

Returns a String value of the Font's font family. If the font family name is not available, then the Font's typeface name is returned. The font family is stored as a System property under the key "awt.font.<typeface-name>". If this System property is not available, then the Font's typeface name is returned instead.

Returns

A String filled with the name of the font family this Font belongs to.

Example

This example method prints all available information about a particular Font object, using the various public methods of the Font class.

public void print(String s)

public void printFontInfo(Font f) else
// Print style flags as demonstrated by the getStyle
// method.
print([using getStyle:]");
if(0 != (f.getStyle() & Font.PLAIN))
print("tPLAIN");
} else

getName

ClassName

Font

Purpose

Gets the name of the Font's typeface.

Syntax

public String getName();

Parameters

None.

Imports

None.

Description

Returns the typeface name for the Font. This String should indicate the same value passed to the Font constructor, or to getFont, whichever was used to create the Font object.

Returns

The typeface name of the Font is returned in a String object.

See Also

The getFont method of the Font class.

Example

See the example for the getFamily method of the Font class.

getStyle

ClassName

Font

Purpose

Gets the style flags for the Font.

Syntax

public int getStyle();

Parameters

None.

Imports

None.

Description

Gets an integer which describes the style indicators used to create the Font. One or more of the static Font class constants PLAIN, BOLD, or ITALICS will be combined to describe the style of the Font.

Returns

The style flags for the Font are ORed together to create the return value for this method. This should be the same value passed to the Font constructor.

Example

See the example for the getFamily method of the Font class.

getSize

ClassName

Font

Description

Return the size of the Font, measured in points.

Syntax

public int getSize();

Parameters

None.

Imports

None.

Description

The size is the combination of the typeface's ascension above the baseline plus its descension below the baseline. The return value is the same as the size parameter passed to the Font constructor.

Returns

The point size of the Font, measured in "points." A point is a typesetter's unit equal to 1/72 inch.

Example

See the example for the getFamily method of the Font class.

isPlain

ClassName

Font

Purpose

Tells whether the Font's style is plain or not.

Syntax

public boolean isPlain();

Parameters

None.

Imports

None.

Description

Indicates whether the Font's style is devoid of any special flags, such as BOLD or ITALICS.

Returns

True is returned if all style flags for the Font are cleared.

See Also

The isBold and isItalics methods of the Font class

Example

See the example for the getFamily method of the Font class.

isBold

ClassName

Font

Purpose

Tells whether the Font is boldface.

Syntax

public boolean isBold();

Parameters

None.

Imports

None.

Description

Tells whether or not the BOLD style flag for the Font is set.

Returns

Returns true if the Font.BOLD style flags is set for the Font.

See Also

The isPlain and isItalics methods of the Font class

Example

See the example for the getFamily method of the Font class.

isItalic

Class

Font

Purpose

Tells whether the Font is italicized.

Syntax

public boolean isItalic();

Parameters

None.

Imports

None.

Description

Tells whether or not the ITALICs style flag for the Font is set.

Returns

Returns true if the Font.ITALICs style flag is set for the Font.

See Also

The isPlain and isBold methods of the Font class

Example

See the example for the getFamily method of the Font class.

getFont

ClassName

Font

Purpose

Creates a new Font given just a typeface name.

Syntax

public static Font getFont(String nm);
public static Font getFont(String nm, Font font);

Parameters

String nm

The name of the typeface to use for the Font. Only valid typeface names are acceptable. A list of valid typeface names for the local system can be accessed through Toolkit.getFontList() which returns an array of typeface names stored in Strings.

Font font

Default Font object to return if the typeface name passed in the nm parameter is not a valid typeface name.

Description

This static method creates a new Font object given just a typeface name. In addition to the typeface name, you can add style attributes to the Font by prepending style prefixes to the typeface name in the nm parameter.

Returns

A new Font object which uses the typeface indicated by the nm parameter is returned. Null will be returned by the first overloaded version of this method if the nm parameter does not indicate a valid typeface name.

Example

This example program asks the user for the name of a typeface to display. Once provided, a Font of that typeface is created using getFont and is used to display a sample string in a Label centered in a floating Frame.

import java.awt.*;

public class GetFontTest

_label.setFont(f);
_frame.repaint();

System.out.print( strPrompt );
strInput = System.in.readln();
}
}

FontMetrics

Purpose

Encapsulates vital metrics of a Font as it is rendered on a specific display surface.

Syntax

public abstract class FontMetrics

Description

A Font object alone does not contain enough information to compute the size of characters when they are displayed using that Font. To understand why this information may not be available, remember that Font objects only store the Font's point size. But "point size" does not directly translate into a logical display size before the Font is actually associated with a particular display surface. For example, imagine trying to use a 30-point Courier Font to display text on a dot matrix printer. The printer probably can only display text using a single text size. In this case, it doesn't matter whether your Font is 30 points or 3 points in size, both will produce visible text of exactly the same size.
Once a particular Font is associated with a display surface (that is, a Graphics object which controls the display surface), then the logical size of the Font's characters on that display surface can be calculated. The FontMetrics class represents the actual size of displayed text on a particular display surface using a particular Font. The various methods of this class automatically compute the width and height of one or more displayed characters for that display surface and Font.
To create a FontMetrics object, you associate the Font you want to use with the Graphics object associated with the desired display surface. For example, to calculate the width of the string "Measure Me!" as it is displayed on a Canvas using a particular Font, you would use code similar to this

public class MyCanvas extends Canvas

public void paint(Graphics g)

Java was originally designed to be a Unicode language. "Unicode," for those unfamiliar with the term, is a 16-bit character set designed to encode all the character sets of all languages in the world. The 8-bit ASCII character set is actually a subset of the Unicode set. That is, all ASCII codes translate directly to Unicode value by zero-padding the ASCII value with another byte containing 0.

Unfortunately, the Java 1.0 API does not include Unicode support beyond the normal ASCII character set. All FontMetrics methods which refer to character values will only accept ASCII code values. In fact, most FontMetrics methods assume the 8-bit ASCII character set only is being used. In later versions of Java, this API will have to be changed to accommodate the full Unicode character set.
Figure 7-11 shows the class hierarchy for the FontMetrics class.


Figure 7-11  The class hierarchy for the FontMetrics class

Package

awt.java

Imports

None.

Constructors

public FontMetrics(Font font);
This constructor creates a FontMetrics measuring the Font font on the default display device (the desktop). The Graphics method getFontMetrics can be used to get a FontMetrics for the display surface associated with a particular Graphics object.

Parameters

None.

Example

See the above example, which demonstrates creation and use of a FontMetrics object, to measure the size of a String as it is rendered on the desktop.

getFont

ClassName

FontMetrics

Purpose

Gets the Font this FontMetrics was created to measure.

Syntax

public Font getFont();

Parameters

None.

Imports

None.

Description

Retrieves the Font object associated with this FontMetrics object. This will be the same Font passed to the FontMetrics constructor, or the same Font selected into the Graphics object which created this FontMetrics through Graphics.getFontMetrics.

Returns

The Font object associated with this FontMetrics is returned.

Example

This example method ensures that the Graphics object it is passed has a bold font as its current font.

public void selectBoldFont(Graphics g)

getLeading

ClassName

FontMetrics

Purpose

Gets the leading distance between successive lines of rendered text.

Syntax

public int getLeading();

Parameters

None.

Imports

None.

Description

Returns the internal leading distance between successive lines of text for the associated Font, as rendered on the associated display surface. The "internal leading" distance is the suggested distance from the bottom of characters descending below the text baseline to the top of characters ascending above the baseline of the subsequent line of text.

Returns

The internal leading value for the associated Font rendered on the associated display surface is returned. The internal leading is measured in logical units of the display surface (e.g., in pixels for the on-screen desktop).

Example

This example uses the internal leading value as an inset distance to leave around a String of text rendered on a display surface.

public class MyStringDisplayComponent extends Canvas
public Dimension preferredSize()
public void paint(Graphics g)

getAscent

ClassName

FontMetrics

Purpose

Gets the ascending distance of tall characters.

Syntax

public int getAscent();

Parameters

None.

Description

Retrieves the ascent of tall characters above the baseline. The getMaxAscent() method returns the ascent of the highest character, while this method returns the ascent of the majority of tall characters (such as "t", "h" or "k").

Returns

Returns the ascent of the Font as rendered on the associated display surface. The ascent is measured in logical units of the display surface (e.g., for the desktop, the return value would be in pixels).

Example

See the example for the getLeading method.

getDescent

ClassName

FontMetrics

Purpose

Gets the descending distance of characters that hang below the baseline.

Syntax

public int getDescent();

Parameters

None.

Imports

None.

Description

Retrieves the descent of characters that hang below the baseline. The getMaxDescent() method returns the descent of the character that hangs lowest below the baseline for this Font, while this method returns the descent of the majority of characters which hang below the baseline (such as "q", "j" or "g").

Returns

Returns the descent of the Font as rendered on the associated display surface. The descent is measured in logical units of the display surface (e.g., for the desktop the return value would be in pixels).

Example

See the example for the getLeading method.

getHeight

ClassName

FontMetrics

Purpose

Gets the total height of a single line of rendered text.

Syntax

public int getHeight();

Parameters

None.

Imports

None.

Description

Retrieves the total height of a line of text drawn using the associated Font on the associated display surface. This value is the sum of the ascent, the descent, and the internal leading. The height of a line is a convenient measure of the distance bewteen baselines of successive lines of text.

Returns

The total height of a line of text rendered on the associated display surface using the associated Font. This height is measured in logical units of the display surface (e.g., for the desktop the return value would be in pixels.

Example

The paint method of this example Component paints two lines of text on the passed Graphics, using the height as a recommended distance between baselines.

String _str1;
String _str2;

// _str1 and _str2 must be initialized somewhere before
// paint() is called.

public void paint(Graphics g)

getMaxAscent

ClassName

FontMetrics

Purpose

Gets the maximum ascent above the baseline of any chartacter in the character set.

Syntax

public int getMaxAscent();

Parameters

None.

Imports

None.

Description

This method retrieves the maximum ascent above the baseline of any character in the character set, rendered on the associated display surface using the associated Font. The getAscent method retrieves the ascent of the majority of "tall" characters such as "t", "h" and "k".

Returns

The maximum ascent of all characters and the character set if rendered on the associated display surface using the associated Font. The maximum ascent is measured in logical units of the display surface (e.g., pixels for the on-screen desktop).

See Also

The getMaxDescent method of the FontMetrics class

Example

This example method calculates the maximum height of a Font, based on the Font's maximum ascent and maximum descent. (The normal getHeight method of the Font class calculates the Font's height based on the average ascent and descent of the Font.)

public int getMaxHeight(Font f)

getMaxDescent

ClassName

FontMetrics

Purpose

Get the maximum descent below the baseline of any character in the character set.

Syntax

public int getMaxDescent(); public int getMaxDecent();

Parameters

None.

Imports

None.

Description

This method retrieves the maximum descent below the baseline of any character in the character set, rendered on the associated display surface using the associated Font. The getDescent() method retrieves the descent of the majority of characters such as "q", "j", and "g". Note that another version of this same method exists which is misspelled. The misspelled version maintains backwards compatibility with alpha and beta versions of the Java API, which were developed before spellcheckers.

Returns

The maximum descent of all characters and the character set if rendered on the assoicated display surface using the associated Font. The maximum descent is measured in logical units of the display surface (e.g., pixels for the on-screen desktop).

See Also

The getMaxAscent method of the FontMetrics class.

Example

See the example for the getMaxAscent method of the FontMetrics class.

charWidth

ClassName

FontMetrics

Purpose

Gets the width of a specific character.

Syntax

public int charWidth(char ch); public int charWidth(int ch);

Parameters

char ch

Char storing the ASCII code of the character to measure. By design, Java is a Unicode language which uses 16-bit Unicode character values. Currently, however, only the 8-bit ASCII code values are recognized by Java.

int ch

32-bit integer storing the ASCII code of the character to measure. When later versions of Java gain fuller Unicode capabilities, the overloaded version of this method, which takes an integer parameter, will have to be used to process 16-bit Unicode values. You can use the overloaded version of this method with ASCII code values, zero-padded in the top three bytes of this integer parameter.

Imports

None.

Description

Retrieves the width of a single character rendered in the associated Font on the associated display surface.

Returns

The width (in logical untis of the associated display surface) of a single character.

Example

This example creates an Image object precisely the same size as the character which is also painted on the Image surface.

public Image getCharImage(char ch)

stringWidth

ClassName

FontMetrics

Purpose

Calculates the width of a String of text.

Syntax

public int stringWidth(String str);

Parameters

String str

The String of text to measure.

Imports

None.

Description

Calculates the width of the String of text rendered on the associated display surface using the associated Font.

Returns

The total width of the String of text is returned. The return value is in logical units of the associated display surface (e.g., for the desktop, the return value is in pixels).

Example

A useful method is getMeasuredSubstring(), listed below. This method breaks the input String at the last whitespace chartacter which can fit within a particular width on the default display surface. This is useful for finding the correct place to break a string when word-wrapping text yourself (instead of depending on a TextArea to do it).

public int getMeasuredSubstring(String str, Font font, int width)
return strRet;

charsWidth

ClassName

FontMetrics

Purpose

Calculates the width of a set of characters stored in an array of characters.

Syntax

public int charsWidth(char[ ] data, int off, int len);

Parameters

char[ ] data

Array of characters to measure. Each element holds an 8-bit ASCII character value.

int off

Zero-based index of the first character to measure in the data array.

int len

Count of characters to measure in the data array.

Imports

None.

Description

Calculates the width of characters in a char array on the associated display surface using the associated Font object to render the characters. You specify the offset into the array and the number of characters to measure. Use 0 for the offset and data.length for the len to measure the entire array of characters.
Note that if the data array passed into this method is not at least (off+len) elements in length, then this method will throw an ArrayIndexOutOfRange exception.

Returns

The sum of the widths of the off through (off+len-1) characters in the data array. Character measurements are in logical units of the associated display surface (e.g., in pixels for the on-screen desktop).

Example

This method is very similar to the stringWidth method. See the example for stringWidth.

bytesWidth

ClassName

FontMetrics

Purpose

Calculates the width of a set of characters stored in an array of bytes.

Syntax

public int bytesWidth(byte[ ] data, int off, int len);

Parameters

byte[ ] data

Array of characters to measure. Each element holds an 8-bit ASCII character value.

int off

Zero-based index of the first character to measure in the data array.

int len

Count of characters to measure in the data array.

Imports

None.

Description

Calculates the width of all the characters in a byte array on the associated display surface, using the associated Font object to render the characters. Since characters are stored in bytes, which are always eight bits wide, only ASCII characters can be measured using this method, even in future version of Java.
Note that if the data array passed into this method is not at least (off+len) elements in length, then this method will throw an ArrayIndexOutOfRange exception.

Returns

The sum of the widths of the off through (off+len-1) characters in the data array. Character measurements are in logical units of the associated display surface (e.g., in pixels for the on-screen desktop).

Example

This method is very similar to the stringWidth method. See the example for the stringWidth method.

getWidths

ClassName

FontMetrics

Purpose

Gets the widths of all characters in the ASCII character set.

Syntax

public int[ ] getWidths();

Parameters

None.

Imports

None.

Description

Gets an array of the widths of each character in the ASCII character set, as rendered with the associated Font on the associated display surface.

Returns

A 256 element array of integer values, each element containing the width of the corresponding character in the ASCII character set. The width of each character is measured in logical units of the display surface. Note that only the width of the ASCII characters is returned. Even though Java is designed to be a Unicode language, only the ASCII character set is supported by the Java 1.0 API.

Example

This is an example implementation of the FontMetrics.charsWidth method which utilizes getWidths.

public class MyFontMetrics extends FontMetrics

Image

Purpose

Represents an image which can be rendered on a Graphics object's display surface.

Syntax

public abstract class Image

Description

Lots of functionality in the Java API is centered around creating, manipulating, and displaying images. Images are represented in Java as Image class instances. Image objects can represent either a single static picture, or a series of animation frames. The Graphics.drawImage method is built to display both types of Images on a display surface. A couple of chapters in this book deal with other Java classes that handle Image objects. Chapter 1 explains in detail the Graphics class, and touches on the ImageObserver interface which is required to render an Image on a display surface. Figure 7-12 shows the Image class hierarchy.


Figure 7-12  The class hierarchy of the Image class

Package

java.awt

Imports

java.awt.image.ImageProducer, java.awt.image.ImageObserver

Constructors

None.
No constructor is defined for the Image class, so you cannot create Image objects directly using the new operator. Instead, four techniques for creating Image objects indirectly are provided by the AWT API.
First, Image objects can be created by the AWT Toolkit from graphical format files. Image data is generally stored in formatted files, such as GIF or JPEG files. The AWT's Toolkit class exposes methods to create Image objects from popular graphical image formats. Files in one of these formats can be located either on the local file system, or anywhere on the network which can be addressed by a URL. Chapter 3 explains the Toolkit class in detail and explains these methods. For a list of the file formats which can be read by the AWT Toolkit, see the explanation of the Toolkit.createImage() method.
The second method for creating Image objects involves using the ImageProducer interface (discussed in Chapter 8). The ImageProducer API defines an object which can provide image pixel data in a standard way. Image pixel data is provided as individual pixel values and a ColorModel. The ColorModel explains how to convert each pixel's value into RGBΑ data. The AWT Toolkit class provides an overloaded version of the createImage() method, which creates an Image object from the pixel data provided by an ImageProducer.
The third method for creating an Image object is by using an ImageFilter. The ImageFilter accepts the pixel data from an ImageProducer and modifies that pixel data to create a filtered Image. For example, you might want to convert a particular Image by blurring it or sharpening it. To do this, you would define a BlurImageFilter, which will be used by the AWT Toolkit to convert a source image into a blurred image. The technique for defining and using an ImageFilter is explained in detail in Chapter 8.
Finally, and most simply, the AWT Toolkit also provides an overloaded version of createImage(), which allows you to create a blank Image of arbitrary width and height. Images created this way are called "in-memory" Images. In-memory Images can be drawn on, just like a display surface. This is done by acquiring a Graphics object associated with the Image as its display surface. You then use the Graphics' drawing methods to draw on the Image itself. Only in-memory Images can be drawn on this way. Images created using any one of the other three Image-creation techniques cannot be associated with a Graphics object as a display surface.
Except for in-memory Images, which are just blank, Images must be constructed from a pixel data source. This source may be a graphical formatted file, an ImageProducer you have implemented yourself, or an ImageFilter coupled with an ImageProducer. In any one of these three cases, the Java runtime system actually compiles the Image's pixel data only as it is needed. That is, the Image pixel data is only read into memory allocated on behalf of the Image object when a query is performed which requires the pixel data. For example, an Image created from a graphical file URL will just start to read in its pixel data asynchronously when you ask for the Image to be rendered using Graphics.drawImage.

Parameters

None.

Example

This example uses the Toolkit's getImage method to read an image from the local file system.

public class MyComponent extends Canvas

public MyComponent(URL urlImage)



getWidth

ClassName

Image

Purpose

Gets the width of the Image in pixels.

Syntax

public int getWidth(ImageObserver observer);

Parameters

ImageObserver observer

Object to receive asynchronous notification of the construction of this Image's pixel data if the data has not yet been read into memory.

Imports

java.awt.image.ImageObserver

Description

Retrieves the width of the Image in pixels. Requires an ImageObserver since the Image may have to be constructed asynchronously from its source.

Returns

The width of the Image in pixels is returned. If the Image pixel data has not yet been constructed in memory, then the asynchronous construction process is kick-started right away, and -1 is returned by this method. The ImageObserver observer will be notified at a later time when the Image's width is available.

Example

The ImageCanvas class is a visual Component which merely displays an image on its surface. The constructor to ImageCanvas requires an Image object that is to be displayed. The ImageCanvas' preferredSize method attempts to access the Image's width and height. The ImageCanvas implements the ImageObserver interface in case asynchronous construction of the Image is required.

public class ImageCanvas extends Canvas
implements ImageObserver

// Attempt to get _img Image width and height. If
// asynchronous construction is required, return a
// preferred size of (0, 0).
public Dimension preferredSize()

// Just display the _img Image.
public void paint(Graphics g)

// Default implementation of imageUpdate() forces a repaint
// always. We only want to do an actual repaint if the
// _img Image has been completely constructed, indicated
// by the ALLBITS flag of the infoflags parameter.
public void imageUpdate(Image img, int infoflags,
int x, int y, int width, int height)

getHeight

ClassName

Image

Purpose

Gets the height of the Image in pixels.

Syntax

public int getHeight(ImageObserver observer);

Parameters

ImageObserver observer

Object to receive asynchronous notification of the construction of this Image's pixel data, if the data has not yet been read into memory.

Imports

java.awt.image.ImageObserver.

Description

Retrieves the height of the Image in pixels. Requires an ImageObserver since the Image may have to be constructed asynchronously from its source.

Returns

The height of the Image in pixels is returned. If the Image pixel data has not yet been constructed in memory, then the asynchronous construction process is kick-started right away, and -1 is returned by this method. The ImageObserver observer will be notified at a later time when the Image's height is available.

Example

See the example under the method getWidth of the Image class.

getSource

ClassName

Image

Purpose

Gets an ImageProducer that can deliver the pixel data from this Image to an ImageConsumer.

Syntax

public abstract ImageProducer getSource();

Parameters

None.

Imports

java.awt.image.ImageProducer

Description

Creates a new ImageProducer which will pass this Image's pixel data to any ImageConsumer or ImageFilter. This method is most often used in conjunction with a FilteredImageSource and an ImageFilter to create a filtered version of the Image's pixel data, as demonstrated by the example code below.

Returns

An ImageProducer object is returned. This ImageProducer will deliver the pixel data and ColorModel for this Image to any ImageConsumer or ImageFilter it is associated with.

Example

The typical use of getSource is to create an ImageProducer to associate with an ImageFilter. This allows you to create a filtered version of the Image. The code below demonstrates exactly how you do this using a FilteredImageSource object.

Image imgBase;
ImageFilter filter;

// imgBase is made a reference to a valid Image object.
// filter is made a reference to a valid ImageFilter.

Image imgFiltered = new FilteredImageSource(imgBase.getSource(), filter);

getGraphics

ClassName

Image

Purpose

Gets a Graphics object which uses this Image as its display surface.

Syntax

public Graphics getGraphics();

Parameters

None.

Description

Retrieves a Graphics object associated with this Image. This Image object is the display surface for the Graphics, so that all rendering operations performed with the Graphics will be drawn on this Image. Only in-memory Images, created with the AWT Toolkit's overloaded createImage(width, height) method, will successfully retrieve a Graphics object. If you try to get the Graphics for an Image created using another technique, then this method will throw an exception.
Image.getGraphics is closely associated with the double-buffered rendering technique. The double-buffered rendering technique, for fast visual updating, utilizes an in-memory Image. All drawing operations are performed on the in-memory Image, through the Graphics retrieved by this method. When all graphics have been completely rendered, the Image is copied in full to the on-screen desktop display surface.

Returns

A Graphics object which uses this in-memory Image as its display surface.

Example

This example demonstrates double-buffering. In this example, the DoubleBufferCanvas' paint method performs several drawing operations on an in-memory Image. When all drawing operations on the in-memory Image are complete, the entire Image is copied to the on-screen display surface. Note that the DoubleBufferCanvas, which is a Component, acts as an ImageObserver for the drawImage operation.

public class DoubleBufferCanvas extends Canvas


getProperty

ClassName

Image

Purpose

Gets one of the properties stored with the Image.

Syntax

public Object getProperty(String name, ImageObserver observer);

Parameters

String name

Name of the property to retrieve. Individual properties are specific to the image format. Only three properties are publicly defined for the Java API, as indicated in the table below.

ImageObserver observer

If no properties have been read in for this Image yet, the ImageObserver will be notified about the property value asynchronously.

Description

An extensible list of Image properties is stored within the Image object. Each property has a text name, which is passed into this method to identify the property to retrieve. A property's value is an arbitrary Object.
A comprehensive list of the properties for different image formats is not available as of this book's publication. Also, there is no simple way to poll the Image for a list of its valid properties. The table below lists the three Image properties currently documented in the Java API.

Property

Description


"comments"

This property's value is a String which can describe the Image, hold a copyright notice, or relay any textual information about the Image.

"filters"

A concatenation of human-readable Strings (into a single String) listing the ImageFilters used in creating the Image.

"croprect"

If a CropImageFilter is used to create the Image, then the "croprect" property holds the boundaries of the rectangle of the original Image that was cropped.


Returns

The value of the named property. Note that if the property does not exist for the Image, then an Object class instance is returned (an Object object). If the properties for the Image have not yet been retrieved from the Image's source, then null will be returned and the object referenced by the observer parameter will be notified asynchronously when the Image's properties have been retrieved.

Example

This example prints an Image's values for the three known Image properties.

public void printImageProps(Image img, ImageObserver io)

flush

ClassName

Image

Purpose

Resets the constructed version of the Image.

Syntax

public void flush();

Parameters

None.

Description

All pixel data for the Image, which has been constructed, is flushed from the system. After a call to flush(), the Image is as if it had just been created and none of the image pixel data had been constructed yet. Any query of the Image's value would cause the Image to be reconstructed from scratch.

Returns

None.

Example

This example constantly reloads and redisplays an Image on a Canvas-derived component. This could be useful for doing Web server-based animation. (This particular example would not work for non-interlaced images, since interlaced images cause multiple paint calls to be made while the image is rendered in memory.)

public class ServerBasedAnimator extends Canvas

public void paint(Graphics g)

Point

Purpose

The Point class represents a two-dimensional point.

Syntax

public class Point

Description

A coordinate on the two-dimensional integer plain is abstracted by the Point class. The Point is comprised of an x and y coordinate value. Several public methods are also defined in the Point class for modifying these coordinate values.

Package

java.awt

Imports

None.

Constructors

public Point(int x, int y);
The Point object's x and y members are assigned the values of the x and y parameters to the constructor.

Parameters

The following table lists the Point class' public member variables.

Member

Description


int x

The distance along the X axis from the origin to this Point.

int y

The distance along the Y axis from the origin to this Point.


move

ClassName

Point

Purpose

Sets the x and y values of the Point object.

Syntax

public void move(int x, int y);

Parameters

int x

New X value for the Point.

int y

New Y value for the Point.

Description

Changes the x and y values for the Point object.

Example

See the example for the method translate.

translate

ClassName

Point

Purpose

Adds a dx and a dy value to the Point's x and y member variables.

Syntax

public void translate(int dx, int dy);

Description

Moves the Point a specified distance along either axis.

Parameters

int dx

Relative distance along the X axis to move the Point.

int dy

Relative distance along the Y axis to move the Point.

Example

The following example method moves the Point about the origin in a circle at the distance specified by the R parameter. Both move and translate are utilized.

public void CircularMotion(Point p, int R)

Polygon

Description

A Polygon is stored in Java as an ordered set of points on a two-dimensional plane. Each point represents a vertex of the polygon. The Polygon class includes some convenience methods to make polygons easier to work with. Also, the Graphics class includes two methods, fillPolygon and drawPolygon, so that you can draw your Polygon objects on display surfaces.
Consistent with the other geometric helper classes (Point and Rectangle), the Polygon class exposes its member variables with no protection.
Figure 7-13 shows the class hierarchy for the Polygon class.


Figure 7-13  Class hierarchy for the Polygon class

Package

java.awt

Imports

None.

Constructors

public Polygon();

public Polygon(int xpoints[ ], int ypoints[ ], int npoints);
The parameterless constructor creates a Polygon with no vertices. You must use the Polygon method addPoint to populate the Polygon with vertices. The second constructor takes an initial list of vertices, specified by an array of x coordinates and an array of y coordinates. When using this constructor, make sure your xpoints and ypoints arrays have at least npoints elements in them, or else an ArrayIndexOutOfBounds exception will be thrown.

Parameters

The following table lists the public member variables of the Polygon class.

Member

Description


int[ ] xpoints

An array of x coordinates.

int[ ] ypoints

An array of y coordinates. The nth element of the xpoints array and the ypoints array, taken together, indicates the location of the nth vertex of the Polygon. Both the xpoints array and the ypoints array are dynamically reallocated to make more room for new vertices as necessary.

int npoints

The number of vertices in the Polygon. The lengths of the xpoints and ypoints arrays are guaranteed to be at least npoints each.


Example

This example creates a Polygon whose vertices are in a star pattern.

public Polygon makeStar(int radius)

return poly;

addPoint

ClassName

Polygon

Purpose

Adds a new vertex to the Polygon.

Syntax

public void addPoint(int x, int y);

Parameters

int x

The x coordinate of the vertex to add to the Polygon.

int y

The y coordinate of the vertex to add to the Polygon.

Imports

None.

Description

Appends a new vertex to the Polygon. The new vertex is the last in the list of vertices, and conceptually is connected by a line to the first vertex and the second-to-the-last vertex.

Returns

None.

Example

See the example for the Polygon class constructor above.

getBoundingBox

ClassName

Polygon

Purpose

Gets the size of a bounding rectangle for this Polygon.

Syntax

public Rectangle getBoundingBox();

Parameters

None.

Imports

None.

Description

A Rectangle object which represents a rectangle that contains all the vertices of the Polygon. The Rectangle object which is returned is actually a private member variable of the Polygon object. This means that if you modify the member variable of the Rectangle object, and later call getBoundingBox, the changes you previously made to the Rectangle will be retained.

Returns

A Rectangle object which completely contains the Polygon.

Example

This example Component displays a Polygon. The Component uses the size of the Polygon's bounding rectangle as its preferred size.

public class MyPolyComponent extends Canvas



inside

ClassName

Polygon

Purpose

Tells whether a point lies within the Polygon.

Syntax

public boolean inside(int x, int y);

Parameters

int x

X coordinate of the point to test.

int y

Y coordinate of the point to test.

Imports

None.

Description

Tells whether or not a particular point lies within the Polygon. The evenodd insideness rule is used to determine whether or not the point is inside the Polygon's boundaries.

Returns

True is returned if the point lies inside the Polygon; otherwise false. The even-odd insideness rule is used to test for insideness.

Rectangle

Purpose

A Rectangle object represents a rectangle on a two-dimensional surface.

Syntax

public class Rectangle

Description

Rectangles are represented by an origin point, which is the upper-left corner of the rectangle, a width, and a height. Of all the shape classes, the Rectangle is by far the most completely implemented. Several methods for working with, and manipulating, rectangles are implemented. For example, methods for computing the intersection and union of rectangles are included. Also included are methods for combining rectangles with Point and Dimension objects. Figure 7-14 shows the class hierarchy for the Rectangle class.


Figure 7-14  Class hierarchy for the Rectangle class

Package

java.awt

Imports

None.

Constructors

public Rectangle();
public Rectangle(int x, int y, int width, int height);
public Rectangle(int width, int height);
public Rectangle(Point p, Dimension d);
public Rectangle(Point p);
public Rectangle(Dimension d);
These six overloaded constructors, taken as a group, allow you to specify none, one, or both of the Rectangle defining parameters: its points of origin and its dimensions. Note that the parameterless constructor actually does not initialize the Rectangle's member variables. If you use this constructor, be sure to zero-out the Rectangle using reshape.

Parameters

The following table lists the Rectangle class' public member variables.

Member

Description


int x

The x and y parameters define the Rectangle's point of origin.

int y

int width

The width and height parameters define the Rectangle's dimensions.

int height


reshape

ClassName

Rectangle

Purpose

Used to change both the Rectangle's origin and dimensions.

Syntax

public void reshape(int x, int y, int width, int height);

Parameters

int x

The x coordinate of the new origin of the Rectangle.

int y

The y coordinate of the new origin of the Rectangle.

int width

The new width of the Rectangle.

int height

The new height of the Rectangle.

Imports

None.

Descriptions

Modifies the origin point, the width, and the height of the Rectangle. Note that negative values are allowed, as the example for this method shows.

Returns

None.

See Also

The resize method of the Rectangle class.

Example

The Rectangle class allows negative widths and heights. If a Rectangle's width or height is less than zero, then the origin point is no longer the upper-left corner of the rectangle. However, Components, which have a Rectangle of display surface, do not allow widths nor heights less than zero. To facilitate the use of negative widths and heights, the following method uses reshape to keep the origin as the upper-left corner of the rectangle.

public void fixDimension(Rectangle r)

move

ClassName

Rectangle

Purpose

Changes the Rectangle's point of origin.

Syntax

public void move(int x, int y);

Parameters

int x

New x coordinate of the origin of the Rectangle.

int y

New y coordinate of the origin of the Rectangle.

Imports

None.

Description

Moves the Rectangle by changing its point of origin to another specified point.

Returns

None.

Example

See the example for the translate() method of the Rectangle class.

translate

ClassName

Rectangle

Purpose

Moves the Rectangle's point of origin a specified distance along and X and Y axes.

Syntax

public void translate(int dx, int dy);

int dx

Distance along the X axis to move the origin of the Rectangle.

int dy

Distance along the Y axis to move the origin of the Rectangle.

Imports

None.

Description

Moves the Rectangle a specified distance along the X and Y axes. The origin after the call is distance (dX, dY) from the origin before the call.

Example

This example demonstrates how to implement translate as a call to move, since these two methods are so similar.

public void translate(Rectangle r, int dx, int dy)

resize

ClassName

Rectangle

Purpose

Modified the dimensions of the Rectangle.

Syntax

public void resize(int width, int height);

Parameters

int width

New width of the Rectangle.

int height

New height of the Rectangle.

Imports

None.

Description

Changes the width and height of the Rectangle without modifying the Rectangle's origin.

Returns

None.

Example

The CrossHairs component uses four rectangles to draw a cross-hair that centers wherever the user clicks the mouse.

public class CrossHairs extends Canvas

// when component resized, resize rects
public void resize(int width, int height)

public void paint(Graphics g)

public boolean mouseDown(Event evt, int x, int y)

inside

ClassName

Tells whether a point is inside the Rectangle.

Syntax

public boolean inside(int x, int y);

Parameters

int x

The x coordinate of the point to test.

int y

The y coordinate of the point to test.

Imports

None.

Description

Tells whether or not the specified point lies inside the Rectangle. Points which fall on the border of the Rectangle are considered inside the Rectangle.

Returns

If the given point lies inside the Rectangle, or on its border, then true is returned. False is returned if the point lies outside the Rectangle.

Example

This example component draws a rectangle whose lower-right corner is the place where the last mouse click occurred.

public class GrowRect extends Canvas

public void paint(Graphics g)

public boolean mouseDown(Event evt, int x, int y)

intersects

ClassName

Rectangle

Purpose

Tells whether a Rectangle intersects with another.

Syntax

public boolean intersects(Rectangle r);

Parameters

Rectangle r

This external Rectangle is tested to see if it intersects this Rectangle.

Imports

None.

Description

Tells whether or not another Rectangle intersects this one. Rectangles which share a segment of border or a corner point are considered to intersect.

Returns

If the external Rectangle intersects this Rectangle, or the two Rectangles share a segment of border or a corner point, then the Rectangles are said to overlap. In this case, true is returned. Otherwise, false is returned.

Example

This example shows one possible implementation of the intersects method.

public class Rectangle



intersection

ClassName

Rectangle

Purpose

Calculates the intersection of this Rectangle with another.

Syntax

public Rectangle intersection(Rectangle r);

Parameters

Rectangle r

The external Rectangle to intersect with this one.

Imports

None.

Description

Computes the new Rectangle which is the intersection of this Rectangle and an external Rectangle object. If the two Rectangles do not overlap, then the resulting intersection has a zero width and a zero height. The origin of this null-intersection Rectangle has an interesting relationship to the original two Rectangles, but it is essentially useless. Use isEmpty to test whether the resultant Rectangle represents an empty intersection.

Returns

A new Rectangle object is created and returned which lies completely within both the external Rectangle and this Rectangle.

Example

See the example for the intersect method of the Rectangle class.

union

ClassName

Rectangle

Purpose

Finds a bounding Rectangle for this Rectangle and another.

Syntax

public Rectangle union(Rectangle r);

Parameters

Rectangle r

External Rectangle which is to be unioned with this Rectangle.

Imports

None.

Description

Computes a new Rectangle which completely contains this Rectangle and an external Rectangle object. The resultant union Rectangle is the smallest Rectangle which can contain both input rectangles.

Returns

The returned Rectangle is a new Rectangle which is the smallest Rectangle which can contain the two input Rectangles.

add

ClassName

Rectangle

Purpose

Unioning two Rectangles, or a Rectangle and a Point.

Syntax

public void add(int x, int y); public void add(Point pt); public void add(Rectangle r);

Parameters

int x

The x coordinate of the point to add to this Rectangle.

int y

The y coordinate of the point to add to this Rectangle.

Point pt

Point to add to this Rectangle.

Rectangle r

Rectangle to add to this Rectangle.

Imports

None.

Description

The addition of a Rectangle and a point is analogous to the union operation. The new dimension of this Rectangle is the smallest which can contain both the original Rectangle and a given point. The addition of another Rectangle uses the same procedure as a union operation. The overloaded add methods modify the origin, width, and height of this Rectangle. The resultant dimensions and placement of this Rectangle represent the smallest Rectangle which can contain both the original Rectangle and any external point or external Rectangle object.

Example

See the example for the inside method of the Rectangle class.

grow

ClassName

Rectangle

Purpose

Grows a Rectangle's Dimensions.

Syntax

public void grow(int h, int v);

Parameters

int h

Distance in the horizonal direction to move the left and right borders away from the center of the Rectangle. Negative numbers move the borders toward the center.

int v

Distance in the vertical direction to move the top and bottom borders away from the center of the Rectangle. Negative numbers move the borders toward the center.

Imports

None.

Description

Makes the dimensions of the Rectangle larger (or smaller) according to the magnitude of the horizontal and vertical grow parameters. The Rectangle is modified in such a way that all broders are moved a uniform distance away from (or towards) the center of the original Rectangle.

Returns

None.

Example

This example demonstrates how the grow method can be used to shrink rectangles, too.

public void shrink(Rectangle r, int h, int v)

isEmpty

ClassName

Rectangle

Purpose

Tells whether either of the Rectangle's Dimensions are 0.

Syntax

public boolean isEmpty();

Parameters

None.

Imports

None.

Description

Tests the Rectangle to see if it has a non-zero volume. That is, whether or not both the width and height parameters are non-zero. It is useful to use isEmpty() to see if the results of the intersection() method produce a non-empty Rectangle object.

Returns

True is returned if the Rectangle indeed has a zero internal volume. This indicates either the width or the height of the Rectangle is zero (or both).

Example

See the example for the intersects method of the Rectangle class.

The Graphical Object Project: Doodle

The Graphical object SuperBible Project is the Doodle application. Doodle is a simple whiteboard application. It allows you to draw Lines, Rectangles, Polygons, and text on the drawing surface. Through simple mouse clicks and drags, you define the shape and placement of each "doodle" on the whiteboard surface. Figure 7-15 shows the Doodle application in action. The Java code for the Doodle application is included under the directory Chap07 on the CD accompanying this book.


Figure 7-15  Screenshot of the Doodle application running

Doodle's user-interface employs two toolbars: shape and color. The shape toolbar has five buttons, labeled Line, Rect, Polygon, Image, and Text. You click on the button for the type of doodle you want to draw. The Color toolbar contains a set of several radio buttons. When you select a radio button, all doodles will be drawn using the corresponding Color.

Doodle employs "virtual Components" to draw each of the doodles you define. For example, instances of the DoodleLine class, also defined in Doodle.java, draw a single line on the whiteboard surface. DoodlePoly objects draw a polygon; DoodleRect objects draw filled rectangles, etc.

A virtual Component is a Canvas-derived class which explicitly prevents its peer from being created. Why stop the peer from being created? Isn't the whole point of Components that it allows you to draw on a rectangle of the on-screen desktop? The reason is that overlapping Components, created with a peer, automatically "clip" siblings. That is, Components added to the same Container cover each other, so overlapping sibling Components are not transparent. Imagine drawing two diagonal lines right next to each other: If each line was represented by a single DoodleLine Component, then the Component on top would completely overwrite the Component on the bottom. Doodle was created with transparent Components to prevent this overwriting problem.

By removing the operating system peer, each Doodle graphical object Component represents a rectangle of the whiteboard's surface. The whiteboard uses each Doodle Component's paint method to render the doodle on its rectangle, but the Doodle Component makes sure it does not erase anything. The practical result is transparent Component objects.

But removing a Doodle Component's peer has two important side effects:

.  No paint() calls are made by the Java runtime system for the Component. Instead, the whiteboard, which contains the Doodle Components, must explicitly call each Component's paint() method to let the Doodles draw themselves.

.  No Events, such as mouse or keyboard Events, are delivered by the Java runtime system to the Doodle Component. Again, the whiteboard must explicitly deliver these Events to the correct Component object.

The Doodle application overcomes both of these shortcomings to allow each virtual Component to act like a Canvas with a peer, in addition to being transparent.

Assembling the Project

Follow these steps to assemble the Doodle application.

1.  Create a text file named Doodle.java. Make sure the correct packages are imported and implement the static method, which just creates Doodle's main Frame window. Here is the code:

import java.awt.*;
import java.util.Hashtable;
import java.util.Vector;
import java.awt.image.ImageObserver;
public class Doodle

2.  Create the Doodle application's main Frame class. This class manages the shape and color toolbars. Start by declaring the member variables for these toolbars. Also declare the DoodleView. The DoodleView is the actual whiteboard on which we will draw the doodles.

class DoodleFrame extends Frame

3.  The DoodleFrame constructor creates the interface for the Doodle application. It creates the two toolbars and adds the DoodleView to the Frame. The DoodleFrame uses a GridBagLayout to arrange the two toolbars and the DoodleView. See Chapter 6 for an explanation of the LayoutManager classes. In this application, the GridBagLayout ensures the toolbars and the DoodleView arrange themselves neatly no matter what the size of the DoodleFrame. Here is the code for the constructor:

public DoodleFrame(String strTitle)

4.  The DoodleFrame must catch WINDOW_DESTROY Events so it knows when to destroy the main window. Here's the code for DoodleFrame's overridden handleEvent method:

public boolean handleEvent(Event evt)

return super.handleEvent(evt);

5.  When a toolbar button is pressed, the DoodleFrame catches the event and "remembers" (in a member variable) the last button pressed. The buttons indicate what type of doodle the user wants to paint. Here is the code for DoodleFrame's overridden action implementation:

// action() will be called whenever one of the
// toolbar buttons is pressed. When this happens,
// report new doodle tool and store reference
// to the button pressed.
public boolean action(Event evt, Object what)

// Everything else can be ignored.
return false;
}

6.  The DoodleFrame.createDoodleCompInstance method creates a new Doodle component ("DoodleComp") of the type indicated by the last toolbar button pressed. The DoodleView calls this method when it detects the user has started drawing a new doodle. Here's the code for that method:

// createDoodleCompInstance() creates a new DoodleComp
// of the type indicated by the last toolbar button
// that was clicked. This is called by the DoodleView
// when it determines its time to create a new doodle.
public DoodleComp createDoodleCompInstance()

7.  The other thing the DoodleView needs to get from the DoodleFrame is the color currently selected in the color toolbar. The DoodleFrame.getDoodleColor method returns the Color corresponding to the color selected in the color toolbar. Here's the code for that method:

// getDoodleColor returns the hashtable entry for the
// colorbar checkbox which is currently checked.
public Color getDoodleColor()

8.  That was the last DoodleFrame method. The DoodleFrame class is now fully implemented. Now we declare the DoodleView class. The DoodleView is the whiteboard panel which is the parent of all the DoodleComp virtual Components. The DoodleFrame uses double-buffering so that redrawing of the screen is smooth. Here's the declaration of the DoodleView class and its member variables:

class DoodleView extends Panel

9.  The DoodleView constructor requires a reference to the application's DoodleFrame to be passed. In the constructor, the DoodleView does some minor initialization work. Here is the code for the DoodleView constructor:

public DoodleView(DoodleFrame df)

10.  To avoid "flicker" caused by the default implementation of update, DoodleView must override update to simply call paint.

public void update(Graphics g)

11.  To implement double-buffering, the DoodleView must keep around an in-memory Image and associated Graphics object. The Image must be exactly the same size as the DoodleView itself. To achieve this, DoodleView.reshape is implemented. The reshape method is automatically called whenever the DoodleView is resized. So in our implementation, DoodleView calls the base class implementation of reshape, but also creates a new Image and associated Graphics of exactly the correct size. Here's the code:

// Whenever the view is reshaped, must re-allocate
// our in-memory image to be the same size.
public void reshape(int x, int y, int width, int height)

12.  Since DoodleComps have no peers, the Java system never tells them to repaint themselves. Instead, the DoodleView will explicitly tell each DoodleComp to paint itself onto the in-memory Image whenever the DoodleView's paint method is called. Here is the code for DoodleView's paint method:

// Since all DoodleComps have no peers, this
// DoodleView is responsible for making sure
// they paint themselves. Use double-buffering
// to minimize visual flicker.
public void paint(Graphics g)
}

// Copy in-memory image to Graphics g.
g.drawImage(_img2blBuf, 0, 0, this);

return;

13.  The DoodleFrame calls the DoodleView's notifyToolChanged method whenever the user selects a new shape button on the shape toolbar. This gives the DoodleView a chance to abort any doodle which is only half-drawn. For example, let's say the user was typing some text. The Doodle application requires that the user clicks with the mouse to notify the application when she is done with a particular doodle. But instead the user clicks on a different tool on the shape toolbar. In that case, the DoodleView should remove the half-finished DoodleComp. That's what notifyToolChanged does. Here's the code:

// The DoodleFrame calls notifyToolChanged whenever
// the user selects a doodle tool button. The view
// abandons any incomplete doodles and gets rid
// of them if this happens.
public void notifyToolChanged()
return;

14.  Interpretation of mouse and keyboard events is left completely up to the DoodleComps themselves. The DoodleView passes all mouse and keyboard actions to the DoodleComp currently being edited, if there is one. The DoodleComp lets the DoodleView know when it is done by either returning false from the mouse or keyboard Event, or by returning true from its isComplete method at any time. Here's DoodleView's mouse Event methods, which pass the Events on to the active Doodle:

// If a mouse-down occurs, and there is no active
// doodle, then a new one is created using
// DoodleFrame.createDoodleCompInstance().
public boolean mouseDown(Event evt, int x, int y)

// Pass mouse message on to the active doodle.
boolean fRet = _ActiveDoodleComp.mouseDown(evt, x, y);

if((false==fRet) ||
(true==_ActiveDoodleComp.isComplete()))
_ActiveDoodleComp = null;

return fRet;


// Mouse drags are simply passed on to the active
// doodle, if there is one. If active doodle
// isComplete() after processing the message, then
// we can drop reference.
public boolean mouseDrag(Event evt, int x, int y)

// Mouse ups are simply passed on to the active doodle,
// if there is one. If active doodle isComplete() after
// processing the message, then we can drop reference.
public boolean mouseUp(Event evt, int x, int y)

15.  Keyboard Events, specifically keyDown events, are treated the same as mouse Events by the DoodleView. Here's the code for the DoodleView's keyDown Event handler.

// key presses are simply passed on to the active
// doodle, if there is one. If active doodle
// isComplete() after processing the message,
// then we can drop reference.
public boolean keyDown(Event evt, int key)

16.  That's it for the DoodleView. Now for the individual DoodleComp classes. Each DoodleComp represents, and is able to edit and draw a single doodle, such as a line or a polygon. All types of DoodleComps are derived from the DoodleComp class, which does nothing more than implement a few methods which will be re-used by the individual doodle classes, and declare the isComplete method. Doodles being edited let the DoodleView know they do not want any more events passed to them by returning true from the isComplete method. Here's the full implementation of the DoodleView class:

abstract class DoodleComp extends Canvas

// Avoid adding a peer by overriding addNotify().
public void addNotify()
// paint() is called explicitly by the Doodle-
// View when it is painting itself. Graphics
// has no guarantee of state, so this implementation
// does a little initialization. Derived classes
// can call super.paint() to have this code run
// before doing any actual rendering on the
// Graphics.
public void paint(Graphics g)

// isComplete() returns true if the doodle
// has been completed.
public abstract boolean isComplete();

17.  Now for the individual doodles. The simplest is the DoodleLine. The DoodleLine just waits for the mouse button to be let go. At that point, the Line is defined by two points: where the mouse was when the DoodleLine was created, where the mouse was when the user let go of the mouse button. Here's the code for the DoodleLine's constructor, member variables, and isComplete method implementation:

class DoodleLine extends DoodleComp

public boolean isComplete()

18.  The DoodleLine keeps track of where the user is dragging the mouse. This is important because if the user drags the mouse to the left or upward of the upper-left corner of the DoodleLine, then the DoodleLine must resize and reposition itself with its origin far enough towards the application's upper-left corner to encompass the new point. Here's the code for DoodleLine.mouseDrag:

public boolean mouseDrag(Event evt, int x, int y)
if(_ptDrag.y < 0)

Rectangle r = bounds();
r.add(new Point(x, y));
reshape(r.x, r.y, r.width, r.height);

getParent().repaint(r.x, r.y, r.width, r.height);

return true;

19.  The initial MOUSE_DOWN Event defines where the first point of the DoodleLine is, and a MOUSE_UP Event causes the DoodleLine to report that it is done editing. Here's the code for the mouseDown and mouseUp event handlers of the DoodleLine class:

public boolean mouseDown(Event evt, int x, int y)

public boolean mouseUp(Event evt, int x, int y)
if(_pt2.y < 0)

Rectangle r = bounds();
r.add(new Point(x, y));
reshape(r.x, r.y, r.width, r.height);

getParent().repaint(r.x, r.y, r.width, r.height);

return true;

20.  The paint method of all DoodleComps is called explicitly by the DoodleView from its paint implementation. Here is DoodleLine's implementation, which makes sure to call its superclass implementation of paint first (DoodleComp.paint). The superclass implementation sets up the Graphics with the proper colors, fonts, and painting mode. Here's DoodleLine's painting code:

public void paint(Graphics g)

if(null != _ptDrag)
g.drawLine(_pt1.x, _pt1.y, _ptDrag.x,
_ptDrag.y);
return;

The rest of the DoodleComp classes are very similar to DoodleLine. Similarly to DoodleLine, they handle mouse and keyboard events until the user is done editing the doodle. They all use pretty much the same code to ensure the bounding rectangle of the DoodleComp continually contains the location of the mouse.

How It Works

The following table lists all the classes defined in the Doodle application, and a short description of each.

Class

Description


Doodle

The class contains the static main() method for the Doodle application. This is the only public class in the Doodle project.

DoodleFrame

The main window of the Doodle application. The DoodleFrame window creates the two toolbars, allowing the user to select a type of doodle to draw on the whiteboard surface and a Color to draw in. The two toolbars and the whiteboard (DoodleView) are the three Components added to this Container.

DoodleView

This is the whiteboard Component. This is where the guts of making the DoodleComp (doodle Component) virtual Components work. Mouse and keyboard Events on the whiteboard are delivered explicitly to the correct DoodleComp. When the whiteboard is supposed to paint itself, it explicitly calls each DoodleComp's paint() method with a unique Graphics attached to the DoodleComp's rectangle.

DoodleComp

This is the base class for all the doodle Component objects. The methods, which are implemented the same for each doodle Component, are implemented in this class.

DoodleLine

Each doodle line is a single line the user drew on the whiteboard surface. It collects a mouseDown() and a mouseUp() Event call (sent explicitly by the whiteboard) to define a line to draw.

DoodleRect

Each doodle rectangle is a filled rectangle the user drew on the whiteboard surface. It collects a mouseDown() and mouseUp() Event call to define the upper-left and lower-right corners of the rectangle.

DoodlePoly

Each doodle polygon is a filled Polygon the user drew on the whiteboard surface. The user defines the polygon by a series of mouse down,drag, and mouse up actions.

DoodleText

Each String of text the user defined to be drawn on the whiteboard surface is stored as a DoodleText. All keyboard Events sent by the DoodleView to a DoodleText are stored up by the DoodleText. A mouse click defines the upper-right corner of the DoodleText's surface rectangle.

NullLayout

The doodle Components should be placed and sized exactly how the user defines them with her mouse clicks and drags. The whiteboard uses a NullLayout as its LayoutManager. NullLayout does absolutely nothing to the size or position of the doodle Components. Thus, the doodle Components can place themselves wherever they want using their own move(), resize(), or reshape() methods.

PolygonEx

There is no translate() method for the Polygon class in the Java API. The PolygonEx class defines a method to move, or translate, all the vertices in a Polygon object any distance in either the X or Y directions.


Use of Rectangles in Doodle

Each doodle object in the Doodle application is represented by a Component object. One drawback with the Component class is that it does not allow you to specify a negative width or height when reshaping the Component on the screen. For the Doodle application, this poses a little problem. While allowing the user to click-and-drag to define a doodle, say for instance a LineDoodle, the Doodle application must continually reshape the LineDoodle component. If the user drags the mouse to the right or below the LineDoodle's rectangle, then the Doodle application simply adds to the width and/or height of the LineDoodle Component and redraws it. If, on the other hand, the user drags the mouse above or to the left of the LineDoodle component, both the origin and dimensions of the Component must be changed. The trick is to ensure that the upper-left-most extent of the Component is always the origin.

The code DoodleLine uses whenever it receives a mouse-drag is:

public boolean mouseDrag(Event evt, int x, int y)
if(_ptDrag.y < 0)

// Reshape this Component to encompass the
// new mouseDrag point.
Rectangle r = bounds();
r.add(new Point(x, y));
reshape(r.x, r.y, r.width, r.height);

// Since line has changed, repaint it by repainting
// its rectangle within the Container's surface.
getParent().repaint(r.x, r.y, r.width, r.height);

// This Component will continue processing events, so
// return true to indicate line is not yet complete.
return true;

The DoodleRect and DoodlePoly virtual Components use a similar technique to reshape themselves whenever the user expands them to the left or upward. DoodleRect uses almost exactly the same code as DoodleLine. The big difference between the two is in the paint method. DoodleLine paints a line between its internally stored _pt1 and _pt2 Point member variables, while DoodleRect fills a Rectangle which is its bounds.

The DoodlePoly class is different than DoodleLine or DoodleRect in that the user does not use a single mouse click-and-drag to define the Polygon. Instead, the user uses a series of mouse clicks-and-drags, one for each segment of the Polygon to draw. Instead of using mouseDrag to reshape the Polygon and redraw it, DoodlePoly uses mouseUp. Nevertheless, the technique is still the same: If the MOUSE_UP event is above or to the left of the DoodlePoly Component, then the DoodlePoly is moved and reshaped to keep the origin as the upper-left corner of the Component to avoid having a negative width or height.

Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 946
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved