Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 56 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
56
Dung lượng
0,94 MB
Nội dung
211 Mutable: These images are created by requesting a block of memory, specifying the height and width of the desired image. The image is empty until drawn into. Here's how to allocate a mutable image: // Create mutable image and get graphics object for image Image tmpImg = Image.createImage(80, 20); Graphics g = tmpImg.getGraphics(); Look what we just uncovered. There's our second reference to a Graphics object, through a mutable image. Which also answers the question, how do you draw into a mutable image? Before moving on, let's go over the fundamental difference between the lifetime of a Graphics objects acquired inside paint() versus a Graphics object acquired through an Image. 1. Through paint() method The Graphics reference is valid only inside paint(). Once leaving (even if you save a reference to the variable), the object cannot be used to draw onto the Canvas. 2. Through an image The Graphics reference is valid as long as the Image and the variable that references the Graphics object are in scope. For example, depending on where the following declaration is made, image and g may be available for the lifetime of the MIDlet. Image image = Image.createImage(40, 40); Graphics g = image.getGraphics(); 24 bits are allocated for color support; 8 bits to each of the colors: red, green, and blue. If a device does not support all possible colors in the range, it will map color requests to the closest possible match available. This includes mapping a color request to an appropriate shade of gray for non-color devices. Table 9.9. Color Suppor t: javax.microedition.lcdui.Graphics Method Description void setColor(int RGB) Set color by com b ining each color component (Red, Green, Blue) into one integer value void setColor(int red, int green, int blue) Set color specifying each color component (Red, Green, Blue) separately int getColor() Get current color as one integer value int getBlueComponent() Get the blue component of the current color Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 212 int getGreenComponent() Get the green component of the current color int getRedComponent() Get the red component of the current color void setGrayScale(int value) Set the grayscale int getGrayScale() Get current grayscale Setting Colors When setting the color, we have two choices: combine the three color components into one integer value or specify each color as a separate integer. When combining colors, blue occupies the lower eight bits, followed by green, ending with red. For example, let's randomly select a value for each color: Decimal Hexadecimal Binary Red 0 0x0 0000 0000 Green 126 0x7E 0111 1110 Blue 255 0xFF 1111 1111 When combining each separate color into one integer, we need to shift a few bits around. Specifically, red needs to move up 16 bits, green up 8 bits, with blue occupying the lower 8 bits. // Assume 'g' is a valid Graphics object int red = 0, green = 126, blue = 255; g.setColor((red << 16) | (green << 8) | blue); The end result is an integer value with the binary representation: The second option is to specify the colors separately: g.setColor(red, green, blue); Determining Color Suppor You can check for color support on a mobile device through the method javax.microedition.lcdui.Display.isColor(). true is returned if the device supports color; otherwise false is returned. There is an additional method— javax.microedition.lcdui.Display.numColors() —that returns the number of colors (or shades of gray) available. Getting Colors Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 213 To get the current color configuration the options are the reverse of setting the colors: the current color selection can be returned as one integer value or a separate integer for each color. For separate color values use getRedComponent(), getGreenComponent() and getBlueComponent(). When requesting the color be returned as one integer value, you can get the value assigned to each color (red, green and blue) by masking off the appropriate bits. int colors, red, green, blue; colors = g.getColor(); // Return the highest 8 bits red = colors & 0xFF0000 // Return middle eight bits green = colors & 0xFF00; // Return lowest 8 bits blue = colors & 0xFF Using Grayscale setGrayScale(int) allows selection of a shade of gray in the range of 0 to 255. As with a color device, if the value is outside the supported range, an appropriate match will be selected. Background and Foreground Colors MIDP does not support the concept of separate background and foreground colors. This should be apparent by looking at the methods for setting colors— setColor(int) and setColor(int, int, int). No distinction is made between the background and foreground. Instead, fill operations are used to color the background. For example, to change the background to blue and draw a text string in white, we can follow these steps: // Assume ‘g’ is a valid Graphics object // Fill display with blue background g.setColor(0, 0, 255); g.fillRect(0, 0, getWidth(), getHeight()); // Set color to white and draw text g.setColor(255,255,255); g.drawString(“Testing”, 5, 5, Graphics.TOP | Graphics.LEFT); We’ll visit all the fill operations as we move through the remainder of this chapter. Stroke Style When drawing lines, arcs and rectangles we can choose between a solid or dashed stroke style. If you don’t specify a preference, the default is solid. Figure 9–11 shows a line drawn in each stroke style. Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 214 Figure 9-11. SOLID and DOTTED stroke styles Table 9.10. Stroke Methods: javax.microedition.lcdui.Graphics Method Description int getStrokeStyle() Get the current stroke style void setStrokeStyle(int style) Set the stroke style (available styles are shown in Table 9.11) Setting the preferred stroke is as easy as: g.setStrokeStyle(Graphics.DOTTED); or g.setStrokeStyle(Graphics.SOLID); Once the stroke style is set, every line, arc and rectangle drawn with the associated Graphics that will use that stroke style. There are a few important notes regarding the dotted stroke style: • A dotted line is drawn by skipping pixels in drawing path • Which pixels are skipped is determined by the implementation • End points (of lines and arcs) and corners (of rectangles) are not guaranteed to be drawn Table 9.11. Stroke Styles: javax.microedition.lcdui.Graphics Property Description SOLID Draw solid lines DOTTED Draw dotted lines Drawing Lines Let’s start with the most basic drawing operation, a line. Each line has a starting point, (x1 y1) and ending (x2 y2) point (see Table 9.12 ). Regardless of the stroke style, the thickness of a line is always one pixel wide. Back in Example 9.3 , doodle.java, we used this method to draw line segments as a mouse was moved about on a Canvas. The starting location of the line and the current location of the mouse were specified as the parameters to drawLine(). // Draw with black pen g.setColor(0, 0, 0); // Draw line g.drawLine(startx, starty, currentx, currenty); Table 9.12. Line Drawing: javax.microedition.lcdui.Graphics Method Description void drawLine(int x1, int y1, int x2, int y2) Draw line specifying starting and ending points Drawing Arcs Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 215 There are two methods to draw arcs: one to create an "outline" of an arc and the second to fill an arc (see Table 9.13 ). Table 9.13. Arc Methods: javax.microedition.lcdui.Graphics Property Description void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) Draw an arc inside a bounding box specified by x,y and width,height. void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) Fill an arc inside a bounding box specified by x,y and width,height. Drawing an arc begins by specifying the bounding box (i.e., the outside dimensions of an "imaginary" box that will contain the arc). The startAngle is the location to start the arc, where 0 is found at 3 o'clock. Positive values go counter-clockwise. Therefore, if you choose a startAngle of 90 the arc would begin at 12 o'clock. The arcAngle is how many degrees to rotate from the startAngle. A startAngle of 0 and arcAngle of 180 would begin at 3 o'clock and rotate counter-clockwise to 9 o'clock. A startAngle of 90 with an arcAngle of 180 would begin at 12 o'clock and rotate counter- clockwise to 6 o'clock. Example: Modifying startAngle and arcAngle Example 9.4 draws an arc inside a bounding box defined by 5,5 to 75, 75. The startAngle is 0 (3 o'clock) and the arcAngle is 225. Here is the request to create the arc: g.drawArc(5, 5, 75, 75, 0, 225); Figure 9–12 shows the resulting arc. Figure 9-12. Drawing an arc with startAngle 0 and arcAngle 225 Example 9.4 Arcs.java /* * Arcs.java * * Draw arc on a canvas * */ import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class Arcs extends MIDlet { private Display display; // The display private ArcsCanvas canvas; // Canvas public Arcs() { display = Display.getDisplay(this); canvas = new ArcsCanvas(this); } Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 216 protected void startApp() { display.setCurrent(canvas); } protected void pauseApp() { } protected void destroyApp(boolean unconditional) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed(); } } /* * Class ArcsCanvas * * Draw Arcs * */ class ArcsCanvas extends Canvas implements CommandListener { private Command cmExit; // Exit midlet private Arcs midlet; public ArcsCanvas(Arcs midlet) { this.midlet = midlet; // Create exit command & listen for events cmExit = new Command("Exit", Command.EXIT, 1); addCommand(cmExit); setCommandListener(this); } /* * Draw an arc * */ protected void paint(Graphics g) { // Start at 3 o'clock and rotate 225 g.drawArc(5, 5, 75, 75, 0, 225); // Start at 12 o'clock and rotate 225 // g.drawArc(5, 5, 75, 75, 90, 225); // Change the size of the bounding box // Start at 12 o'clock and rotate 225 // g.drawArc(25, 35, 30, 50, 90, 225); } public void commandAction(Command c, Displayable d) { if (c == cmExit) Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 217 midlet.exitMIDlet(); } } Inside paint() are three calls to drawArc(). The result of the first call is shown in Figure 9–12: g.drawArc(5, 5, 75, 75, 0, 225); Notice in Figure 9–13 (on the left) how the arc changes when the startAngle is modified. The arcAngle is still 225; however, the starting position is now 90 (12 o'clock): Figure 9-13. Leftmost arc is the same arc as Figure 9-12, with a startAngle of 90; Arc on the right has a modified bounding box. g.drawArc(5, 5, 75, 75, 90, 225); Finally, the arc on the right in Figure 9–13 is the result of a change to the bounding box: g.drawArc(25, 35, 30, 50, 90, 225); Filling of arcs follows exactly the same principal: specify a bounding box and start angle and rotation of the arc. Lets change the original arc (Figure 9–12 ) from: g.drawArc(5, 5, 75, 75, 0, 225); to a filled arc: g.fillArc(5, 5, 75, 75, 0, 225); The result is shown in Figure 9–14. Figure 9-14. Filled arc Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 218 Make a few changes of your own to get a feel for drawing arcs and filled arcs. Specifically, try specifying a negative arcAngle, an option we didn't experiment with in the earlier examples. Drawing Rectangles Rectangles can have either square or rounded corners and can be drawn as an outline or filled (see Table 9.14 ). Table 9.14. Rectangle Methods: javax.microedition.lcdui.Graphics Property Description void drawRect(int x, int y, int width, int height) Draw a rectangle void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) Draw a rounded rectangle void fillRect(int x, int y, int width, int height) Fill a rectangle void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) Fill a rounded rectangle The parameters for a non-rounded rectangle should be unmistakable. Specify the starting x and y location as well as the width and height. When creating a rectangle with rounded corners we also specify the horizontal diameter ( arcWidth) and the vertical diameter (arcHeight) of the arc drawn at each corner. Example: Four Rectangle Types Example 9.5 creates a rectangle for each of the four types. Example 9.5 Rectangles.java /* * Rectangles.java * * Draw Rectangle on a canvas * */ import javax.microedition.midlet.*; Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 219 import javax.microedition.lcdui.*; public class Rectangles extends MIDlet { private Display display; // The display private RectangleCanvas canvas; // Canvas public Rectangles() { display = Display.getDisplay(this); canvas = new RectangleCanvas(this); } protected void startApp() { display.setCurrent(canvas); } protected void pauseApp() { } protected void destroyApp(boolean unconditional) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed(); } } /* * Class RectangleCanvas * * Draw arcs * */ class RectangleCanvas extends Canvas implements CommandListener { private Command cmExit; // Exit midlet private Rectangles midlet; public RectangleCanvas(Rectangles midlet) { this.midlet = midlet; // Create exit command & listen for events cmExit = new Command("Exit", Command.EXIT, 1); addCommand(cmExit); setCommandListener(this); } /* * Draw an arc * */ protected void paint(Graphics g) { g.drawRect(1, 1, 25, 25); g.drawRoundRect(28, 28, 45, 45, 15, 45); Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com 220 // g.fillRect(1, 1, 25, 25); // g.fillRoundRect(28, 28, 45, 45, 15, 45); } public void commandAction(Command c, Displayable d) { if (c == cmExit) midlet.exitMIDlet(); } } Figure 9–15 shows the following two rectangles, the latter with rounded corners. Figure 9-15. Rectangles with and without rounded corners g.drawRect(1, 1, 25, 25); g.drawRoundRect(28, 28, 45, 45, 15, 45); To draw a filled rectangle, change the method call, leaving all the parameters unchanged. The results are shown in Figure 9–16 . Figure 9-16. Filled rectangles with and without rounded corners Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com [...]...Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com g.fillRect(1, 1, 25, 25) ; g.fillRoundRect(28, 28, 45, 45, 15, 45) ; Rounded Rectangles The horizontal and vertical diameter (arcWidth and arcHeight) specified when creating a rounded rectangle define... Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_MEDIUM); graphics.setFont(font); // Draw a filled (black) rectangle graphics.setColor(0, 0, 0); graphics.fillRoundRect(0,0, im.getWidth()-1, im.getHeight()-1, 20, 20); // Center text horizontally in the image Draw text in white graphics.setColor( 255 , 255 , 255 );... Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com image; otherwise, reset the translation point to zero, which will move the image back to the top of the display Once the coordinate system has been translated, we request the display be updated through a call to repaint() protected void paint(Graphics g) { if (im != null) { // Clear the background g.setColor( 255 , 255 , 255 ); g.fillRect(0,... how this affects the output on the display protected void paint(Graphics g) { g.setClip( 25, 25, 45, 45) ; g.drawImage(im, 0, 0, Graphics.TOP | Graphics.LEFT); } Figure 9–32 shows how only the region of the display defined by the clipping rectangle has been painted Figure 9-32 Clipping region defined as 25, 25, 45, 45 246 ... exit command & listen for events cmExit = new Command("Exit", Command.EXIT, 1); addCommand(cmExit); setCommandListener(this); try { // Create immutable image im = Image.createImage("/bolt.png"); } catch (java.io.IOException e) { System.err.println("Unable to locate or read png file"); } } protected void paint(Graphics g) { if (im != null) { // Clear the background g.setColor( 255 , 255 , 255 ); g.fillRect(0,... http://www.simpopdf.com // Specify a font face, style and size Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_ITALIC, Font.SIZE_MEDIUM); graphics.setFont(font); // Draw a filled (black) rectangle graphics.setColor(0, 0, 0); graphics.fillRoundRect(0,0, im.getWidth()-1, im.getHeight()-1, 20, 20); // Center text horizontally in the image Draw text in white graphics.setColor( 255 , 255 , 255 ); graphics.drawString(message,... more gradual the arc For example, when setting the horizontal diameter to 15 and the vertical diameter to 45, the arc in the vertical direction is more gradual than that in the horizontal direction See Figure 9–17 Figure 9-17 Determining the "sharpness" of corners on a rounded rectangle g.drawRoundRect(28, 28, 45, 45, 15, 45) Drawing Text Anytime we draw text we must take into consideration the font... commandAction(Command c, Displayable d) 2 35 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com { if (c == cmExit) midlet.exitMIDlet(); } } Inside the constructor for the Canvas an immutable image is read from a file resource // Create immutable image im = Image.createImage(“/image_bw.png”); The paint() method draws the image onto the Canvas (see Figure 9– 25) Figure 9- 25 Immutable image on Canvas... Fonts Font support within MIDP has been slimmed down significantly compared with J2SE The most glaring omission is the lack of a FontMetrics class Metrics define characteristics of a Font that 221 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com deal with measurements such as the height of a character or the size of the gap between one character and the next MIDP does provide various... Graphics.TOP); 233 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com } Mutable Image 1 Allocate the image Image im = Image.createImage(80, 20); 2 Create the image content (using arcs, rectangles, lines and text) // Get Graphics object to draw onto image Graphics graphics = im.getGraphics(); // Draw a filled rectangle graphics.fillRoundRect(0, 0, 50 , 50 , 20, 20); 3 Display the . g) { // Start at 3 o'clock and rotate 2 25 g.drawArc (5, 5, 75, 75, 0, 2 25) ; // Start at 12 o'clock and rotate 2 25 // g.drawArc (5, 5, 75, 75, 90, 2 25) ; // Change the size. 9–12 ) from: g.drawArc (5, 5, 75, 75, 0, 2 25) ; to a filled arc: g.fillArc (5, 5, 75, 75, 0, 2 25) ; The result is shown in Figure 9–14. Figure 9-14. Filled arc Simpo PDF Merge and Split Unregistered. background g.setColor(0, 0, 255 ); g.fillRect(0, 0, getWidth(), getHeight()); // Set color to white and draw text g.setColor( 255 , 255 , 255 ); g.drawString(“Testing”, 5, 5, Graphics.TOP | Graphics.LEFT);