티스토리 뷰

Introduction to Graphics Programming using WFC

The display of graphical objects in Microsoft Windows occurs through the graphics device interface (GDI), a device-independent graphics output model that processesgraphical function calls from a Windows-based application and passes those calls to theappropriate device driver. The driver performs the hardware-specific functions thatgenerate output. By acting as a buffer between applications and output devices, the GDIpresents a device-independent view for the application while interacting in adevice-dependent format with the device.

Application developers use the functionality of the GDI  to display images, todraw controls, shapes, and text, and to create and use pens, brushes, and fonts. TheWindows Foundation Classes (WFC) for Java Graphics object coordinates with otherWFC objects, such as the Pen, Font, and Brush objects, toencapsulate  these capabilities as Java-based objects.

In the WFC environment, graphical output occurs through the Graphicsobject.  This chapter provides an illustrated overview of this object's capabilities,and includes the following topics:

Creating a Graphics Object

The WFC environment provides several ways to access the capabilities of the Graphics object.

·                     You can explicitly create a Graphics object from within a control class. To do this, use the form's createGraphics method, as follows:

Graphics g = this.createGraphics();

When you create a Graphics object in this fashion, graphical operations performed using that object apply only to the control through which it was created.

·                     You can add a paint event handler to your Form class code, and use the Graphics object instance stored in the PaintEvent object. To do this, display the form's properties in the Properties window, open the event list, and double-click the paint entry. This action adds the following handler in your Form class code.

Form1_paint(Object sender, PaintEvent e){

}

The PaintEvent object contains a graphics public member, and this member is a valid Graphics object instance. You reference this object in your paint event handler as follows:

Form1_paint(Object sender, PaintEvent e){

e.graphics.drawString("Hello, World", new Point(10, 10));

}

·                     You can retrieve a Graphics object instance from any object that supports a method that creates and returns a Graphics object. The Bitmap object's getGraphics method provides an example of this support.

Bitmap bmpBubbles = new Bitmap("c:\\bubbles.bmp");

Graphics g = bmpBubbles.getGraphics();

Keep in mind that when you retrieve a Graphics object instance in this way, the object belongs to the object through which you retrieved it. Thus, in the example above, a call to one of the object's drawing methods results in drawing to the bitmap, not to the form.

After creating a Graphics object, you associate other graphics-based objects, such as fonts, pens, and brushes with the object, and then use the object's numerous drawing methods to render output to the display. For example, to draw lines with a specific appearance, you use the Graphics object's setPen method to specify the pen that the object will use for drawing. You can modify these associations as often as you want.

The following table lists the objects that you specifically associate withthe Graphics object.

Object

Description

Brush

Used to fill enclosed surfaces with patterns, colors, or bitmaps.

Font

Used to describe text to be rendered to a form.

Pen

Used to draw lines and polygons, including rectangles, arcs, and pies.

Graphics Object Scope

The Graphics object has method scope. This means that when a method in which you usethe Graphics object returns, the object’s dispose method is calledautomatically, freeing all resources that the object has allocated. After disposehas been called, attempts to use the object result in a run-time exception.

If you declare an instance of the Graphics object at the class level, you shoulduse the Form object’s createGraphics method to initialize that objectin every method that uses it.

Public class Form1 extends Form{

Graphics g = new Graphics();

Private void Form1_resize(Object sender, Event e){

   // Initialize object instance.

   g = this.createGraphics();

   // dispose automatically called…

}

private void Form1_click(Object sender, Event e){

   // Initialize object instance.

   g = this.createGraphics();

   // dispose method automatically called…

}

}

Maintaining the Bounding Rectangle

The area of a window in which you can draw is referred to as the window’s clientarea. Within this area, a bounding rectangle defines the invisible rectangularregion in which the Graphics object draws, and can include the window’s entireclient area.

When a window loses, and then regains focus, the part of the bounding rectangle coveredby some other object does not automatically re-display the items that were previouslyrendered to it.

To ensure correct display, you must manage the repainting of your form. The paintevent handler is the place in your Form class code in which such managementtypically takes place. Within this handler, you restore the bounding rectangle to itsproper state.

The following example creates a Bitmap object at the class level, then it usesthe paint event handler to redraw the Bitmap. Each time the client area ofthe form becomes invalid, Windows invokes this handler, and the image is repainted to theform.

Bitmap bmp = new Bitmap("c:\\MyImage.bmp");

private Form1_paint(Object sender, PaintEvent e){

   e.graphics.drawImage(bmp, new Point(0, 0));

}

When your form is initially displayed, and each time it regains focus, the paintevent handler is automatically invoked. However, if your form supports resizing, a changein the form’s dimensions does not automatically trigger a repaint. Instead, you mustadd a resize handler to the Form class and then call the Formobject’s invalidate method from within this handler. A call to invalidatetrigger’s the form’s paint event handler.

private void Form1_resize(Object sender, Event e){

   this.invalidate();

}

Drawing Text

The Graphics object's drawString method outputs a string of text to aform.  The drawString method writes the text to the location that you specify,using the object's current background color, text color, and font settings.

The following call to the drawString method displays the text "Hello,World" in the upper left corner of a form.

Graphics g = this.createGraphics();
g.drawString("Hello, World", new Point(0, 0));

To determine the text and background color of the text, use the Graphicsobject's setBackColor and setTextColor before calling drawString.

// Set the text to white, the background to black.

g.setTextColor(Color.WHITE);
g.setBackColor(Color.BLACK);

// Draw the text...

The setBackColor method affects only the background color of text. To set thebackground or fill color for other objects, such as polygons and lines, use the setBrush and setPen methods, respectively.

Using the Font Object

A font is a collection of characters and symbols that share a common design. Themajor elements of a font include its typeface, style, and size.

In the WFC, Windows fonts are encapsulated in the Font object.  The Graphics object supports the setFont method, which associates a font with the Graphics object. The object also supports the getFontDescriptors method, which returns an array of FontDescriptor objects, in which each object describes one of theavailable system fonts.

After you associate a Font with the Graphics object, all text drawnwithin the Graphics object's bounding rectangle is drawn using that font.

The following program statements illustrate the process of setting the background colorof the Graphics object to white, the text color to black, and the font to 26-pointTimes New Roman. The text is drawn to the display at a specified position.

Graphics g = this.createGraphics();

g.setFont(new Font("Times New Roman", 26));
g.setBackColor(Color.WHITE);
g.setTextColor(Color.BLACK);
g.drawString("Hello, World", 0, 0);

Enumerating Fonts

In some instances, an application must be able to enumerate and retrieve detailedinformation about the available fonts, and to select the one most appropriate for aparticular operation.

The WFC FontDescriptor object describes a font, including the font's name,height, orientation, and so forth. For a detailed description of all the fonts availableon your system, use the Graphics object's getFontDescriptors method. This method returns an array of FontDescriptor objects, in which each element inthe array describes a font.

The following example illustrates how to use the getFontDescriptorsmethod.  This example retrieves an array of available fonts and then inserts a uniquelist of the font names into a list box.

Graphics g = this.createGraphics();

// Create the array.

FontDescriptor rgFonts[] = g.getFontDescriptors();

for(int i = 0; i < rgFonts.length; i++){

   if(listBox1.findString(rgFonts[i].fullName) == -1){

       listBox1.addItem(rgFonts[i].fullName);

   }

}

Using Pens

A pen is a graphics tool that an application for Microsoft Windows uses to drawlines and curves. Drawing applications use pens to draw freehand lines, straight lines,and curves. Computer-aided design (CAD) applications use pens to draw visible lines,hidden lines, section lines, center lines, and so on. Word processing and desktoppublishing applications use pens to draw borders and rules. Spreadsheet applications usepens to designate trends in graphs and to outline bar graphs and pie charts.

Each pen consists of three attributes: style, width, and color.  While no limitsare imposed on the width and color of a pen, the pen's style must be supported by theoperating system. These styles are illustrated in the following figure.

WFC Pen Object

The capabilities of Win32 pens are encapsulated in the WFC Pen object. Thefollowing code fragment demonstrates how to create a Pen object.

Pen p = new Pen(Pen.PS_DASH);

The constant that you pass to the Pen object constructor is a pen style.The seven built-in pen styles supported on Windows are each represented by a constantdefined in the Pen class. The following table lists these constants.

Constant

Description

Pen.STYLE_DASH

Represents a dashed pen.

Pen.STYLE_DOT

Represents a dotted pen.

Pen.STYLE_DASHDOT

Represents a pen of alternating dashes and dots.

Pen.STYLE_DASHDOTDOT

Represents a pen of alternating dashes and double dots.

Pen.STYLE_INSIDEFRAME

Represents a pen that draws a line inside the frame of closed shapes produced by the Graphics object’s output functions that specify a bounding rectangle (for example, drawRect, drawPie, and drawChord).

Pen.STYLE_NULL

Represents a null pen.

Pen.STYLE_SOLID

Represents a solid pen.

Setting the Pen on a Graphics Object

The Pen object itself contains no coloring or drawing capability. It onlydescribes a subset of the capabilities of the GDI. Before you use a Pen to draw ona form, you associate the Pen with a Graphics object using the Graphicsobject's setPen method.

Graphics g = this.createGraphics();

g.setPen(new Pen(Pen.STYLE_DASH));

After you associate a Pen with a Graphics object, all lines drawn withinthe Graphics object's bounding rectangle are drawn using that pen. In addition, youcan call the setPen method any number of times on the same Graphics object.

The following example demonstrates how the Pen object works with theline-drawing capabilities of the Graphics object. In this example, the Penstyles defined in the Pen object are stored in an array of integers. Within theclass's paint event handler, a for loop is used to iterate through thisarray of pen styles, drawing a single line using each style.

public class Form1 extends Form{

// Create an array that contains all Pen styles.

int rgPenStyles[] = { Pen.STYLE_DASH, Pen.STYLE_DASHDOT,                    Pen.STYLE_DASHDOTDOT,
              Pen.STYLE_DOT,Pen.STYLE_INSIDEFRAME, Pen.STYLE_SOLID };

// Loop through the array of PenStyles, associating each with the
// Graphics object in turn, and then use the drawLine method to
// draw a line that uses the pen.

private void Form1_paint(Object sender, PaintEvent e){

   Rectangle rcBounds = this.getBounds();
   rcBounds.y += 10;

   for(int i = 0; i < rgPenStyles.length; i++){

       e.graphics.setPen(new Pen(Color(0,0,0),rgPenStyles[i]));
       e.graphics.drawLine(new Point(0, rcBounds.y),
           newPoint(rcBounds.width, rcBounds.y));
       rcBounds.y += 10;
   }

}

// Rest of Form1 class...

Using Brushes

A brush is a graphics tool that a Win32-based application uses to paint theinterior of polygons, ellipses, and paths. Drawing applications use brushes to paintshapes; word processing applications use brushes to paint rules; computer-aided design(CAD) applications use brushes to paint the interiors of cross-section views; andspreadsheet applications use brushes to paint the sections of pie charts and the bars inbar graphs.

There are two types of brushes: logical and physical. A logical brush is one that youdefine in code as the ideal combination of colors and/or pattern that an applicationshould use to paint shapes. A physical brush is one that a device driver creates based onyour logical-brush definition.

Brush Origin

When an application calls a drawing function to paint a shape, Windows positions abrush at the start of the paint operation and maps a pixel in the brush bitmap to thewindow origin of the client area. (The window origin is the upper-left corner of thewindow's client area.) The coordinates of the pixel that Windows maps are called the brushorigin.

The default brush origin is located in the upper-left corner of the brush bitmap at thecoordinates (0,0). Windows then copies the brush across the client area, forming a patternthat is as tall as the bitmap. The copy operation continues, row by row, until the entireclient area is filled. However, the brush pattern is visible only within the boundaries ofthe specified shape. (Here, the term bitmap is used in its most literal sense — as anarrangement of bits — and does not refer exclusively to bits stored in an imagefile).

There are instances when the default brush origin should not be used. For example, itmay be necessary for an application to use the same brush to paint the backgrounds of itsparent and child windows and blend a child window's background with that of the parentwindow.

The following illustration shows a five-pointed star filled by using anapplication-defined brush. The illustration shows a zoomed image of the brush, as well asthe location to which it was mapped at the beginning of the paint operation.

Logical Brush Types

Logical brushes come in three varieties: solid, pattern, and hatched.

A solid brush consists of a color or pattern defined by some element of the Windowsuser interface (for example, you can paint a shape with the color and patternconventionally used by Windows to display disabled buttons).

A hatched brush consists of a combination of a color and of one of the six patternsdefined by Win32. The following table illustrates the appearance of these predefinedpatterns.

Brush style

IllustrationM

Backward diagonal

Cross-hatched

Diagonally cross-hatched

Forward diagonal

Horizontal

Vertical

A pattern brush consists of a bitmap that is used as the basis for a patternthat fills a shape. Where the area to be filled is larger than the bitmap, the bitmap istiled horizontally and vertically across the display. Pattern brushes enable you to createcustom brushes that consist of any pattern that you define.

The WFC Brush Object

The capabilities of Win32 brushes are encapsulated in the WFC Brush object, anobject which supports the creation of solid, pattern, and hatched brushes.

The Brush object represents these objects in various ways. For example, solidbrushes are represented as a group of public static final members, eachof which is itself a Brush object. Hatched brushes are represented as a group ofinteger constants, each of which represents a different brush style.

The following table lists the Brush object constants that represent solidbrushes.

Constant

Description

Brush.BLACK

Represents a solid black brush.

Brush.DARKGRAY

Represents a dark gray brush.

Brush.HALFTONE

Represents a halftone brush.

Brush.HOLLOW

Represents a transparent brush.

Brush.LIGHTGRAY

Represents a light gray brush.

Brush.NULL

Represents a null brush.

Brush.WHITE

Represents a white brush.

The following table lists the Brush object constants that represent hatchedbrushes.

Constant

Description

Brush.STYLE_BDIAGONAL

Represents a backward diagonal brush. Parallel lines run from the lower-left corner of the brush origin to the upper-right corner.

Brush.STYLE_DIAGACROSS

Represents a cross-hatched brush.

Brush.STYLE_FDIAGONAL

Represents a forward diagonal brush. Parallel lines run from the lower-right corner of the Brush origin to the upper-left corner.

Brush.STYLE_HORIZONTAL

Represents pattern consisting of evenly spaced horizontal lines.

Brush.STYLE_VERTICAL

Represents pattern consisting of  evenly spaced vertical lines.

Creating a Brush Object

How you create a Brush object depends on the type of brush needed. Because solidbrushes are Brush objects, you create a solid brush as follows:

Brush br = Brush.BLACK;

A pattern brush is represented by the Brush object as an integer constant and iscreated as follows:

Brush br = new Brush(new Color(0,0,0), Brush.STYLE_FDIAGONAL);

The following code fragment that demonstrates one way to create a brush based on abitmap:

Brush bmpBrush = new Brush(new Bitmap("c:\\myBitmap.bmp"));

This example assumes that the bitmap on which you want to base your brush pattern isstored in a file on disk. However, you can also use the Bitmap object’s createBitmapmethod to define bitmaps at run-time, and can use the bitmap you define as the basis forthe brush pattern.

Setting the Brush on the Graphics Object

Like the Pen and Font objects, the Brush object contains nocoloring or drawing capability. It expresses a subset of the capabilities of the GDI.Before a brush can be used to fill surfaces, it must be associated with a Graphicsobject using the setBrush method.

// Declare class-level Brush variable.

Brush br = new Brush(Brush.STYLE_FDIAGONAL);

public void Form1_paint(Object sender, PaintEvent e)

{

// Associate the brush with the Graphics object.

   e.graphics.setBrush(Color.BLACK, br);

}

After you associate a Brush object with the Graphics object, all polygonsthat you draw using that Graphics object instance are filled with the associatedbrush. You can call setBrush as often as you want to associate a new Brushwith the Graphics object.

Drawing Bitmaps

A bitmap is a drawable surface. This surface can be used to display pens, brushes, orimages, including Windows bitmaps, .gif, and .jpg  images.

The Bitmap object supports creating and loading bitmaps. After creating a Bitmapobject, you use the Graphics object's drawImage method to render a Bitmapobject to the display.

The following code fragment creates a new Bitmap object and then uses the Form class's createGraphics method to create the Graphics object for drawing the image.

Bitmap bmp = new Bitmap("c:\\MyImage.bmp");
Graphics g = this.createGraphics();

g.drawImage(bmp, new Point(10, 10));

Raster Operations

A raster operation applies a logical operation to the display of a GDI primitive, suchas a pen, brush, image, or shape to achieve a visual effect.  Raster operations thatyou can perform using the Graphics object are defined in the RasterOpobject. When you review the methods supported by the Graphics object, and you'llsee that for each basic operation, such as the drawing of lines or the display of images,there's a method that takes a RasterOp as a parameter.

In their simplest incarnations, the drawing methods the Graphics object supportsmerely write or copy pixels to some area of the display, overwriting what's currentlydisplayed.  Add raster operations to the equation, and this overwrite becomes morecomplex.

Suppose, for example, that you want to draw a black rectangle to an area currentlycovered by an image, but want to logically combine the black pixels with theircorresponding pixels in the target image and to write the result to the display. Raster operations make such combinations possible.

The variations on the logic the RasterOps object supports are too numerous to becovered thoroughly in this document.  The following statements, however, demonstratethe basic syntax of a call using a RasterOps object.  These statements set thebackground color of a form, and then draw a line that represents a color inversion of thebackground color.

private void Form1_paint(Object sender, PaintEvent e)

{

this.setBackColor(new Color(255, 255, 255);
e.graphics.drawLine(new Point(10, 10), new Point(100,               10),                  
RasterOp.TARGET.invert());

}

Drawing Shapes

The Graphics object supports the drawing of rectangles, rounded rectangles,arcs, Bezier splines, chords, and pies.

Lines

A line is a set of highlighted pixels on a display, identified by two points: astarting point and an ending point. In Windows, the pixel located at the starting point isalways included in the line, and the pixel located at the ending point is always excluded(these lines are sometimes called inclusive-exclusive).

An application can draw a single line by calling the Graphics object’s drawLinemethod. This method takes two Point parameters, which specify the start and end ofthe line.

private void Form1_paint(Object sender, Event e){

Rectangle rcClient = this.getClientRect();

// Draw lines that divide the screen area equally into four squares.

e.graphics.drawLine(new Point(rcClient.x, rcClient.height / 2),
   new Point(rcClient.width, rcClient.height / 2));

e.graphics.drawLine(new Point(rcClient.width / 2, rcClient.y),
   new Point(rcClient.width / 2, rcClient.height));

}

To draw a line from the current pen position to another point on the display,applications use the drawLineTo method, which takes a destination point as aparameter. For an example of how to use this method, see the section entitled Arcs.

Rectangles

Applications written for Microsoft Windows use rectangles to specify rectangular areason the screen or in a window. Rectangles are used to describe the client area of a window,areas of the screen that need repaints, and areas for displaying formatted text. Yourapplications can also use rectangles to fill, frame, or invert a portion of the clientarea with a given brush, and to retrieve the coordinates of a window or the window'sclient area.

The dimensions of rectangular regions are described in the WFC Rectangle object.This object consists of x, y, height and width integers thatdescribe the Rectangle's screen position and dimensions. In addition, you can use theobject's getRight and getBottom methods to retrieve the screen position ofits right and bottom sides.

Rectangle Operations

The Rectangle object provides a number of methods for working with rectangles.The object's equals method determines whether two Rectangle objects areidentical - that is, whether they have the same coordinates.

The inflateRect method increases or decreases the width or height of a Rectangle,or both. It can add or remove width from both ends of the Rectangle; it can add orremove height from both the top and bottom of the Rectangle.

The overloaded contains method enables you to determine whether the area described byone Rectangle exists within the area described by another, or to determine whether a givenpoint exists within a Rectangle.

The intersects and intersectsWith methods determine whether two Rectangle object’s intersect.

A Rectangle Example

The example in this section illustrates how to divide areas of an application’sclient area into sub-rectangles, and how to work within these regions.

When the application starts, it divides the main form’s client area into 16 by 16sub-regions, and displays every shade of a given color within those rectangular regions.To modify the number of rectangles displayed across and down the display, you use theDimensions menu item to display a dialog box in which you specify the new number ofRectangles you’d like to see displayed.

The method that divides the screen into Rectangle objects is given in thefollowing example. This method, getRects, takes three parameter: a Rectangle thatspecifies the area to be divided, and two integers, which identify the number of cells todraw across and down, respectively. The method returns an array of Rectangles that containthe appropriate coordinates.

private Rectangle[] getRects(Rectangle rcClient, int nDown, int nAcross){

int deltaX, deltaY; // The height and width of each cell.
int x, y;
int i;
Rectangle rgRects[] = new Rectangle[nDown * nAcross];

// Determine the height and width of each Rectangle.

deltaX = (rcClient.getRight() – rcClient.x) / nAcross;
deltaY = (rcClient.getBottom() – rcClient.y) / nDown;

// Create and initialize the Rectangle array.

for(y = rcClient.y, i = 0; y < rcClient.getBottom(); y += deltaY){
   for(x = rcClient.x; x < (rcClient.getRight() – nAcross) &&
       i < (nAcross * nDown); x += deltaX, i++){

   rgRects[i] = new Rectangle(x, y, deltaX, deltaY);
   }

}

// Return the initialized array.

return rgRects;

}

When the application start’s, its Form class constructor initializes twoclass-level integers, nAcross and nDown, to 16, and calls the getRectsmethod previously listed.

public Form1(){

initForm();
nAcross = 16;
nDown = 16;

// Initialize class-level array.

rgRects = getRects(this.getClientRect(), nAcross, nDown);

}

After the class constructor returns, the class’s paint event handler isautomatically called. This event handler loops through the class-level rgRectsarray, uses the Graphics object’s setBrush method to set a new color,and then calls the drawRect method to draw the array’s Rectangle.

private void Form1_paint(Object sender, PaintEvent e){

   for(int i = 0; i < rgRects.length; i++){
       e.graphics.setBrush(new Brush(newColor(0,0,i)));
       e.graphics.drawRect(rgRects[i]);
   }

}

Finally, the Form class’s resize handler simply re-initializes the arrayand forces a repaint of the form’s client area.

private void Form1_resize(Object sender, Event e){

   Rectangle rcClient = this.getClientRect();

   rgRects = getRects(rcClient, nDown, nAcross);
   this.invalidate();

}

Chords

A chord is a region bounded by the intersection of an ellipse and a linesegment, called a secant. The chord is outlined by using the current pen and filledby using the current brush. The part of the ellipse on one side of the secant is clipped.

To draw a chord, use the Graphics object's drawChord method, which hasthe following syntax:

drawChord(Rectangle p1, Point p2, point p3);

The drawChord method's Rectangle parameter designates the area into whichthe ellipse will be draw. The two Point parameters identify the points at which thetwo ends of the secant intersects the ellipse.

The following sample makes two calls to drawChord. The first call draws a chordin the lower-left corner of the display, and the second draws a chord in the upper rightcorner. Prior to each call to drawChord, a different brush is associated with the Graphicsobject to ensure that the two chords, which combine to form a circle, are painted blackand white, respectively.

private void Form1_paint(Object sender, PaintEvent e){

Rectangle rcClient = this.getClientRect();

// Associate a black brush with the object, and draw a chord.

e.graphics.setBrush(new Brush(new Color(0,0,0)));
e.graphics.drawChord(rcClient, new Point(rcClient.x, rcClient.y),
   new Point(rcClient.getRight(), rcClient.getBottom());

// Associate a white brush with the object, and draw a chord.

e.graphics.setBrush(new Brush(new Color(255,255,255)));
e.graphics.drawChord(rcClient, new Point(rcClient.getRight(),
   rcClient.getBottom()), new Point(rcClient.x, rcClient.y));

}

Arcs

An application can draw an ellipse or part of an ellipse by calling the drawArcmethod. This method draws a curve within the perimeter of an invisible rectangle called abounding rectangle. The size of the ellipse is specified by two invisible radialsextending from the center of the rectangle to the size of the rectangle. The followingillustration shows an arc (part of an ellipse) drawn using the drawArc method.

When calling the drawArc method, an application specifies the coordinates of thebounding rectangle and radials. The preceding illustration shows the rectangle and radialswith dashed lines while the actual arc was drawn using a solid line.

The following example draws an arc that fills the client area of a form, and then usesthe Graphics object’s drawLine method to draw a line from the top of the arcto its radius, then from its radius to the rightmost side of the ellipse.

void private Form1_paint(Object sender, Event e){

   Rectangle rcClient = this.getClientRect();

e.graphics.drawArc(rcClient, new Point(rcClient.width /2,rcClient.y),
   new Point(rcClient.width, rcClient.height / 2));
e.graphics.drawLine(new Point(rcClient.width / 2, rcClient.y),
   new Point(rcClient.width / 2, rcClient.height / 2));
e.graphics.drawLine(new Point(rcClient.width, rcClient.height / 2),
   new Point(rcClient.width / 2, rcClient.height / 2));

}

ArcAngles

An arc angle is similar to an arc. The primary practical difference between the two isthat when an application uses drawArc to draw an arc, it specifies the x andy locations of the arc’s radials.

In contrast, to draw an arc angle, the application uses the drawArcAngle method,and specifies the degrees of the angle; the method itself takes care of locating thecoordinates at which drawing starts and stops.

The drawArcAngle method has the following syntax:

public final void drawAngleArc(Point center, int radius, float startAngle, floatendAngle)

The Point parameter identifies the screen location at which to place the radius,specified in the radius parameter. The startAngle specifies the number, indegrees, where the angle starts, and the endAngle parameter specifies how manydegrees from the to draw, beginning at the startAngle.

The following example shows how to use this method. This method draws an arc angle,beginning at a start angle of 30, and extending 300 degrees from the start angle.

private void Form1_paint(Object sender, PaintEvent e){

Rectangle rcClient = this.getClientRect();
int x = rcClient.width / 2;
int y = rcClient.height / 2;
int radius = 100;
float startAngle = 30;
float endAngle = 300;

e.graphics.drawLineTo(new Point(x,y));
e.graphics.drawAngleArc(new Point(x,y), radius,startAngle, endAngle);
e.graphics.drawLineTo(new Point(x,y));

}

Code Listings

The following is a complete code listing for the Rectangle example referenced earlierin this chapter.

// Form1.java

import com.ms.wfc.app.*;
import com.ms.wfc.core.*;
import com.ms.wfc.ui.*;

/**
* This class can take a variable number of parameters on the command
* line. Program execution begins with the main() method. The class
* constructor is not invoked unless an object of type 'Form1'
* created in the main() method.
*/
public class Form1 extends Form
{

   private void Form1_resize(Object sender, Event e)
   {
       rgRects = getRects(this.getClientRect(), nDown,nAcross);
       this.invalidate();
      
   }

   public int nAcross, nDown;
   Rectangle rgRects[];
  
   private void Form1_paint(Object sender, PaintEvent e)
   {
      
       for(int i = 0; i < rgRects.length; i++){
          
           e.graphics.setBrush(newBrush(new Color(0,0,i)));
          e.graphics.drawRect(rgRects[i]);
       }

   }

  
   private void mnuDimensions_click(Object sender, Event e)
   {
       Dimensions d = new Dimensions();
       this.addOwnedForm(d);
       d.showDialog();
      
       rgRects = getRects(this.getClientRect(),nAcross, nDown);
       this.invalidate();
      
   }

   public Form1()
   {
       // Required for Visual J++ Form Designersupport
       initForm();
       nAcross = 16;
       nDown = 16;
      
       rgRects = getRects(this.getClientRect(),nAcross, nDown);

       // TODO: Add any constructor code afterinitForm call
   }
  
   private Rectangle[] getRects(Rectangle rcClient, int nDown,
       int nAcross){
  
       int deltaX, deltaY;
       int x,y;
       int i;
      
       Rectangle rgRects[] = new Rectangle[nDown *nAcross];
      
       deltaX = (rcClient.getRight() - rcClient.x) /nAcross;
       deltaY = (rcClient.getBottom() - rcClient.y) /nDown;
      
       // Initialize the array of cells.
      
       for(y = rcClient.y, i = 0; y <rcClient.getBottom(); y += deltaY){
          
           for(x = rcClient.x; x< (rcClient.getRight() - nAcross) &&
                              i < (nAcross * nDown); x += deltaX, i++){
                             
                  rgRects[i] = new Rectangle(x, y, deltaX, deltaY);
           }
       }
      
       return rgRects;
   }
                 

   /**
   * The main entry point for the application.
   *
   * @param args Array of parameters passed to the application
   * via the command line.
   */
   public static void main(String args[])
   {
       Application.run(new Form1());
   }


   /**
   * NOTE: The following code is required by the Visual J++ form
   * designer. It can be modified using the form editor. Do not
   * modify it using the code editor.
   */

   Container components = new Container();
   MainMenu mainMenu1 = new MainMenu();
   MenuItem menuItem1 = new MenuItem();
   MenuItem mnuDimensions = new MenuItem();

   private void initForm()
   {

      mnuDimensions.setText("&Dimensions..");
       mnuDimensions.addOnClick(newEventHandler(this.mnuDimensions_click));
       menuItem1.setMenuItems(new MenuItem[] {
           mnuDimensions});
       menuItem1.setText("&Rectangle");
       mainMenu1.setMenuItems(new MenuItem[] {
           menuItem1});
       /* @designTimeOnly mainMenu1.setLocation(newPoint(0, 0)); */
       this.setBackColor(Color.CONTROL);
       this.setLocation(new Point(0, 0));
       this.setSize(new Point(368, 320));
       this.setTabIndex(-1);
       this.setTabStop(true);
       this.setText("Rectangles Example");
       this.setAutoScaleBaseSize(13);
       this.setClientSize(new Point(360, 273));
       this.setMenu(mainMenu1);
       this.addOnResize(newEventHandler(this.Form1_resize));
       this.addOnPaint(newPaintEventHandler(this.Form1_paint));
   }
   // NOTE: End of form designer support code

   public static class ClassInfo extends Form.ClassInfo
   {
       // TODO: Add your property and event infos here
   }
}

The following is the code listing for Dimensions.java, the dialog through which theuser specifies the number of rectangles displayed down and across the application's mainform.

// Dimensions.java

import com.ms.wfc.app.*;
import com.ms.wfc.core.*;
import com.ms.wfc.ui.*;

/**
* This class can take a variable number of parameters on the command
* line. Program execution begins with the main() method. The class
* constructor is not invoked unless an object of type 'Dimensions'
* created in the main() method.
*/
public class Dimensions extends Form
{
   private void btnOK_click(Object sender, Event e)
   {
  
       Integer nAcross, nDown;
      
       if(txtAcross.getText().length() > 0 &txtAcross.getText().length() > 0){
  
           nAcross = newInteger(txtAcross.getText());
           nDown = newInteger(txtDown.getText());
      
      
      
           if(nAcross.intValue()> 0 && nAcross.intValue() < 16){
              if(nDown.intValue() > 0 && nDown.intValue() < 16){
      
              Form1 frm = (Form1)this.getOwner();
      
              frm.nAcross = nAcross.intValue();
              frm.nDown = nDown.intValue();
              }
           }
       }
      
       this.dispose();
   }

   public Dimensions()
   {
       // Required for Visual J++ Form Designersupport
       initForm();       

       // TODO: Add any constructor code afterinitForm call
   }

   /**
   * The main entry point for the application.
   *
   * @param args Array of parameters passed to the application
   * via the command line.
   */
   public static void main(String args[])
   {
       Application.run(new Dimensions());
   }


   /**
   * NOTE: The following code is required by the Visual J++ form
   * designer. It can be modified using the form editor. Do not
   * modify it using the code editor.
   */

   Container components = new Container();
   Label label1 = new Label();
   Label label2 = new Label();
   Edit txtAcross = new Edit();
   Edit txtDown = new Edit();
   Button btnOK = new Button();
   Button btnCancel = new Button();

   private void initForm()
   {

       this.setBackColor(Color.CONTROL);
       this.setLocation(new Point(0, 0));
       this.setSize(new Point(300, 134));
       this.setTabIndex(-1);
       this.setTabStop(true);
       this.setText("Dimensions");
       this.setAutoScaleBaseSize(13);
       this.setClientSize(new Point(292, 107));
       label1.setLocation(new Point(10, 10));
       label1.setSize(new Point(100, 20));
       label1.setText("Rectangles Across:");
       label1.setTabIndex(0);
       label2.setLocation(new Point(10, 40));
       label2.setSize(new Point(90, 20));
       label2.setText("Rectangles Down:");
       label2.setTabIndex(1);
       label2.setTextAlign(HorizontalAlignment.RIGHT);
       txtAcross.setBackColor(Color.WINDOW);
       txtAcross.setCursor(Cursor.IBEAM);
       txtAcross.setLocation(new Point(110, 10));
       txtAcross.setSize(new Point(90, 20));
       txtAcross.setTabIndex(2);
       txtAcross.setTabStop(true);
       txtAcross.setText("");
       txtDown.setBackColor(Color.WINDOW);
       txtDown.setCursor(Cursor.IBEAM);
       txtDown.setLocation(new Point(110, 40));
       txtDown.setSize(new Point(90, 20));
       txtDown.setTabIndex(3);
       txtDown.setTabStop(true);
       txtDown.setText("");
       btnOK.setLocation(new Point(70, 80));
       btnOK.setSize(new Point(60, 20));
       btnOK.setTabIndex(4);
       btnOK.setTabStop(true);
       btnOK.setText("OK");
       btnOK.addOnClick(newEventHandler(this.btnOK_click));
       btnCancel.setLocation(new Point(140, 80));
       btnCancel.setSize(new Point(70, 20));
       btnCancel.setTabIndex(6);
       btnCancel.setTabStop(true);
       btnCancel.setText("Cancel");
       this.setNewControls(new Control[] {
           btnCancel,
           btnOK,
           txtDown,
           txtAcross,
           label2,
           label1});
   }
   // NOTE: End of form designer support code

   public static class ClassInfo extends Form.ClassInfo
   {
       // TODO: Add your property and event infos here
   }
}

'my Programing' 카테고리의 다른 글

완성형 폰트 에디터~~!  (3) 2009.12.03
GRAPHICS INTERCHANGE FORMAT --> GIF  (2) 2007.05.01
Standard MIDI File (SMF) Format, WAVE File Format  (0) 2007.05.01
댓글