HOMEWORK 6: Magic Lenses

This is an INDIVIDUAL assignment.


In this assignment you'll learn how to implement Magic Lenses in Swing, and integrate lenses with your Light Table UI.

You'll augment the Light Table to add the ability to display two Magic Lenses. The first will reveal the tags of any photo thumbnails over which it passes. The second will reveal the otherside of the thumbnail you drag it over (so if you drag over an unflipped, photo-side-up thumbnail you should see the underlying annotations; if you drag over a flipped, annotation-side-up thumbnail you should see the original photo). You should be able to make lenses appear and disappear, and drag them around the Light Table UI.

The learning goals for this assignment are:


In this homework we'll add Magic Lenses to the Photo Album UI. The basic idea is that lenses should provide a new way to find the photos you're looking for. Augment the Light Table to provide controls to make your two types of lenses appear or disappear; once on screen, a lens should be draggable across the Light Table. For the tag lens:

When the tag lens passes over a thumbnail it should change the graphical presentation within its bounds. Specifically, it should cause the thumbnail to not its original contents (either the photo or annotations), but rather a graphical representation of the tags that are on the thumbnail(s) below it, such as Vacation, Family, and so forth.

Think of the lens as an alternative view that changes the thumbnails from displaying content to displaying tags. For the anti-flip lens:

When the anti-flip lens passes over a thumbnail, it should change the graphical presentation within its bounds to show the reverse side of the thumbnail. In other words, if you drag over an unflipped, photo-side-up thumbnail you should see the underlying annotations; if you drag over a flipped, annotation-side-up thumbnail you should see the original photo. Interactions among lenses:

Lenses don't need to be able to interact in any special way with each other. So if you place an anti-flip lens over a tag lens, for example, it's fine if you just implement some simple policy, such as making the top-most lens be the only one that alters the view.

NOTE: Remember in the previous assignment I said that it's ok to implement the magnet animation as an alternate view or mode in your interface. If you've done this, it's ok if the lenses only work with the "standard" Light Table view or mode, and not the animated mode.

There are a number of specific requirements you should implement for this assignment:

Implementing the Lenses

Take a look at the slides and other resources for implementing lenses in Swing; they'll be very helpful for this assignment. The first step is that you'll likely want to create a lens parent component that you install as the GlassPane for your Light Table. This will be the container that holds lenses.

Next you'll want to implement the lens class itself. You can either extend JComponent directly (which means that you'll implement paintComponent() to draw your titlebar or drag handles or whatever, as well as your dismiss control), or you may want to investigate using JInternalFrame as a shortcut way to create a lens that looks something like a normal window. You do not need to use the MVC model for your lenses.

For the input part of the assignment, make sure your lens implements listeners for all of the sorts of events that it wants to receive. When an event happens, you simply need to see where in your lens it occurred. If it is on the draggable area or other control, then your lens should respond to the event itself. If on the other hand it's in the transparent main area of the lens, you will need to tweak the event and then re-dispatch it to the underlying component over which it occurred. Look at SwingUtilities.convertMouseEvent() and Component.dispatch() as ways to do this.

For the output part of the assignment, in paintComponent() you'll have to do two things. First is figure out what components are within the lens' bounding box and render them. Remember the strategies for output we talked about in class: ambush, model-in/model-out, and reparameterize and clip. You will likely use either ambush (create your own Graphics object subclass and then ask the thumbnails to draw themselves using this object; see SwingUtilities.paintComponent() ), or model-in/model-out (which would mean just looking at the hierarchy of thumbnails at runtime and drawing a representation of them yourself). Model-in/model-out is probably the easiest approach. Most of the work here will likely be in simply getting the coordinate transforms right. After rendering the new view of the thumbnails, then render the lens' own appearance (drag and dismiss controls) over this.

Extra Credit

As usual, there are a lot of ways to make this fancier than described.

Since this is the last project, we'll also have a one-time chance to earn 10 extra bonus points by doing an in-class demo on November 29, similar to what the grads will do in the following classes. You must sign up to do this in the previous class.

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 it.


This is an INDIVIDUAL assignment; while you may ask others for help on Java or Swing details, please write the code on your own. While you can use any development environment you choose, you are not allowed to use "GUI builder" type tools (like JBuilder or Eclipse GUI Builder).

To turn in the assignment, please follow the same process as last time:

0. Make sure your program is runnable from the command line using the command "j ava PhotoAlbum". Use exactly this name (with no package) to make things easier on me and the TAs.

1. Create a new directory using your last name as the name of the directory.

2. Compile your application and place both the sources and classfiles into this directory (they can be at the top-level or in a subdirectory, whatever you want).

3. Put a README.txt file (described below) into the top level of the directory. This file should contain your name and email address, the version of Java you used (1.5.x or 1.6.x, please) as well as any special info I might need in order to run your code (command line arguments, etc.)

4. ZIP this directory and submit it via T-Square (instructions are here).

If you do any extra credit work, be sure to let us know about it in the README file so that we don't miss it!!

Please take care to remove any platform dependencies, such as hardcoded Windows path names or dependence on a particular look-and-feel that may not exist on all platforms. Also, if you use any images in your application, please make sure that you include these in your ZIP file and that your code will refer to them and load them properly when from from inside the directory that's created when I unZIP your code.

Grading for this assignment, and future assignments, will roughly follow this breakdown:

Please let the TA or me know if you have any questions.