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