CSC 120   --   Lab 8

  1. Changing the RoundHead lab (Lab 6) to use an array of objects.

    1. Launch Netbeans and create a Java Application project named Lab8 that is located in your H:\CSC120\Java folder.

      1. If your Lab6 was fully implemented having the RoundHeads move horizontally, then open your your Lab6 project in NetBeans, copy all of the files from the src folder, and paste them into the src folder of your new Lab8 project.

      2. If your Lab6 project is not working or you didn't completely implement at least the move horizontally stuff, then right-click on the following file and save it:
        Lab8StarterFiles.zip
        Unzip and Extract All of the files, and copy ALL FOUR of the files you unzipped into the src folder of your project.

      The starting point for Lab8 is a working version of the Lab6 code with the RoundHead objects.  Run the new project to make sure that things are working before proceeding.

    2. Edit the MUPanel.java file, and inspect the code to find all declarations, instantiations and uses of the RoundHead objects "firstOne", "secondOne", etc.

      Remove the declarations of separate, individual RoundHead objects, and in their place, declare an array of RoundHeads called rhArray.
          private RoundHead[] rhArray;
      
      In the MUPanel constructor method, replace the instantiations of the separate RoundHead objects, and instead instantiate rhArray so that it contains 19 elements. Then, write a loop that will be repeated once for each element in the array.
          rhArray = new RoundHead[???];
      
          for (Integer index = 0; index < rhArray.length; index++) {
      
              rhArray[index] = new RoundHead( ?, ?, ?, ?, ?, ?, ?, ? );
      	
          } // end of for loop
      
      The body of this loop should instantiate one member of the rhArray array, using these parameter values:

      • the RoundHead should be HAPPY.  This means use true as the boolean parameter value in the constructor call.
      • the RoundHead's hat should be RED.
      • over should be a formula that computes 30 times the loop control variable.
      • down should be should be a formula that computes 20 times the loop control variable.
      • the verticalStepSize should be 15.
      • the horizontalStepSize should be 10.
      • the size should be 25
      • the nickName should be "Sammy"

    3. Don't forget to modify the methods in the MUPanel class that ask RoundHeads to move, change their mood, and draw themselves. In each of these methods in the MUPanel class, add a for loop to call the appropriate method for each RoundHead object in the rhArray array. Run this program and observe the results.  The output should show 19 roundheads in a diagonal line, and they should move, change moods and bounce off walls correctly.

    4. What if we don't want EVERY RoundHead to be Happy with a red hat?  We can choose different values for each RoundHead in the array when it is constructed, as follows:  inside the loop in the MUPanel constructor method where we instantiate new RoundHead objects, as the FIRST line in the loop body, declare a Boolean variable called isHappy.  If the loop control variable is an EVEN NUMBER, store the value true in isHappy; else, store false in isHappy.  Then replace the true in the constructor call with isHappy.  The constructor call must be the LAST statement inside the for loop body.  Recompile and run the program.  Did it work?

    5. Change the program so that the first and last RoundHeads have a GREEN hat.  Run the program to verify that the first and last elements in the array have different colored hats.

    6. Change the program so that if the loop control variable is less than 12, the RoundHeads in the index position in the array is instantiated with a size of 20, and the ones in positions that are not less than 12 are initially 30 pixels in size.  Run the program to verify that your changes were made correctly.

  2. Experiments with an array of Star objects.

    1. It is now nighttime in RoundHead Land, so let's make some changes to the program that will use a second array of objects.

    2. Copy the Star class into the src folder of your project.

      In your browser right click on:

      and choose Save Target As... and save the file in the src folder of your project. 

    3. Declare an array of Star objects at the top of the MUPanel class in the MUPanel.java file.

    4. Instantiate the array of Star objects in the constructor method of the MUPanel class so that the array contains 100 elements.

    5. In the constructor method of the MUPanel.java file, write a loop that will be executed once for each of the elements in the array of Star objects.  The body of the loop should:
      • declare two Integer variables called x and y
      • set x to a random integer in the range from 0 to 590
      • set y to a random integer in the range from 0 to 390
      • instantiate one element of the array, using x and y as the two parameters that are passed into the Star constructor method.

      Hint:  here is an example of code that sets the Integer variable randNum to a random integer in the range from 0 to upper:
          Random randGenerator = new Random();
      
          randNum = randGenerator.nextInt(upper);
      

      Put the first of these two lines above  the for loop, and then you can put lines similar to the second one  inside the for loop to put random numbers into x and y. (Note; a light bulb will appear beside the first line; just click on it and then select the Add import for java.util.Random item from the menu that pops up.

    6. In the paintComponent method of the MUPanel.java file, write code that uses a loop to call the draw method of each Star object in the array.  Place the loop that draws the stars BEFORE you draw the RoundHeads in the paintComponent method.

    7. If you run the program now, you won't see any stars, because they are white, and they are being drawn on a white background.  Change the program so that the background of the output window is Color.BLACK, and run the program.

  3. Make a .zip file from your Lab8 folder on your H: drive, and turn in your Lab8 project in the Dropbox in D2L for grading.

  4. The following instructions are optional for Lab 8, but they are very fun -- Try these experiments to add animation to a Java graphics program:

    1. Declare a new RoundHead object named "Fred" in MUPanel.java, and instantiate Fred so that he is happy with a CYAN hat, is 60 pixels in size, moves 25 pixels horizontally and vertically, and is located at the start of the program in the bottom-left corner of the screen somewhere.  Be sure to draw Fred in the paintComponent method.
    2. Add two new methods to MUPanel.java, as follows.  The first method is named "moveFred", and it is a void method that accepts no parameters.  In the moveFred method, call the moveVertically method and also the moveHorizontally method for the fred object.  The second method is named "changeFredsMood", and it also is a void method that accepts no parameters.  The changeFredsMood method should call the changeMood method for the fred object.

    3. Switch to MUFrame.java in the editor, and change to "Design" mode.  Add two new buttons to the interface, one labeled "Move Fred" and the other named "Change Fred's Mood".  The actionPerformed methods for these two buttons should call the appropriate methods of the muPanel object that you wrote in the previous instruction, and then ask muPanel to repaint().  Test the program now, and the new buttons should cause Fred to move or change mood while the other RoundHeads remain stationary.

    4. Now let's modify MUPanel so that the RoundHeads in the array move on the screen even if we aren't clicking the Move Roundheads button.  To do this, copy the following code and paste it into MUPanel.java right above the comment that says, "Don't change anything below here":

          private volatile Thread animator;
          private Integer animationDelay = 200;
       
          public void start() {
              if (animator == null) {
                  animator = new Thread(this);
                  animator.start();
              } // end if
          } // end of start()
      
          public void stop() {
              animator = null;
          } // end of stop()
        
          public void run() {
              Thread thisThread = Thread.currentThread();
              while (animator == thisThread) {
                  moveObjects();
                  repaint();
      			
                  try { Thread.sleep(animationDelay); }
                  catch (InterruptedException e) { }
              } // end while
          } // end of run()
      	
      
      Next, modify the class heading for the MUPanel class so that it looks like this:
      public class MUPanel extends JPanel implements Runnable {
      
      
      Then, switch to MUFrame and add two more buttons to the interface, one named "Start Animation" and the other named "Stop Animation".  When the Start Animation button is clicked, you should call muPanel.start(); when the Stop Animation button is clicked, you should call muPanel.stop().  Run the program, and try out the new buttons.  Can you move Fred around the screen and avoid the marching RoundHeads?
    5. If you would want the animation to start as soon as the program starts, there is a simple way to do that.  In MUFrame.java, scroll to the end of the constructor method, and then right before the closing brace for the method, call the muPanel.start() method.  The constructor is executed only once, when the program starts, and so the animation will begin right away instead of waiting for the user to click the Start Animation button.  You should be able to stop and start the animation with the buttons as before.

    6. The variable named animationDelay specifies the delay that will be used between repaintings, and is a number of milliseconds (thousandths of a second).  You can make the animation effects happen faster by using a smaller number for the animation delay, or slow it down with a bigger number for the delay.  Try changing the value of animationDelay in MUPanel.java, using 500 (which is a ½ second delay), then try 100 (a tenth-of-a-second delay), and finally try 25 — that's really fast!  Change the delay a final time to a value that you like.

    7. Add randomness to the instantiation of the RoundHead objects in your program so that the horizontal and vertical movement factors used for each RoundHead in the array is a random integer in the range from -30 to 30.  Run the program and watch the RoundHeads break out of their initial positions unpredictably.

    8. Write a ShootingStar class definition based on the Star class that draws something that looks like a shooting star, and then declare, instantiate and draw an array of 10 shooting stars.  The shooting stars should be randomly placed in the output window, in a manner that is similar to the way the Stars were placed.
    9. You could add a button or two to the interface to increase or decrease the animationDelay value to speed up or slow down the animation as it is running.  To do that, you would need a setAnimationDelay method in MUPanel that could be called from the actionPerformed methods in MUFrame.  Or maybe you would like to try a Spinner or a Slider for changing the animationDelay....