CATEGORII DOCUMENTE |
Asp | Autocad | C | Dot net | Excel | Fox pro | Html | Java |
Linux | Mathcad | Photoshop | Php | Sql | Visual studio | Windows | Xml |
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 GraphicsWithout the Color class, this single parameter would be replaced by three, making coding more complex:
public abstract class GraphicsIn 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.
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 dataWhen 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
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.
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
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();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 |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
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);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;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;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
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 heightAn alternative, and easier, way to do the same thing is
Rectangle r = myComponent.bounds();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)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 lineThe 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
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-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.
PackageName java.awt Imports java.io.*, java.lang.* Constructors public Color(int red, int green,
int blue); 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.
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); 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.
Package java.awt Imports None. Constructors public Font(String name,
int style, int size); 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.
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);
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. 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.
Package awt.java Imports None. Constructors public FontMetrics(Font font);
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 Canvaspublic 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. 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. 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 FontMetricsImage 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.
Package java.awt Imports java.awt.image.ImageProducer, java.awt.image.ImageObserver Constructors None. Parameters None. Example This example uses the Toolkit's getImage method to read an image from the local file system. public class MyComponent extends Canvaspublic 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 Canvasimplements 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. 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 CanvasgetProperty 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.
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 Canvaspublic 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); Parameters The following table lists the Point class' public member variables.
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.
Package java.awt Imports None. Constructors public Polygon(); public Polygon(int xpoints[ ], int
ypoints[ ], int npoints); Parameters The following table lists the public member variables of the Polygon class.
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 Canvasinside 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.
Package java.awt Imports None. Constructors public Rectangle(); Parameters The following table lists the Rectangle class' public member variables.
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 Canvaspublic 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 Rectangleintersection 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: DoodleThe 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.
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 ProjectFollow 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 Frame3. 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 Panel9. 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 DoodleComppublic 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 WorksThe following table lists all the classes defined in the Doodle application, and a short description of each.
Use of Rectangles in DoodleEach 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 |
Vizualizari: 1045
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved