Learning to program is not an easy task. Teaching people to program is not easy either. There is no fomula to show that once you plug in all the right elements, you have a working program. To that end, many have attempted to provide an environment to students learning how to program so that the beginner can focus on design or algorithmic thinking rather than specifics about exactly "how" a particular effect is achieved within the computer. Two such examples are Karel the Robot and LOGO Turtle Graphics (which you explored in the last assignment). Another example (perhaps less famous) is the environment we give you in CSE 115 with our own graphics package.
In this lab, you will work with elements from all three of these environments and create a set of controls that can manipulate any one of them. Essentially, this is an integration problem. One that we will solve by using two different design patterns.
Innovations and inventions that are built for the same purpose are not often built at the same time, nor are they compatable with each other in some way. For example, when the VCR was first being introduced, there were two formats for video cassette tapes, Beta and VHS. VHS won out and Beta tapes disappeared. However, an interesting problem arose. Some people had purchased Beta tapes and VCRs. Unfortunately, the Beta technology and the VHS were not compatible. If only there was a way to make the Beta tapes work in the VHS VCRs and vice versa.
With software, we have an opportunity to make seemingly uncompatible things compatible and view those uncompatible things interchangeably, using the adapter pattern and polymorphism.
In this lab, we will look at the Adapter Pattern and the Proxy Pattern.
Your task is to create a control system and a user interface that will control Karel
or the Turtle
from the lab6lib
package or a graphic object from the graphics
package in Classlibs. Each of these three things have a different interface with different methods that you can call on them. However, they all have the ability to move. Your job will be to create controls to move each of them in the directions Up, Down, Left, and Right. The user will choose which of the three elements he/she wishes to move. However, no matter what the user's choice, the movement must occur with the same result. For example, if the user chooses to move the Turtle
up and then chooses to move the graphic up, each will move the same distance in the upward direction.
First, you should look at the code that has been provided for you. Notice that the framework for the graphical components of this program have already been laid out. However, none of the graphical components react to user interactions. We will fix that as the lab goes on.
Notice that Karel, the Turtle, and a graphic already appears on the DrawingCanvas when the program begins.
BEFORE GOING ON TO THE NEXT STEP you should make sure that you understand all of the code that is already in the designpatterns package.
Discover how Karel, the Turtle and graphics work. You should look at the Javadocs provided for each to see how you can manipulate each one of these elements. You should note at this point that each one of them is manipulated in totally different ways. For example, Karel can only turn to one of four directions and then move forward in whatever direction it is facing. The turtle can be set to face a particular direction (indicated in degrees) and then move forward in that direction. A graphic can be set to any location, but does not have the same notion of movement as the other two elements.
This is a problem. Your controls must control each of the three elements, so we need a common way to speak to each of them - a common interface! However, you can not make changes to the code of Karel or the Turtle, or the graphics package, so what can you do? You can use an Adapter!
First, create an interface with the type of controls you wish to have. Remember, you want each of these things to move up, down, left and right. So, probably good candidates for the names of the methods in the interface are up, down, left, and right.
Then we'll start with the Karel Adapter. You make a class that implements the interface that you just wrote and "knows a" Karel object. Leave the interface methods blank for now. Now, include the creation of this adapter object in the code in Lab6Program and make sure that you can still see Karel (and all of the rest of the elements on the screen).
You can do the same for a Turtle Adapter and Graphic Adapter, each time, making sure that creating this adapter object does not break what you currently have in your code.
We should have our buttons talk to the adapter for Karel so that we can program the adapter to make Karel do what we'd like him to do when we ask him to move up, down, left, or right. Concentrate on up first. Look back at the Javadocs and see how we could make Karel move up. Write the code for that in the Karel Adapter class. Then you should test out to make sure it works. Therefore, you will need the movement buttons to have action listeners. Create the action listener for the up button and make sure it talks to the Karel Adapter (and only the Karel Adapter for now). Run the program and see if Karel moves up. If not, go back and fix it so that Karel does.
Continue in this way for the rest of the three directions. Now you have a set of controls that can move Karel.
Modify your controls so that they communicate with a Turtle Adapter (and only the Turtle Adapter). Write the code in the Turtle Adapter methods so that the turtle behaves appropriately when the buttons are clicked. Remember that the turtle should move as far on the screen as Karel does and Turtle steps are smaller so you will have to adjust the movement to get them to move at the same pace. Make sure that all of the buttons work and control your Turtle Adapter properly.
Modify your controls so that they communicate with a Graphic Adapter (and only the Graphic Adapter). Write the code in the Graphic Adapter methods so that the graphic you have chosen behaves appropriately when the buttons are clicked. Make sure that all of the buttons work and control your Graphic Adapter properly.
Now, we want to create code so that the user can select which element they want to control and then the program will control that element.
For this, we will need the Proxy Pattern to hold onto the currently selected element (Karel, Turtle, or Graphic). Create the Proxy so that it can hold onto any of these three things. Hmmm - how can I do that - they all have different types? Well, they do, but we've created some things already that will help us. There are Adapters for each of these elements and the Adapters all implement the same interface, so the Proxy can hold onto an element of that type and we can then assign any object whose class implements the interface to that variable (that's polymorphically delicious). Set the proxy up with the proper mutator method and so it delegates properly when it's methods are called.
Change the directional movement buttons so that they talk to the Proxy instead of the Graphic Adapter. To test to make sure things are working correctly, create a Proxy object and set its initial element to be the Karel Adapter. Test all of the buttons to make sure they work. Now modify it so that the initial element is the Turtle Adapter and test again. Modify one more time so that the initial element is the Graphic Adapter and test once more. Change it back so that the initial element is Karel and move on to Step 7.
Now, you need your selection buttons to communicate with the Proxy. Create an action listeners for the Karel selection button so that it will notify the proxy when it has been clicked to change the "current element" to Karel. Run your program, select the Karel button and make sure you can move Karel.
Now create a listener for the Turtle selection button. Run the program and make sure you start off initially controlling Karel, then can control the Turtle, and then Karel again, then the Turtle.
Lastly, create a listener for the Graphic selection button. Run the program and make sure you start off initially controlling Karel, but then can arbitrarily switch between the three elements. After this - you're all done with the coding!
For this lab, we will begin to look at your code more closely. First, you should make sure each of your code files is spacing and tabbed nicely. There is an automatic formatting feature of Eclipse to help you do this. Use whitespace to increase readability.
Second, look at the names of all your classes - do they make sense and explain what the class is doing. Classes named Button and ActionListener ARE NOT GOOD AND DESCRIPTIVE NAMES. Those buttons and action listeners have a purpose. Rename your classes to reflect that purpose.
Third, go through your variable and method names. Any variable and method names you have control of should be meaningful. Variables named x, c, or p are not good descriptive names. Change them!
Fourth, pay attention to the class coding standards and naming conventions. Watch capitalization and make sure your code conforms to the class standards.
Fifth, go through and comment your code. Every class should have a comment stating its purpose. Every instance variable should have a comment stating its purpose. Every method should have a comment stating its purpose. Inside methods, comment any code that uses an algorithm that is not immediately understandable from looking at the code. If the class is part of a design pattern, state the pattern and this class' purpose in the pattern.
Read through the entire lab before you start working, so that you know what to expect. Make sure you save your work often, and keep track of what you are expected to submit.
Do not be afraid to refer to earlier labs to recall what things mean or what commands are available for you to use.
You will submit your Lab 6 assignment using the Web-CAT submission plugin from Eclipse. There will be no automatic grading for this assignment. You will receive a score of zero when you submit and then it will be updated when the TA is finished grading your submission.
Recitation | Due Date |
---|---|
A1 | Monday, April 4th at 9:00pm |
A2 & A5 | Tuesday, April 5th at 9:00pm |
A3 & A6 | Wednesday, April 6th at 9:00pm |
A4 | Thursday, April 7th at 9:00pm |
Here is the grading information for this assignment:
Automatic Grades of 0 awarded for the following reasons:
[1] If the code does not compile.
[2] If the code does not run.
[A] Interface that Adapters Implement (10%)
(4%)[A1] Interface created by students (name is up to them)
(6%)[A2] Has method headers for each of the type of controls we want
for all three elements (up, down, left, right)
[B] Adapters (24%)
(8%)[B1] An adapter has been created for Karel that implements the
interface defined in Part B and "knows" a Karel object. The
adapter calls the correct methods on the Karel object to allow
it to move up, down, left, and right.
(8%)[B2] An adapter has been created for the Turtle that implements the
interface defined in Part B and "knows" a Turtle object. The
adapter calls the correct methods on the Turtle object to allow
it to move up,down, left, and right. The turtle should move as
far as Karel does in pixels, so an adjustment must be made to
the turtles steps to achieve this. If the turtle does not move
as far as Karel, award zero points for this section.
(8%)[B3] An adapter has been created for the graphic that implements the
interface defined in Part B and "knows" a graphic object. The
adapter calls the correct methods on the graphic object to allow
it to move up, down, left, and right. Once again, the graphic
must move as far as Karel does on each step. Therefore the code
must be written to allow the distance in the movement. If the
graphic does not move as far as Karel, award zero points for
this section.
[C] Proxy (16%)
(4%)[C1] Proxy class created
(4%)[C2] Proxy class implements interface defined in Part B
(4%)[C3] Proxy class knows an object whose declared type is the
interface defined in Part B
(4%)[C4] Proxy methods delegate to the object from Part C3
[D] Directional Buttons communicate with Proxy (15%)
The buttons that control direction should each provide an
ActionListener that has a reference to a Proxy object. The
ActionListeners for these buttons should not have a reference to
any of the Adapters created in Part C or to Karel, the Turtle, or
the graphic itself. When clicked, the buttons should communicate to
the Proxy which direction the element should move by calling the
appropriate method from the Proxy. There is no partial credit for this
section.
NOTE: If a student did not implement the Proxy at all and
therefore only made it to Step 4 of the lab, award 12 points for
this section if the ActionListeners can speak directly to one of
the adapters.
[E] Selection Buttons communicate with Proxy (15%)
The buttons that control which element should move should each provide an
ActionListener that has a reference to a Proxy object. When clicked, the
ActionListener should set the object that is the Proxy's "current" to be
appropriately Karel, the Turtle, or the graphic. There is no partial
credit for this section.
[F] Style (20%)
There is no partial credit for these sections. If the submitted code does
not meet the given criterion, it should be awarded zero points for that
subsection.
(5%)[F1] Code uses proper tabbing and whitespace for
readability.
(5%)[F2] Naming of classes, methods, and variables are meaningful to the
project.
(5%)[F3] Naming conventions for classes, methods, variables, parameters
are following according to CSE 115 styles.
(5%)[F4] Every class, instance variable, and method is commented with its
purpose in the project.