CS351 - Design of Large Programs - Professor Ackley

Tuesday and Thursday: 11:00am - 12:15pm (Centennial B146) Labs: Monday (001) 1:00pm - 1:50pm and Thursday (005) 12:30pm - 1:20pm (Centennial B146)

Lab #9: Bouncing Red Ball Animation

Goals

  • Get more familiar with GUIs
  • repaint() a JPanel object instead of just producing a static image
  • Learn about javax.swing.Timer and java.awt.event.ActionListener/java.awt.event.ActionEvent

Needs


Background

Last lab we did a refresher on javax.swing.* and basic GUIs for your project. I have heard from multiple students that they would like to do another lab with more GUI work since it's been awhile. One of the main issues with the last lab was that it just produced a single static image and never called javax.swing.JPanel.repaint(). To get you thinking about how to update a JPanel by repainting, this lab creates a bouncing red ball animation that is created by showing a filled in red ball, changing its position by a single pixel, and then repainting the ball in its new position.


//TODO

You need to create a com.putable.labs.lab9.AnimationPanel class which extends javax.swing.JPanel and implements java.awt.event.ActionListener. This AnimationPanel class will be added to the created javax.swing.JFrame that you see in the main() method that is given to you (NOTE: it's almost exactly the same as Lab 7's main()). Like before, this main() method should live in the com.putable.labs.lab9.AnimationPanel class.

Like before, the

protected void paintComponent(Graphics g)

method must be overridden so it draws our own custom content onto it.

The only method that we need to implement from the java.awt.event.ActionListener is

public void actionPerformed(ActionEvent arg0)

It's an abstract method, so it needs to be overridden. This method is called by any object that this (AnimationPanel) is listening to. In other words, since our AnimationPanel implements ActionListener, the AnimationPanel can "listen" to an object and have its actionPerformed() method called when an ActionEvent occurs.

This is where the javax.swing.Timer comes in. It is just like the java.util.Timer, except it is made specifically for GUIs since it has access to a "listener" of some sort in which it will call the listener's actionPerformed() method when it needs to (i.e. after every x number of milliseconds as described below...)

The javax.swing.Timer has a constructor that takes an int delay and an ActionListener listener as parameters. Check out the Javadoc for the specifics on what these two mean. In short, the delay is the milliseconds in which it will space subsequent calls to the listener's actionPerformed() method and the listener is exactly that, the listener. In our case, the listener will be this, the AnimationPanel.

Create an animation of a red ball bouncing in a gravity-less room (i.e. no velocity is lost from the transfer of force when it strikes a wall) forever, or until the animation is stopped. A few rules that you must follow:

  • The ball must be filled in red
  • The ball's WIDTH and HEIGHT are final ints with value 50, each
  • Normally animations have concurrency issues and you need to use multiple threads to avoid the concurrency issues. HOWEVER. For this lab, you do not need to do this. Running everything on the EDT (event-dispatching thread) is perfectly fine since no other computation is being done concurrently with us moving the ball. Don't do any special threading.
  • On each timestep (repaint()), the ball can only move a maximum of 1 pixel in each direction. This doesn't mean you MUST move 1 pixel in both directions, but you cannot move more than 1 pixel in any direction. In other words, you will always be moving in the y direction for every time step, but not necessarily in the x direction as often.
  • The delay parameter of the timer must be 1 millisecond
  • Choose how often to move in the x direction so that it looks as close to my example as possible. My animation hits the top/bottom walls ~5 times as it moves across the window.
  • Don't change the size of the AnimationWindow created in the main() method. It should be 500px x 500px.
  • Javadoc everything that must be Javadoc'd. I'll start taking off points now. Same with formatting.


An “executable JAR” is nothing but a JAR in which the entry point of execution is defined.
To create an executable JAR from within Eclipse:

  1. Right click on the com.putable.labs.lab9 package -> Export...
  2. Under the "Java" folder, select "JAR file" (even though "Runnable JAR file" looks tempting...)
  3. Check the "Export generated class files and resources" and "Export Java source files and resources" boxes like normal
  4. Select the export destination
  5. Press "Next"
  6. Press "Next" again
  7. At the very bottom of this final window, use the "Browse..." button to navigate to your com.putable.labs.Lab9.AnimationPanel class and select it. This is what tells the MANIFEST.MF file which main() method to run, and essentially makes it a Runnable or "executable" JAR
  8. Test it by running on the command line: $ java -jar AnimationPanel.jar


Turn in a runnable AnimationPanel.jar file containing a single com.putable.labs.lab9.AnimationPanel class. The main() method should live in this class. Make sure to turn in the java source files otherwise you will get a 0.

The AnimationPanel.jar should be turned in using the online interface by 11:59:59 PM of your lab day.