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
andjava.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
andHEIGHT
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:
- Right click on the
com.putable.labs.lab9
package ->Export...
- Under the "Java" folder, select "JAR file" (even though "Runnable JAR file" looks tempting...)
- Check the "Export generated class files and resources" and "Export Java source files and resources" boxes like normal
- Select the export destination
- Press "Next"
- Press "Next" again
- 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 whichmain()
method to run, and essentially makes it a Runnable or "executable" JAR - 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.