intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

Java™ How to Program ( Deitel - Deitel) - Phần 11

Chia sẻ: Nguyen Kien | Ngày: | Loại File: PDF | Số trang:50

161
lượt xem
45
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Tham khảo tài liệu 'java™ how to program ( deitel - deitel) - phần 11', công nghệ thông tin, kỹ thuật lập trình phục vụ nhu cầu học tập, nghiên cứu và làm việc hiệu quả

Chủ đề:
Lưu

Nội dung Text: Java™ How to Program ( Deitel - Deitel) - Phần 11

  1. [Page 250 (continued)] 6.10. Case Study: A Game of Chance (Introducing Enumerations) A popular game of chance is a dice game known as "craps," which is played in casinos and back alleys throughout the world. The rules of the game are straightforward: You roll two dice. Each die has six faces, which contain one, two, three, four, five and six spots, respectively. After the dice have come to rest, the sum of the spots on the two upward faces is calculated. If the sum is 7 or 11 on the first throw, you win. If the sum is 2, 3 or 12 on the first throw (called "craps"), you lose (i.e., the "house" wins). If the sum is 4, 5, 6, 8, 9 or 10 on the first throw, that sum becomes your "point." To win, you must continue rolling the dice until you "make your point" (i.e., roll that same point value). You lose by rolling a 7 before making the point. The application in Fig. 6.9 and Fig. 6.10 simulates the game of craps, using methods to define the logic of the game. In the main method of class CrapsTest (Fig. 6.10), line 8 creates an object of class Craps (Fig. 6.9) and line 9 calls its play method to start the game. The play method (Fig. 6.9, lines 2165) calls the rollDice method (Fig. 6.9, lines 6881) as necessary to roll the two dice and compute their sum. Four sample outputs in Fig. 6.10 show winning on the first roll, losing on the first roll, winning on a subsequent roll and losing on a subsequent roll, respectively. Figure 6.9. Craps class simulates the dice game craps. (This item is displayed on pages 251 - 252 in the print version) 1 // Fig. 6.9: Craps.java 2 // Craps class simulates the dice game craps. 3 import java.util.Random; 4 5 public class Craps 6 { 7 // create random number generator for use in method rollDice 8 private Random randomNumbers = new Random(); 9 10 // enumeration with constants that represent the game status 11 private enum Status { CONTINUE, WON, LOST }; 12 13 // constants that represent common rolls of the dice 14 private final static int SNAKE_EYES = 2; 15 private final static int TREY = 3; 16 private final static int SEVEN = 7; 17 private final static int YO_LEVEN = 11; 18 private final static int BOX_CARS = 12;
  2. 19 20 // plays one game of craps 21 public void play() 22 { 23 int myPoint = 0; // point if no win or loss on first roll 24 Status gameStatus; // can contain CONTINUE, WON or LOST 25 26 int sumOfDice = rollDice(); // first roll of the dice 27 28 // determine game status and point based on first roll 29 switch ( sumOfDice ) 30 { 31 case SEVEN: // win with 7 on first roll 32 case YO_LEVEN: // win with 11 on first roll 33 gameStatus = Status.WON; 34 break; 35 case SNAKE_EYES: // lose with 2 on first roll 36 case TREY: // lose with 3 on first roll 37 case BOX_CARS: // lose with 12 on first roll 38 gameStatus = Status.LOST; 39 break; 40 default: // did not win or lose, so remember point 41 gameStatus = Status.CONTINUE; // game is not over 42 myPoint = sumOfDice; // remember the point 43 System.out.printf( "Point is %d\n", myPoint ); 44 break; // optional at end of switch 45 } // end switch 46 47 // while game is not complete 48 while ( gameStatus == Status.CONTINUE ) // not WON or LOST 49 { 50 sumOfDice = rollDice(); // roll dice again 51 52 // determine game status 53 if ( sumOfDice == myPoint ) // win by making point 54 gameStatus = Status.WON; 55 else 56 if ( sumOfDice == SEVEN ) // lose by rolling 7 before point 57 gameStatus = Status.LOST; 58 } // end while 59 60 // display won or lost message 61 if ( gameStatus == Status.WON ) 62 System.out.println( "Player wins" ); 63 else 64 System.out.println( "Player loses" ); 65 } // end method play 66 67 // roll dice, calculate sum and display results 68 public int rollDice() 69 { 70 // pick random die values
  3. 71 int die1 = 1 + randomNumbers.nextInt( 6 ); // first die roll 72 int die2 = 1 + randomNumbers.nextInt( 6 ); // second die roll 73 74 int sum = die1 + die2; // sum of die values 75 76 // display results of this roll 77 System.out.printf( "Player rolled %d + %d = %d\n", 78 die1, die2, sum ); 79 80 return sum; // return sum of dice 81 } // end method rollDice 82 } // end class Craps Figure 6.10. Application to test class Craps. (This item is displayed on page 253 in the print version) 1 // Fig. 6.10: CrapsTest.java 2 // Application to test class Craps. 3 4 public class CrapsTest 5 { 6 public static void main( String args[] ) 7 { 8 Craps game = new Craps(); 9 game.play(); // play one game of craps 10 } // end main 11 } // end class CrapsTest Player rolled 5 + 6 = 11 Player wins Player rolled 1 + 2 = 3 Player loses
  4. Player rolled 5 + 4 = 9 Point is 9 Player rolled 2 + 2 = 4 Player rolled 2 + 6 = 8 Player rolled 4 + 2 = 6 Player rolled 3 + 6 = 9 Player wins Player rolled 2 + 6 = 8 Point is 8 Player rolled 5 + 1 = 6 Player rolled 2 + 1 = 3 Player rolled 1 + 6 = 7 Player loses Let's discuss the declaration of class Craps in Fig. 6.9. In the rules of the game, the player must roll two dice on the first roll, and must do the same on all subsequent rolls. We declare method rollDice (lines 6881) to roll the dice and compute and print their sum. Method rollDice is declared once, but it is called from two places (lines 26 and 50) in method play, which contains the logic for one complete game of craps. Method rollDice takes no arguments, so it has an empty parameter list. Each time it is called, rollDice returns the sum of the dice, so the return type int is indicated in the method header (line 68). Although lines 71 and 72 look the same (except for the die names), they do not necessarily produce the same result. Each of these statements produces a random value in the range 16. Note that randomNumbers (used in lines 7172) is not declared in the method. Rather it is declared as a private instance variable of the class and initialized in line 8. This enables us to create one Random object that is reused in each call to rollDice . [Page 251] [Page 252] The game is reasonably involved. The player may win or lose on the first roll, or may win or lose on any subsequent roll. Method play (lines 2165) uses local variable myPoint (line 23) to store the "point" if the player does not win or lose on the first roll, local variable gameStatus (line 24) to keep track of the overall game status and local variable sumOfDice (line 26) to maintain the sum of the dice for the most recent roll. Note that myPoint is initialized to 0 to ensure that the application will compile.
  5. If you do not initialize myPoint, the compiler issues an error, because myPoint is not assigned a value in every branch of the switch statement, and thus the program could try to use myPoint before it is assigned a value. By contrast, gameStatus does not require initialization because it is assigned a value in every branch of the switch statementthus, it is guaranteed to be initialized before it is used. [Page 253] Note that local variable gameStatus is declared to be of a new type called Status, which we declared at line 11. Type Status is declared as a private member of class Craps, because Status will be used only in that class. Status is a programmer-declared type called an enumeration, which, in its simplest form, declares a set of constants represented by identifiers. An enumeration is a special kind of class that is introduced by the keyword enum (new to J2SE 5.0) and a type name (in this case, Status). As with any class, braces ({ and }) delimit the body of an enum declaration. Inside the braces is a comma-separated list of enumeration constants, each representing a unique value. The identifiers in an enum must be unique. (You will learn more about enumerations in Chapter 8.) [Page 254] Good Programming Practice 6.3 Use only uppercase letters in the names of constants. This makes the constants stand out in a program and reminds the programmer that enumeration constants are not variables. Variables of type Status can be assigned only one of the three constants declared in the enumeration or a compilation error will occur. When the game is won, the program sets local variable gameStatus to Status.WON (lines 33 and 54). When the game is lost, the program sets local variable gameStatus to Status.LOST (lines 38 and 57). Otherwise, the program sets local variable gameStatus to Status.CONTINUE (line 41) to indicate that the dice must be rolled again. Good Programming Practice 6.4 Using enumeration constants (like Status.WON, Status.LOST and Status.CONTINUE) rather than literal integer values (such as 0, 1 and 2) can make programs easier to read and maintain. Line 26 in method play calls rollDice , which picks two random values from 1 to 6, displays the value
  6. of the first die, the value of the second die and the sum of the dice, and returns the sum of the dice. Method play next enters the switch statement at lines 2945, which uses the sumOfDice value from line 26 to determine whether the game has been won or lost, or whether it should continue with another roll. The sums of the dice that would result in a win or loss on the first roll are declared as public final static int constants in lines 1418. These are used in the cases of the switch statement. The identifier names use casino parlance for these sums. Note that these constants, like enum constants, are declared with all capital letters by convention, to make them stand out in the program. Lines 3134 determine whether the player won on the first roll with SEVEN (7) or YO_LEVEN (11). Lines 3539 determine whether the player lost on the first roll with SNAKE_EYES (2), TREY (3), or BOX_CARS (12). After the first roll, if the game is not over, the default case (lines 4044) saves sumOfDice in myPoint (line 42) and displays the point (line 43). If we are still trying to "make our point" (i.e., the game is continuing from a prior roll), the loop in lines 4858 executes. Line 50 rolls the dice again. In line 53, if sumOfDice matches myPoint, line 54 sets gameStatus to Status.WON, then the loop terminates because the game is complete. In line 56, if sumOfDice is equal to SEVEN (7), line 57 sets gameStatus to Status.LOST, and the loop terminates because the game is complete. When the game completes, lines 6164 display a message indicating whether the player won or lost and the program terminates. Note the use of the various program-control mechanisms we have discussed. The Craps class uses three methodsmain, play (called from main) and rollDice (called twice from play)and the switch, while, if...else and nested if control statements. Note also the use of multiple case labels in the switch statement to execute the same statements for sums of SEVEN and YO_LEVEN (lines 3132) and for sums of SNAKE_EYES, TREY and BOX_CARS (lines 3537). You might be wondering why we declared the sums of the dice as public final static int constants rather than as enum constants. The answer lies in the fact that the program must compare int sumOfDice (line 26) to these constants to determine the outcome of each roll. Suppose we were to declare enum Sum containing constants (e.g., Sum.SNAKE_EYES) representing the five sums used in the game, then use these constants in place of the final variables in the cases of the switch statement (lines 2945). Doing so would prevent us from using sumOfDice as the switch statement's controlling expressionJava does not allow an int to be compared to an enumeration constant. To achieve the same functionality as the current program, we would have to use a variable currentSum of type Sum as the switch's controlling expression. Unfortunately, Java does not provide an easy way to convert an int value to a particular enum constant. To translate an int into an enum constant would require a separate switch statement. Clearly this would be cumbersome and not improve the readability of the program (thus defeating the purpose of using an enum), so we are better off using public final static int constants to represent the sums of the dice. [Page 255]
  7. [Page 255 (continued)] 6.11. Scope of Declarations You have seen declarations of various Java entities, such as classes, methods, variables and parameters. Declarations introduce names that can be used to refer to such Java entities. The scope of a declaration is the portion of the program that can refer to the declared entity by its name. Such an entity is said to be "in scope" for that portion of the program. This section introduces several important scope issues. (For more scope information, see the Java Language Specification, Section 6.3: Scope of a Declaration, at java.sun.com/docs/books/jls/second_edition/html/names.doc.html#103228.) The basic scope rules are as follows: 1. The scope of a parameter declaration is the body of the method in which the declaration appears. 2. The scope of a local-variable declaration is from the point at which the declaration appears to the end of that block. 3. The scope of a local-variable declaration that appears in the initialization section of a for statement's header is the body of the for statement and the other expressions in the header. 4. The scope of a method or field of a class is the entire body of the class. This enables non-static methods of a class to use the class's fields and other methods. Any block may contain variable declarations. If a local variable or parameter in a method has the same name as a field, the field is "hidden" until the block terminates executionthis is called shadowing. In Chapter 8, we discuss how to access shadowed fields. Common Programming Error 6.10 A compilation error occurs when a local variable is declared more than once in a method. Error-Prevention Tip 6.3
  8. Use different names for fields and local variables to help prevent subtle logic errors that occur when a method is called and a local variable of the method shadows a field of the same name in the class. The application in Fig. 6.11 and Fig. 6.12 demonstrates scoping issues with fields and local variables. When the application begins execution, class ScopeTest's main method (Fig. 6.12, lines 711) creates an object of class Scope (line 9) and calls the object's begin method (line 10) to produce the program's output (shown in Fig. 6.12). Figure 6.11. Scope class demonstrating scopes of a field and local variables. (This item is displayed on page 256 in the print version) 1 // Fig. 6.11: Scope.java 2 // Scope class demonstrates field and local variable scopes. 3 4 public class Scope 5 { 6 // field that is accessible to all methods of this class 7 private int x = 1; 8 9 // method begin creates and initializes local variable x 10 // and calls methods useLocalVariable and useField 11 public void begin() 12 { 13 int x = 5; // method's local variable x shadows field x 14 15 System.out.printf( "local x in method begin is %d\n", x ); 16 17 useLocalVariable(); // useLocalVariable has local x 18 useField(); // useField uses class Scope's field x 19 useLocalVariable(); // useLocalVariable reinitializes local x 20 useField(); // class Scope's field x retains its value 21 22 System.out.printf( "\nlocal x in method begin is %d\n", x ); 23 } // end method begin 24 25 // create and initialize local variable x during each call 26 public void useLocalVariable() 27 { 28 int x = 25; // initialized each time useLocalVariable is called 29 30 System.out.printf( 31 "\nlocal x on entering method useLocalVariable is %d\n", x );
  9. 32 ++x; // modifies this method's local variable x 33 System.out.printf( 34 "local x before exiting method useLocalVariable is %d\n", x ); 35 } // end method useLocalVariable 36 37 // modify class Scope's field x during each call 38 public void useField() 39 { 40 System.out.printf( 41 "\nfield x on entering method useField is %d\n", x ); 42 x *= 10; // modifies class Scope's field x 43 System.out.printf( 44 "field x before exiting method useField is %d\n", x ); 45 } // end method useField 46 } // end class Scope Figure 6.12. Application to test class Scope. (This item is displayed on page 257 in the print version) 1 // Fig. 6.12: ScopeTest.java 2 // Application to test class Scope. 3 4 public class ScopeTest 5 { 6 // application starting point 7 public static void main( String args[] ) 8 { 9 Scope testScope = new Scope(); 10 testScope.begin(); 11 } // end main 12 } // end class ScopeTest
  10. local x in method begin is 5 local x on entering method useLocalVariable is 25 local x before exiting method useLocalVariable is 26 field x on entering method useField is 1 field x before exiting method useField is 10 local x on entering method useLocalVariable is 25 local x before exiting method useLocalVariable is 26 field x on entering method useField is 10 field x before exiting method useField is 100 local x in method begin is 5 [Page 256] In class Scope, line 7 declares and initializes the field x to 1. This field is shadowed (hidden) in any block (or method) that declares a local variable named x. Method begin (lines 1123) declares a local variable x (line 13) and initializes it to 5. This local variable's value is output to show that the field x (whose value is 1) is shadowed in method begin. The program declares two other methods useLocalVariable (lines 2635) and useField (lines 3845)that each take no arguments and do not return results. Method begin calls each method twice (lines 1720). Method useLocalVariable declares local variable x (line 28). When useLocalVariable is first called (line 17), it creates local variable x and initializes it to 25 (line 28), outputs the value of x (lines 3031), increments x (line 32) and outputs the value of x again (lines 3334). When uselLocalVariable is called a second time (line 19), it re-creates local variable x and re-initializes it to 25, so the output of each useLocalVariable call is identical. [Page 257] Method useField does not declare any local variables. Therefore, when it refers to x, field x (line 7) of the class is used. When method useField is first called (line 18), it outputs the value ( 1) of field x (lines 4041), multiplies the field x by 10 (line 42) and outputs the value (10) of field x again (lines 4344) before returning. The next time method useField is called (line 20), the field has its modified value, 10, so the method outputs 10, then 100 . Finally, in method begin, the program outputs the value of local variable x again (line 22) to show that none of the method calls modified start's local variable x, because the methods all referred to variables named x in other scopes.
  11. [Page 257 (continued)] 6.12. Method Overloading Methods of the same name can be declared in the same class, as long as they have different sets of parameters (determined by the number, types and order of the parameters)this is called method overloading. When an overloaded method is called, the Java compiler selects the appropriate method by examining the number, types and order of the arguments in the call. Method overloading is commonly used to create several methods with the same name that perform the same or similar tasks, but on different types or different numbers of arguments. For example, Math methods abs , min and max (summarized in Section 6.3) are overloaded with four versions each: [Page 258] 1. One with two double parameters. 2. One with two float parameters. 3. One with two int parameters. 4. One with two long parameters. Our next example demonstrates declaring and invoking overloaded methods. You will see examples of overloaded constructors in Chapter 8. Declaring Overloaded Methods In our class MethodOverload (Fig. 6.13), we include two overloaded versions of a method called squareone that calculates the square of an int (and returns an int ) and one that calculates the square of a double (and returns a double). Although these methods have the same name and similar parameter lists and bodies, you can think of them simply as different methods. It may help to think of the method names as "square of int " and "square of double," respectively. When the application begins execution, class MethodOverloadTest 's main method (Fig. 6.14, lines 610) creates an object of class MethodOverload (line 8) and calls the object's method testOverloadedMethods (line 9) to produce the program's output (Fig. 6.14). Figure 6.13. Overloaded method declarations. (This item is displayed on pages 258 - 259 in the print version)
  12. 1 // Fig. 6.13: MethodOverload.java 2 // Overloaded method declarations. 3 4 public class MethodOverload 5 { 6 // test overloaded square methods 7 public void testOverloadedMethods() 8 { 9 System.out.printf( "Square of integer 7 is %d\n", square( 7 ) ); 10 System.out.printf( "Square of double 7.5 is %f\n", square( 7.5 ) ); 11 } // end method testOverloadedMethods 12 13 // square method with int argument 14 public int square( int intValue ) 15 { 16 System.out.printf( "\nCalled square with int argument: %d\n", 17 intValue ); 18 return intValue * intValue; 19 } // end method square with int argument 20 21 // square method with double argument 22 public double square( double doubleValue ) 23 { 24 System.out.printf( "\nCalled square with double argument: %f\n", 25 doubleValue ); 26 return doubleValue * doubleValue; 27 } // end method square with double argument 28 } // end class MethodOverload Figure 6.14. Overloaded method declarations. (This item is displayed on page 259 in the print version)
  13. 1 // Fig. 6.14: MethodOverloadTest.java 2 // Application to test class MethodOverload. 3 4 public class MethodOverloadTest 5 { 6 public static void main( String args[] ) 7 { 8 MethodOverload methodOverload = new MethodOverload(); 9 methodOverload.testOverloadedMethods(); 10 } // end main 11 } // end class MethodOverloadTest Called square with int argument: 7 Square of integer 7 is 49 Called square with double argument: 7.500000 Square of double 7.5 is 56.250000 [Page 259] In Fig. 6.13, line 9 invokes method square with the argument 7. Literal integer values are treated as type int , so the method call on line 9 invokes the version of square at lines 1419 that specifies an int parameter. Similarly, line 10 invokes method square with the argument 7.5 . Literal floating-point values are treated as type double, so the method call on line 10 invokes the version of square at lines 2227 that specifies a double parameter. Each method first outputs a line of text to prove that the proper method was called in each case. In line 10, note that the argument value and return value are displayed with the format specifier %f and that we did not specify a precision in either case. By default, floating-point values are displayed with six digits of precision if the precision is not specified in the format specifier. Distinguishing Between Overloaded Methods The compiler distinguishes overloaded methods by their signaturea combination of the method's name and the number, types and order of its parameters. If the compiler looked only at method names during compilation, the code in Fig. 6.13 would be ambiguousthe compiler would not know how to distinguish between the two square methods (lines 1419 and 2227). Internally, the compiler uses longer method names that include the original method name, the types of each parameter and the exact order of the parameters to determine whether the methods in a class are unique in that class.
  14. [Page 260] For example, in Fig. 6.13, the compiler might use the logical name "square of int " for the square method that specifies an int parameter and "square of double" for the square method that specifies a double parameter (the actual names the compiler uses are messier). If method1's declaration begins as void method1( int a, float b ) then the compiler might use the logical name "method1 of int and float." If the parameters are specified as void method1( float a, int b ) then the compiler might use the logical name "method1 of float and int ." Note that the order of the parameter types is importantthe compiler considers the preceding two method1 headers to be distinct. Return Types of Overloaded Methods In discussing the logical names of methods used by the compiler, we did not mention the return types of the methods. This is because method calls cannot be distinguished by return type. The program in Fig. 6.15 illustrates the compiler errors generated when two methods have the same signature and different return types. Overloaded methods can have different return types if the methods have different parameter lists. Also, overloaded methods need not have the same number of parameters. Figure 6.15. Overloaded method declarations with identical signatures cause compilation errors, even if the return types are different.
  15. 1 // Fig. 6.15: MethodOverloadError.java 2 // Overloaded methods with identical signatures 3 // cause compilation errors, even if return types are different. 4 5 public class MethodOverloadError 6 { 7 // declaration of method square with int argument 8 public int square( int x ) 9 { 10 return x * x; 11 } 12 13 // second declaration of method square with int argument 14 // causes compilation error even though return types are different 15 public double square( int y ) 16 { 17 return y * y; 18 } 19 } // end class MethodOverloadError MethodOverloadError.java:15: square(int) is already defined in MethodOverloadError public double square( int y ) ^ 1 error [Page 261] Common Programming Error 6.11 Declaring overloaded methods with identical parameter lists is a compilation error regardless of whether the return types are different.
  16. [Page 261 (continued)] 6.13. (Optional) GUI and Graphics Case Study: Colors and Filled Shapes Although you can create many interesting designs with just lines and basic shapes, class Graphics provides many more capabilities. The next two features we introduce are colors and filled shapes. Adding color brings another dimension to the drawings a user sees on the computer screen. Filled shapes fill entire regions with solid colors, rather than just drawing outlines. Colors displayed on computer screens are defined by their red, green, and blue components. These components, called RGB values, have integer values from 0 to 255. The higher the value of a particular component, the brighter the particular shade will be in the final color. Java uses class Color in package java.awt to represent colors using their RGB values. For convenience, the Color object contains 13 predefined static Color objectsColor.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA , Color.ORANGE, Color.PINK, Color.RED, Color.WHITE and Color.YELLOW. Class Color also contains a constructor of the form: public Color( int r, int g, int b ) so you can create custom colors by specifying values for the individual red, green and blue components of a color. Filled rectangles and filled ovals are drawn using Graphics methods fillRect and fillOval, respectively. These two methods have the same parameters as their unfilled counterparts drawRect and drawOval ; the first two parameters are the coordinates for the upper-left corner of the shape, while the next two parameters determine its width and height. The example in Fig. 6.16 and Fig. 6.17 demonstrates colors and filled shapes by drawing and displaying a yellow smiley face on the screen. Figure 6.16. Drawing a smiley face using colors and filled shapes. (This item is displayed on page 262 in the print version)
  17. 1 // Fig. 6.16: DrawSmiley.java 2 // Demonstrates filled shapes. 3 import java.awt.Color; 4 import java.awt.Graphics; 5 import javax.swing.JPanel; 6 7 public class DrawSmiley extends JPanel 8 { 9 public void paintComponent( Graphics g ) 10 { 11 super.paintComponent( g ); 12 13 // draw the face 14 g.setColor( Color.YELLOW ); 15 g.fillOval( 10, 10, 200, 200 ); 16 17 // draw the eyes 18 g.setColor( Color.BLACK ); 19 g.fillOval( 55, 65, 30, 30 ); 20 g.fillOval( 135, 65, 30, 30 ); 21 22 // draw the mouth 23 g.fillOval( 50, 110, 120, 60 ); 24 25 // "touch up" the mouth into a smile 26 g.setColor( Color.YELLOW ); 27 g.fillRect( 50, 110, 120, 30 ); 28 g.fillOval( 50, 120, 120, 40 ); 29 } // end method paintComponent 30 } // end class DrawSmiley Figure 6.17. Creating JFrame to display a smiley face. (This item is displayed on pages 262 - 263 in the print version)
  18. 1 // Fig. 6.17: DrawSmileyTest.java 2 // Test application that displays a smiley face. 3 import javax.swing.JFrame; 4 5 public class DrawSmileyTest 6 { 7 public static void main( String args[] ) 8 { 9 DrawSmiley panel = new DrawSmiley(); 10 JFrame application = new JFrame(); 11 12 application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 13 application.add( panel ); 14 application.setSize( 230, 250 ); 15 application.setVisible( true ); 16 } // end main 17 } // end class DrawSmileyTest The import statements in lines 35 of Fig. 6.16 import Color, Graphics and JPanel. Class DrawSmiley uses class Color to specify drawing colors and class Graphics to draw. Class JPanel again provides the area in which we draw. Line 14 in method paintComponent uses Graphics method setColor to set the current drawing color to Color.YELLOW. Method setColor requires one argument, the Color to set as the drawing color. In this case, we use the predefined object Color.YELLOW. Line 15 draws a circle with diameter 200 to represent the facewhen the width and height arguments are identical, method fillOval draws a circle. Next, line 18 sets the color to Color.Black, and lines 1920 draw the eyes. Line 23 draws the mouth as an oval, but this is not quite what we want. To create a happy face, we will "touch up" the mouth. Line 26 sets the color to Color.YELLOW, so any shapes we draw will blend in with the face. Line 27 draws a rectangle that is half the mouth's height. This "erases" the top half of the mouth, leaving just the bottom half. To create a better smile, line 28 draws another oval to slightly cover the upper portion of the mouth. Class DrawSmileyTest (Fig. 6.17) creates and displays a JFrame containing the drawing, resulting in the system calling method paintComponent to draw the smiley face. [Page 263]
  19. GUI and Graphics Case Study Exercises 6.1 Using method fillOval , draw a bull's-eye that alternates between two random colors, as in Fig. 6.18. Use the constructor Color( int r, int g, int b ) with random arguments to generate random colors. Figure 6.18. A bull's-eye with two alternating, random colors. 6.2 Create a program that draws 10 random filled shapes in random colors and positions (Fig. 6.19). Method paintComponent should contain a loop that iterates 10 times. In each iteration, the loop should determine whether to draw a filled rectangle or an oval, create a random color and choose coordinates and dimensions at random. The coordinates should be chosen based on the panel's width and height. Lengths of sides should be limited to half the width or height of the window. What happens each time paintComponent is called (i.e., the window is resized, uncovered, etc.)? We will resolve this issue in Chapter 8. Figure 6.19. Randomly generated shapes. (This item is displayed on page 264 in the print version)
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
2=>2