HOMEWORK 5: Animation in the Interface
This is an INDIVIDUAL assignment.
In this assignment you'll learn how to do animation in Swing-based GUIs,
by adding some animated sorting and searching features to the Photo Album
The assignment is to augment the Browser mode view of your Light Table component
to add "magnets" that attract
photos with certain tags on them. Different magnets attract
different tags, so by placing magnets in the Light Table you can "pull out"
photos of interest. Thumbnails should smoothly move toward the magnets
that attract them.
The learning goals for this assignment are:
- Experience building threaded animation loops in Swing.
- Experience integrating animated components into a Swing application.
- Experience with exploiting principles of good animation in an interactive
In this homework we'll add some basic animation functions to the Browser mode view of the Light Table,
to provide the user with a novel way of finding photos that have certain
The basic idea is that we'll introduce the concept of "magnets" to the
interface. Magnets are simply on-screen objects that are set to
attract thumbnails with certain tags.
For example, if you drop a "Vacation" magnet on the Light Table, it will
pull to it all photo thumbnails that have that tag. If you then drop a "Family"
magnet elsewhere on the Light Table, thumbnails that have both tags will move
halfway between the magnets, while thumbnails that have only one will move
to that magnet.
You should be able to drag magnets around the screen to have the thumbnails
This behavior only has to work in the Browser-type view (two dimensional matrix of thumbnails),
not in the Photo or Split view modes.
IMPORTANT NOTE: My intention with this assignment is just to have people focus on
doing animation in Swing, so I don't want to break the existing behavior
of folks' Light Tables. Obviously, things may start to get complicated if you
try to integrate the magnet-related functionality into your existing Browser view functionality, especially since
the Layout Manager you're likely using in Browser view may conflict with
the animation (since Layout Managers will want to "control" the position of
So, for this assignment, you're allowed to separate the magnet and animation functionality
from your existing Browser view. Any of the strategies below can be followed to make sure
your animation doesn't conflict with the basic Light Table functionality:
The basic gist of the above is that the original LightTable Browser functionality
has to keep working, but that you can add modes or separate windows if you
choose, to make it easier to keep the existing browser functionality from
conflicting with the magnet functionality. Let us know if there's another strategy
that you think may work well given your implementation.
- You can have an explicit mode switch in your UI that lets you toggle
between normal Light Table Browser mode and magnet mode. When you're in normal mode, your
Light Table should work like it did in the previous homework: you can't place magnets or
do anything with magnets, the view doesn't animate, but all of the previous behavior--such as selecting thumbnails and changing
views--should still work in this mode. When you change to magnet mode, all of the magnet
placement, dragging, and animation functionality should be enabled. In this mode, thumbnails still need to
be displayed, but it's ok if none of the other Browser-mode functionality is turned on (e.g., no need
to click to select, double-click to change to Photo View, and so forth).
- You can have an "implicit" mode, where once any magnet is placed
magnet mode is enabled; once the last magnet is removed, photos jump back
to their normal order and standard LightTable Browser behavior is re-enabled. The modes should work
as in the explicit case above, it's just that there's no explicit switch to turn the mode on and off.
- You could also do this as a completely separate view that doesn't reuse the
LightTable Browser window at all. If you do this, remember that you'll probably want to instantiate separate copies
of the Thumbnail components to go into the magnet view. This is because any given component can only have
one parent at a time.
Implementing the Magnets
You'll need to create some basic magnet-related controls before working on the animation itself:
Once this is working, you'll need to
implement the code that moves thumbnails around
in response to the placement of magnets. See below for some details on how
you might go about doing this.
- You'll have to create (or reuse) a component class for the on-screen magnets. You
can either create your own Magnet subclass of JComponent, or just
reuse something simple like a JLabel. Magnets don't have to look fancy, so they
can just be a label with the name of the magnet on it, at a minimum
- You'll need to provide some controls for adding a new magnet of a certain type
to the Light Table, as well as removing a particular magnet from the Light Table.
- Magnets should be draggable by the user, so that they can be moved around the Light Table
- Magnets should be positioned over the top of any Thumbnails, so that they're not obscured as they
attract the Thumbnails. This is easy to accomplish: just add them to the container after any
Thumbnails are added.
Implementing the Animation
This section provides some implementation tips for implementing the animation.
Please also check the slides for tips on Swing threading, etc.
Here's the way I'd suggest doing the animation itself:
Remember that updates to Swing components--like changing their locations--must
be done on the event dispatch thread. So you'll most likely be using a
javax.swing.Timer to do the updates.
- First, since you will be controlling the positions of thumbnails explicitly, you'll
want to "turn off" Swing's layout management for the container you're using to hold
the magnets and thumbnails. You do this by calling setLayout(null) on the container, whether
it's a separate, stand-alone view, or your existing Light Table with a magnet mode. When
you're operating without a Layout Manager, you can
explicitly set the positions of thumbnails in the container by using setLocation().
If you go with the strategy of
reusing your existing Light Table rather than creating a separate view, you'll need to reinstall your old Layout Manager when
you change out of magnet mode.
- Every time there's a change to the set of magnets on the LightTable, you want
to use a single Swing Timer to fire off some updates to the positions of all of
the affected photo thumbnails.
There will be several substeps to this process.
- First, figure out where all thumbnails are now and where they ultimately need
to be in relation to the magnets. You can store these final locations in
a HashMap or something that associates the ultimate positions with each
thumbnail. For each thumbnail, figure this out by looking at its
tags, then seeing if there are magnets that attract those tags. The
target location should be the midpoint of all of the magnets' locations that
have those tags, or just the location of the magnet itself if there's only one that attracts that thumbnail.
- In your Swing Timer's run() method, for each thumbnail whose desired location is not its current
location, update its position. For each step
through the timer, you should compute for each thumbnail the position it
should be at that step. The duration
of the animation is up to you, but I'd make it long enough that it's
clear what's going on--maybe 0.5 or 1.0 seconds--and has enough finely-spaced steps that it looks smooth--maybe 30 steps/second.
- The final part of the assignment (and the piece that I'd recommend saving for last) is that
your code should behave correctly if a magnet moves while an animation is already in progress.
The way I'd recommend to do this is to simply re-run the process of computing the new, ultimate positions
of the thumbnails based on the new magnet locations, whenever the magnets are dragged. Update the HashMap (or
whatever data structure you're using) with these new locations. Then, just extend the animation so that
the thumbnails continue moving toward their new locations. The effect should be that the magnets
move smoothly while an animation is in effect;
you should be able to drag a magnet around the screen and have thumbnails follow behind it while you're dragging
A Random Aside...
As an aside, this interaction technique basically gives you a physical model for
simple basic boolean searches. Placing multiple magnets near each other
represents an OR operation: photos that have either of the
magnets' tags are attracted to that spot. Likewise, placing magnets apart from each other lets you
do AND operations: thumbnails that have both tags move to the center
between the two magnets, as they're attracted equally to both.
You could easily imagine extensions to this such as NOT operations implemented
as magnets that repel certain tags, or magnets that have variable attracting power.
Although our tags are simple booleans (the tag is either there or it
isn't) rather than scalars (which would mean they have some value), you
could do some cool things with scalar tags. For example, thumbnails that
have "more" of a certain property might be attracted more strongly (and
move more quickly) toward a magnet that attracts that property.
As usual, there are a lot of ways to make this fancier than described.
As usual, if you do something else that's above and beyond the call of duty,
let us know in your README file and we may assign some extra credit for
- Implement the basic "good animation principles" we descibed in class. What this would mean in the context of this assignment
is 1) the pacing of the movement should follow slow-in/slow-out. 2) There should be a small bit of anticipation and
follow-through in the path of thumbnails. 3) If you happen to move a magnet while an animation is already in progress,
you shouldn't "restart" the anticipation or slow-in/slow-out (it would look weird if thumbnails started to reanticipate
every time a magnet moves; the effect should be more smooth than that). Probably around +3 points or more for this depending on
how well it works.
- Implement more advanced effects from our good animation principles. This could include explicit motion blur for fast moving
objects, or squash-and-stretch where a thumbnail deforms slightly as it starts or stops its movement. +2 for motion blur,
+3 for squash-and-stretch depending on the quality of the effect (e.g., ideally you'd want to skew the image as the
aspect ratio of the thumbnail changes).
- The basic magnet model outlined above only supports OR boolean operations
directly; the AND operation is a hack since it involves placing two magnets.
Add fancier magnets for AND (which would be a magnet that only attracts
thumbnails with multiple tags) and NOT (which would be a magnet that
repels thumbnails with a certain property), or variable strength magnets. +2 points.
- A downside of the basic magnet approach is that all of the thumbnails that match
a certain magnet pile up on top of each other, meaning that you can't see
them easily. Implement some sort of "pile" appearance where thumbnails
cluster on each other, but it's still clear that there are multiple
thumbnails. +2 points.
- Integrate animation into other parts of the interface. I think there are two places where this makes the most sense.
First, in the photo flipping behavior. Make it so that the photo smoothly rotates or has a page-flip style of animation
like an eBook reader. Second, allow reordering of thumbnails in either the Browser or Split view mode by dragging; when
the position of a thumbnail changes, the other thumbnails should smoothly animation to their new positions. Up to +3 points
for each of these, depending on how well it works.
- Remember that there's an opportunity for undergrads to do a short, informal demo the last week of class! +5 points for
See here for instructions on how to submit your homework. These instructions
will be the same for each assignment.