HOMEWORK 6: Magic Lenses

This is an INDIVIDUAL assignment.

Objective

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

You'll augment the PageSorter to add the ability to display a Magic Lens that reveals the tags of any page thumbnails over which it passes. You should be able to make lenses appear and disappear, and drag them around the sorter UI.

The learning goals for this assignment are:

Description

In this homework we'll add Magic Lenses to the notebook UI. The basic idea is that lenses should provide a new way to find the pages you're looking for. Augment the PageSorter to provide controls to make a lens appear or disappear; once on screen, the lens should be draggable across the page sorter.

When the lens passes over a page thumbnail it should change the graphical presentation within its bounds. Specifically, it should cause the thumbnail to not show page contents (ink and text), but rather a graphical representation of the tags that are on the thumbnail(s) below it, such as appointment, action item, and so forth.

Think of the lens as an alternative view that changes the page thumbnails from displaying content to displaying tags.

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" page sorter 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 PageSorter. 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.

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.

Deliverable

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 this assignment is significantly more difficult than the previous one, most of the parts should be fairly straightforward. Start with the basic PLAF component architecture and get that working in your application first; one easy way to do this is to implement the UI class's paint method so that it only draws the page background. This way you'll be able to see your component show up and know it's working correctly. After this do the stroke processing (it's the next easiest), followed by the text processing (slightly more complicated). Finally, once all of this is working, it should be fairly straightforward to keep a list of notepage components in your application and make the New/Delete/Next/Previous controls work.

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 "java NotebookApp" when run from inside your project directory (described below). 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 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 we migiht need in order to run your code.

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

Please take care to remove any platform dependencies, such as hardcoded Windows path names or depencence 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 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.