7.5

## Assignment 7: Beyond gOOD: A Simple Spreadsheet, Part 3

#### Due: Tue 11/26 at 8:59pm; self-evaluation due Wed 11/27 at 9:59pm

This assignment is to be completed with the same partner as Assignment 6, unless you have been reassigned.

### 1Goals

In this assignment you will complete your spreadsheet application. So far, you’ve designed a model that can represent spreadsheets, a builder to be used in reading spreadsheets from files, and a visual view that can display a model you’ve built. But to turn this simple viewer into a more useful editing tool, we need to add some functionality to it: we’d need to be able to add, remove, or modify cells in the spreadsheet and what effect our edits have. Building this new functionality should not break anything we’ve already gotten working, though, so your existing views should remain and continue to work.

This assignment is organized as follows:

• It gives you a sequence of steps to follow, each of which describes what you’re trying to accomplish, and then states what features are specifically required.

• After that, it gives you some helpful tips and example code for working with Swing UI components, key handling, mouse handling, testing, etc.

• Finally, as always, it lays out the required submission guidelines.

### 2Step 0: Cleaning up your design

Most likely, you have an interface for a view, which is directly implemented by your text and visual views. You will notice that some views offer operations that other views do not (e.g. only the visual view has the notion of “scroll position”). The ideal design here is a single interface whose methods are phrased sufficiently generally that they can be applicable to both views. For example, rather than a method to “scroll to a given position”, you might have a method “ensure a given position is visible”: by phrasing it this way, your visual view could scroll, while your text view need not do anything since all cells are already visible. If you cannot revise your design to make this work, then you may create a super interface that offers all functions, and then have individual views suppress some of them (for example, by throwing UnsupportedOperationException).

Interaction, or “back-and-forth between the user and the program” makes the role of a controller more well-defined and non-trivial than it may have seemed in the previous assignment. Like views and models, controllers are best described as an interface whose purpose is to mediate the interactions between the view and the model. Multiple implementations of controllers are possible — potentially a specialized one for every model/view pairing. However it is also possible to implement a single controller that works for all your views: it depends on your design. For this assignment, you should only need a single controller.

### 3Step 1: Adding editing controls to a new view

#### 3.1Motivation

Since we’re going to be editing spreadsheets, we’ll want to have the ability to see the raw formulas in our spreadsheets and edit them. Since displaying the formulas could take up more space than the cells you have, you’ll need some additional UI to manipulate the formulas. One possible UI might look like a toolbar:

#### 3.2Requirements

1. Design a new view that contains the existing visual view as a component within it, and adds the following abilities:

1. Select an individual cell by clicking on it. This should provide some obvious visual feedback to the user — in the screenshot above, I highlight the border of the cell, but you may choose another UI if you wish.

2. Displaying the full formula for that cell somewhere editable — in the screenshot above, I place that formula in a textbox in the toolbar, but you may choose another UI if you wish.

3. Allowing a user to edit that formula and confirm or reject the edits — in the screenshot above I used the two toolbar buttons on the left, but you may choose another UI if you wish. If the edits are confirmed, the cell must be edited; if the edits are rejected, then the displayed formula must revert to the current contents of the cell.

NOTE: You should not add this functionality directly to the existing visual view; you should build a new, composite view, and leave your existing visual view alone.

2. Add an extra option to your command-line option: -edit. Specifying this option should open this editor view (as opposed to -gui which opened your non-editable graphical view from Assignment 6). All previous command-line arguments should continue to work as before.

For Assignment 6 you likely had a class that extends JFrame and implements YourViewInterface. You also very likely have had some class that extends JPanel and did all the “interesting” graphical work; the JFrame probably was pretty thin in terms of its own functionality. For this assignment you need to reuse the JPanel as a component in your new editor view; you do not have to reuse the JFrame class you created, and can develop a new one if needed. If your prior implementation did not create a custom panel, and had all of its implementation directly in your JFrame, then refactor your design so that it is more reusable.

You are free to design the interactions in any way you wish. However your application must meet the following standards:

• The application must provide visual cues about what input is expected (e.g. a hard-to-guess sequence of keystrokes to do something is not acceptable), i.e., the user interface should be discoverable.

• The application must provide visual cues about the effect that a user’s input has had (e.g. a user should know which cell is currently selected, and how to change this selection).

• The interactions must be reasonably user-friendly and intuitive. We do not expect snazzy, highly user-friendly programs. Our standard is: can a user unfamiliar with your code and technical documentation operate the program correctly without reading your code and technical documentation?

### 4Step 2: Editing arbitrary cells

Now that you have the ability to modify cells, you need to make sure that the user can modify any cells they wish. Moreover, any changes they make must be applied to the model, and any affected cells must be re-evaluated.

#### 4.1Requirements

1. Enhance your editor view with the ability for the user to scroll indefintely to the right of the current rightmost cell, or down beneath the bottommost cell, and be able to edit any cell they choose. Ideally, this could be done simply by scrolling; if you chose a different UI, that is ok.

2. As items are edited, the computed values of any affected cells must be recomputed and redisplayed immediately. (One expensive way to do this is simply to recompute all cells on every edit; a more efficiently designed solution is up to you.) Note that this may cause cycles in your model: your program must not crash if this happens, even if you do not currently explicitly detect cycles.

3. Implement whatever controller, keyboard and mouse handlers you need to support the new view’s functionality. Place all the code of your views in the edu.cs3500.spreadsheets.view package, and the controller and handlers in the edu.cs3500.spreadsheets.controller package.

4. Document any further changes made to your models or views from the previous assignments: explain what was added, removed or changed (besides the package declaration), and why. You should place this documentation in your code and a separate README.txt file. PLEASE DON'T FORGET TO SUBMIT THIS README FILE! (The file can be plaintext, with extension .txt, or Markdown, with extension .md. Please don’t forget the extension.)

Again, you are free to design the interactions in any way you wish. However your application must meet the same standards as in Requirements above.

### 5Steps 0–∞: Testing

Testing any keyboard handlers is straightforward — by design, you may replace the Runnables with those that make it easier to confirm that the appropriate one is run with the appropriate key.

Testing the controller should also be straightforward — all of its behavior is either in its methods, or in the wiring-up of those methods to key, mouse or other event handlers/listeners. If you’ve already tested that the wiring works properly, now all that remains is to test the methods themselves.

1. Write tests for various components of your application (controller, listeners). Note that this is distinct from writing tests for your visual and editor views — we are asking you to test the controller functionality, not the views’ appearance.

2. Complete any testing from the last assignment that you didn’t otherwise finish.

### 6Design tips

The following sections offer helpful design tips. You may find them useful or not, depending on how you choose your user interface elements. They are not required parts of your design.

#### 6.1Dividing functionality into MVC

Look at the code for the MVC examples and the turtles example. Notice how the functionality is divided into model, view and controller. Make your decisions based on the roles of these components.

Remember to consider the possibility of adding capabilities to views, or creating new views. If this happens, are the changes isolated and/or minimal? Is your controller really controlling the application? Is your model catering to the specific needs of some view?

#### 6.2Handling the keyboard, generally

Look at the code for the MVC examples. Since you may be using several keys in this assignment, using the map design is recommended. Recall how the controller gets control when a key is pressed: make sure your implementation of this assignment retains this essential ability of a controller.

#### 6.3Mouse handling

Mouse handling involves a MouseListener interface and possibly the MouseMotionListener interface, just as keyboard handling involved a KeyListener.

1. Design a class that implements MouseListener. It probably does not need to be as sophisticated and indirect as the KeyboardHandler above, since there are only three possible mouse events (left, middle and right clicks), rather than an entire keyboard.

2. Enhance your controller to create one of these mouse listener objects, and configure it however you need to.

3. If you need to define only 1 or 2 of these listener methods, starting from a MouseAdapter may be simpler.

Hint: When you are testing each component above, be clear about what you are testing. The objective of testing the keyboard handler is to ensure that the appropriate action is taken on the appropriate key, not whether that action is successfully completed (that is part of testing the controller).

### 7Step 4: Extra-credit functionality

For this assignment, there are a few small extra-credit enhancements you can try. Larger-scale enhancements will be separately explained in Assignment 9.

Add the ability for a user to save their edited computational masterpiece from within the GUI editor. A user should be able to save using the textual format from the previous assignment. For credit here, you must not simply merge your existing views into a single class, but rather keep your views separated and delegate to them as appropriate.

Add the ability to use arrow keys to move the cell selection from one cell to its neighbors.

Add the ability to use the Delete key to clear a cell’s contents.

Do not attempt the extra credit unless you’ve completed the required functionality above. We will not count it as extra credit unless the required features are completed. (You will still have the opportunity for extra credit in Assignment 9.)

For this assignment, you will be graded on

• the design of your entire project,

• whether all your views (the previous ones and the editor one) work correctly,

• how well you justify any changes made to your earlier code,

• whether the required features work,

• how much replication/duplication exists in your views,

• whether your usability choices are reasonable,

• the correctness and thoroughness of your tests.

### 9Submission

• Submit all your source code, for this entire project.

• Submit all your test cases.

• Submit a plaintext README.txt (or Markdown README.md) file explaining your design. Make sure you explain your design changes from the previous assignment.

• Submit a spreadsheet file that computes the first 50 triangular numbers using the standard recursive formula T(1) = 1, T(n) = T(n - 1) + n. Submit a screenshot of your editor view, rendering this file file. It must clearly show your user interface, with the cell containing T(10) selected, and with the formula for T(10) visible. You must submit it as a JPEG, with file extension .jpg, or as a PNG, with file extension .png and the file extensions are case-sensitive.

• Submit a JAR file (with extension .jar) file that can run your program.

• Your directory structure should be the same as in prior assignments — a src/ directory and a test/ directory — plus a third directory named resources/ containing your README, your JAR file, screenshots, and example files as required.

• WARNING: If you are on a Mac, you likely will create a zip file that inadvertently contains a hidden __MACOSX directory. This directory is not needed, but it contains a parallel copy of all the other files in your zip, which basically doubles the size of the zip and the number of files in it. This will likely lead to the server rejecting your submission as too large or as containing too many files. If you get this error, open your zip and delete the __MACOSX directory, then try again. Ask a TA or professor for help if you’re stuck.

To create a JAR file, do the following:

• Go to File -> Project Structure -> Project Settings -> Artifacts

• Click on the plus sign

• Choose JAR -> From Modules with dependencies. You should now see

• Select the main class of your program (where you defined the main(String[] args) method)

• If you see a checkbox labelled “Build on make”, check it.

• Hit ok

• You should now see something like

If now you see a checkbox labelled “Build on make”, check it now.

• Click ok

• Make your project (in older versions of IntelliJ: click the button to the left of the run configurations dropdown, with the ones and zeros and a down-arrow on it; in newer versions of IntelliJ: click the button that looks like a green hammer) Your .jar file should now be in <projectRoot>/out/artifacts/.

Please test your jar file thoroughly by running it using various command-line arguments. This will our primary means of testing your program. There are no automated tests for this assignment, but a lack of a working JAR file will make it very hard for your graders to check if your program runs properly.