[an error occurred while processing this directive]
[an error occurred while processing this directive]

PS3: Input Models

Due at 5:00pm, Monday, March 3rd, 2008, by email submission only.

This assignment explores the following topics related to GUI input:

In this problem set, you will implement input handling for the checkerboard you created in PS2, so that the user can pick up checkers with the mouse and drag them around.

Provided Resources

This assignment builds on top of the code you wrote for PS2, plus a new class:

Problem 1: Dragging in Stroke and Pixel Models (35%)

Add input handling to your StrokeBoardView and PixelBoardView, so that the user can drag checkers around.

Pressing and dragging in a square containing a checker should pick up the checker from the board. The checker should not make any abrupt jumps — neither when the user presses the mouse button, nor when the user starts moving the mouse. The checker should move smoothly with the mouse pointer, hovering over the other checkers on the board as in the example screenshot.

If the user releases the mouse button when the mouse pointer is over an empty square, the checker should be moved to that square using Board.move(). The board model should not be changed until then. If the mouse pointer is over a filled square or off the checkerboard entirely, then the dropped checker should be put back where it was taken from.

If the mouse pointer leaves the checkerboard during the drag operation, the dragged checker may either follow it (becoming invisible because of clipping), or it may stop at the edge of the checkerboard — the behavior is up to you. But if the mouse pointer moves back into the checkerboard, the checker should resume following the mouse.

A word of advice: you may notice that your stroke and pixel model implementations are very similar, differing only in how a single checker is painted. Before you add input to either class, you might want to restructure your code so that one class extends the other, or so that both classes extend a single abstract class, with a method called something like paintChecker() that can be overridden with the appropriate behavior for both models. That way you can just add input handling once, to the superclass, and save yourself a lot of redundant implementation.

Problem 2: Dragging in Component Model (35%)

We could add input handling to ComponentBoardView in the same way, but instead we're going to build a solution more in the spirit of the component model: a generic controller.

Create a generic, reusable move interactor that is capable of dragging any components around inside their container, not just checker components in your ComponentBoardView. We have provided a skeleton interface for MoveInteractor for you to fill in. Your implementation should be generic, not referring to any classes specific to the checkerboard problem.

MoveInteractor should listen to the draggable components themselves (the checkers) for mouse events. It should not listen to their container (i.e., the checkerboard view).

Use MoveInteractor to add input handling to your ComponentBoardView. Checker dragging should behave the same way as specified in Problem 1. Since MoveInteractor is generic, you need to customize it for the checkerboard, which you can do by creating a subclass of MoveInteractor that overrides drop(), in order to decide whether it should allow the checker to be dropped, and if so, change the board model.

Hints:

Problem 3: Hit Testing in Component Model (15%)

A checker should only be picked up when you click on the checker itself, and not the edge of the grid square around it. Modify your MoveInteractor so that this behavior is observed.

This can be done by overriding the contains() method in the CheckerComponent class. Note: There are two contains() methods, one that takes a pair of integers and one that takes a Point. You should override both.

This implementation is only required for the component model.

Questions (15%)

Answer the following questions in readme.txt.

  1. Does Swing coalesce mouse move events when the user drags a checker? Don't just guess: instrument your code to find out, and describe how you did it.
  2. How would each of your views behave if a checker is removed from the model while the user is currently dragging it?
  3. Recall that MoveInteractor listens to individual checker components, not to the entire board. Suppose you attached a mouse listener to the ComponentBoardView as well. Which of the two listeners would receive a mousePressed event in the following cases:
    1. Mouse pressed over the center of a checker.
    2. Mouse pressed just inside the corner of a square containing a checker.
    3. Mouse pressed over an empty square.

What to Hand In

Package your completed assignment as a jar file, as described in PS1. Here's a checklist of things you should confirm before you hand in:

  1. all your Java source is included in your jar file (Javadoc documentation isn't necessary)
  2. the main class of your jar file is BoardViewTester
  3. all necessary third-party libraries are included, either inside your jar or as separate jars referenced by your jar's classpath
  4. all images used by your code are included in the jar and referenced as resources
  5. readme.txt is included, and it answers the questions above and credits anybody you discussed the assignment with
Before you submit your solution, put all the jar files you plan to submit in an empty directory and make sure you can run it:
java -jar yourfile.jar

Submit your solution by email (with all required jar files attached) to 6831handin@csail.mit.edu and include PS3 in the subject line.

[an error occurred while processing this directive]