Assignment 7: The Music Editor: Third Movement
Due: Wed 04/05 at 8:59pm; self-evaluation due Thurs 04/06 at 8:59pm
This assignment is to be completed with the same partner as Homework 6.
In this assignment you will complete your music editor. You will need to implement one more view, and implement/enhance the controller for your editor.
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 —
1 Implementing a controller
Your controller must allow the user to:
Start and stop the music playing with the pressing of a key or clicking of a button
Add a new note to a composition
Scroll through a composition with the arrow keys (and scrollbars, if you have them)
Jump to the beginning or end of the composition, via the Home or End keys (Mac users: look up how to emulate the Home and End keys using the Mac keyboard)
Most likely, you have an interface for a view, which is directly implemented by your console, gui and midi views. You will notice that some views offer operations that other views do not (i.e. key events do not make sense for the console views). You may either create a super interface that offers all functions, and then have individual views suppress some of them, or you can create interfaces for each view type/capability and implement your views accordingly.
2 Enhancing your GUI view
2.1 Handling 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.
In particular by the end of this assignment your gui view is expected to use keys to start playing the music, stop playing the music, scroll the gui view sideways and jump to the beginning and end of the music.
2.2 Mouse handling
Mouse handling involves a MouseListener
interface, just as keyboard handling
involved a KeyListener
.
Design a class that implements
MouseListener
. It probably does not need to be as sophisticated and indirect as theKeyboardHandler
above, since there are only three possible mouse events (left, middle and right clicks), rather than an entire keyboard.Enhance your controller again to create one of this mouse listener objects, and configure it however you need to.
Enhance your
GuiView
again withaddMouseListener(MouseListener)
(and possibly aremoveMouseListener
too).If you need to use only 1 or 2 of these listeners, starting from a
MouseAdapter
may be simpler.
2.3 Organization of dependencies
Notice that the controller is telling the GuiView
“please use the following
objects to react to events”, while the GuiView
is advertising that it
is capable of reacting to mouse and keyboard events. The views don’t have to
know anything about what the controller wants to do with those events, or even
have a reference to the controller object directly. This ensures a looser
coupling between the controller and view, and allows the controller to freely
modify the keys it wants to handle without requiring changes within the view
(beyond the initial, generic ability to handle events in the first place).
3 Composite Views
Having visual and audible views completely separate seems unfortunate: it’s time to remedy that.
Design a new view that takes in both a
GuiViewImpl
and aMidiViewImpl
. It should be able to start, pause and resume playback of the sound, and it should cause the red line to sweep across the gui view as the music is played, in a synchronous manner (i.e. the beat at which the line is should be the beat whose notes the midi view is playing. Once the current beat reaches the right-hand edge of the view, the view should scroll to bring the next measures of the composition into view.
This will likely require writing other methods in your views. Depending on how you have designed your view interfaces, carefully think about where these methods need to be.
To synchronize the sound and visual views, you will need some sort of common reference of time. Either both sound and visual synchronize with a common time, or one of the views synchronize with the other. (Do any of your views already have the notion of time?)
You have some freedom in designing this composite view. Primarily it is important that it reuses the existing gui and midi views in some way, rather than replicate them.
3.1 Adding notes
Use the mouse listeners to enable adding a note by clicking on the appropriate key in the keyboard portion of the visual view. You may assume that this can be done only when the music is not playing (so that the user is not racing with the music player). You may also assume that the user can first scroll the red line to the appropriate beat and then add a note that starts at that beat. Finally you may assume that a single click adds a note of single beat duration of the appropriate pitch.
After adding that note the red line should automatically move by one beat, so that it is possible to smoothly add several notes.
3.2 Assignment
Implement the controller, keyboard and mouse handlers, and the new view above. Place all the code of your views in the
cs3500.music.view
package, and the controller and handlers in thecs3500.music.controller
package.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.
4 Testing
Testing KeyboardHandler
is straightforward —Runnable
s that confirm that they’ve been
run.
Testing the controller should be straightforward —
Complete any testing from the last assignment that you didn’t otherwise finish.
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).
5 Grading standards
For this assignment, you will be graded on
the design of your entire project;
the quality of supporting documentation (Javadocs and README),
the adherence of your implementation to how it is described in the assignment (e.g. using the appropriate keys),
how well you justify any changes made to your earlier code,
the correctness and stylishness of your implementation
the correctness of your tests.
6 Submission
Submit any files created or modified in this assignment.
Submit a text README file explaining your design. Make sure you explain your design changes from the previous assignment.
Submit a screenshot of your composite view, rendering the
mystery-2.txt
file, and paused somewhere between beats 32 and 64. 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.
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 seeSelect 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.
Make your project (Go to Build -> Artifacts, select the jar artifact you created above, and select “Rebuild” for a full rebuild of the project. Your
.jar
file should now be in<projectRoot>/out/artifacts/
.
Please submit your homework to https://handins.ccs.neu.edu/ by the above deadline. Then be sure to complete your self evaluation by the second deadline.