S11:Labs:lab07
From 56wiki
CS56—Advanced Applications Programming—S11
S11:Exams | S11:Homework | S11:Labs | S11:Calendar and Lecture Notes | S11:Syllabus | S11:Choice |
---|
lab00 | lab01 | lab02 | lab03 | lab04 | lab05 | lab06 | lab07 | lab08 |
lab07: Inheritance, Interfaces, Inner Classes, Event Listeners, Exceptions
Tip
If you find typos, note them on the discussion page. This lab is "locked down" for edits only by the instructor and the TA until after the due date has passed.
assigned | due |
---|---|
Wed 05/18 | Fri 05/27 |
Overview
In this lab we
- apply the concepts of inheritance (extends) and interfaces (implements)
- continue working with Java GUIs, adding event listeners and learning about inner classes
- we show how to work with Exceptions in Java
Pre-lab reading
Part 0: Introduction
This week, we have a TicTacToe game (written by your instructor) that illustrates a lot of the concepts from the textbook that covered on the exams (Midterm 2 and the Final). So our first step is to sit down with the code and your textbook, and just get familiar with the code, and the concepts it illustrates. If you do that, then
- when you actually sit down to work on the lab, you'll be in much better shape
- perhaps even more important (to your grade), you'll be preparing yourself for exams by reviewing the things I'll be testing you on.
The order in which we'll go through the code makes sense from the standpoint of understanding the project—but it doesn't exactly correspond to the order of presentation in the textbook. So we'll be skipping around a bit. Sorry about that—but:
- since, supposedly, you've already read these chapters, it shouldn't matter that much
- since we have hyperlinks to help you find your place, it shouldn't be too bad.
So, let's get started.
First, here's the link to the code. You may want to keep this link handy in another window so that you can browse the full source code as you read.
http://www.cs.ucsb.edu/~pconrad/cs56/11S/labs/lab07
Part 1: Review of the basic ideas of Interfaces
Here are some facts about Interfaces in Java, in the form of Q and A.
Potential Exam Questions
All of the Q&A below are things I might definitely ask you about on an exam.
Q: What is an Interface?
A: It's just a collection of "method signatures", or if you prefer, "function prototypes". Really. That's all it is.
Q: What does it mean if a class implements an Interface?
A: It means that the code for that class must include every one of the methods listed in the Interface.
Q: Can the class that implements an Interface have other methods as well?
A: Yes, absolutely—and classes frequently do have other methods. But at least, every one of the methods in the Interface must be there if the class implements that Interface. You could say that implementing an Interface is like "making a promise" that the class has certain capabilities.
Q: When would you want to use an interface?
A: There are lots of reasons, but here are a few:
- Any time you think about a situation where you might have a number of different objects that might be very different from one another, but they have a small set of things in common, and there are times when you want to treat them all the same.
- Any time you have something like a "plug-in" situation, where you have a number of different ways of accomplishing the same thing.
Q: This is all a bit abstract. I think I need to see some examples. Can you help?
A: Why sure--that's the main theme of this week's lab.
Here are two examples of Interfaces from this week's lab.
TicTacToeGame.java
public interface TicTacToeGame { /** returns 'X' or 'O' depending on whose turn it is. Returns ' ' if game over. */ public char getTurn(); /** is this square blank. Should be called before move() to see whether the move is legal. @param i number between 1 and 9 indicating square @return whether square is blank or not. */ public boolean isBlank(int i); /** play the next move. if isBlank(i) is not true, will throw TicTacToeIllegalMoveException. @param i number between 1 and 9 indicating square, organized like a telephone grid. If i is already occupied, a TicTacToeIllegalMoveException is thrown. @return winner 'X', 'O', or 'D' for draw, or ' ' for none yet. */ public char move(int i) throws TicTacToeIllegalMoveException; public String toString(); }
And here is another one, short and sweet:
public interface MessageDestination { /** Get this string to the user @param msg String to send to the user */ public void append(String msg); }
But before we can make sense of these, and see where they are useful, let's first see what the programs we're writing this week are all about.
Part 2: A preview of what we're doing: Three different TicTacToe programs
In lecture a while back, we started talking about developing a TicTacToe program. Your instructor finished off that program, and wrote three user interfaces, just like we discussed in that lecture:
User interface 1: text/console based
Here's what a tic-tac-toe game looks like on the console interface:
-bash-4.1$ java -cp build edu.ucsb.cs56.S11.pconrad.lab07.TextTicTacToe | | 1|2|3 --+-+-- --+-+-- | | 4|5|6 --+-+-- --+-+-- | | 7|8|9 X's move: 5 | | 1|2|3 --+-+-- --+-+-- |X| 4|5|6 --+-+-- --+-+-- | | 7|8|9 O's move: 9 | | 1|2|3 --+-+-- --+-+-- |X| 4|5|6 --+-+-- --+-+-- | |O 7|8|9 X's move: 3 | |X 1|2|3 --+-+-- --+-+-- |X| 4|5|6 --+-+-- --+-+-- | |O 7|8|9 O's move: 7 | |X 1|2|3 --+-+-- --+-+-- |X| 4|5|6 --+-+-- --+-+-- O| |O 7|8|9 X's move: 8 | |X 1|2|3 --+-+-- --+-+-- |X| 4|5|6 --+-+-- --+-+-- O|X|O 7|8|9 O's move: 4 | |X 1|2|3 --+-+-- --+-+-- O|X| 4|5|6 --+-+-- --+-+-- O|X|O 7|8|9 X's move: 2 |X|X 1|2|3 --+-+-- --+-+-- O|X| 4|5|6 --+-+-- --+-+-- O|X|O 7|8|9 X wins! Goodbye! -bash-4.1$
TicTacToeGui01: Gui with messages on System.out.println()
The next user interface has message on System.out.println, but the users click in squares to mark their Xs and Os.
(This user interface uses the EventListener and Inner Class stuff from Chapter 12—but we'll come back to that later. Interfaces are up first.)
TicTacToeGui02: Gui with messages in a JTextArea
This GUI is similar, but instead of having the message on System.out (i.e. in a separate window, which is lame), everything is in the one window.
We use a JTextArea (as discussed on page 414 (On Campus Off Campus) and 415 in Chapter 13 of the text.)
How this relates to Java Interfaces: the TicTacToeGame Interface
As you'll see in the code, Java Interfaces make it possible for us to implement all three Tic Tac Toe user interfaces while reusing as much code as possible.
First: all three User Interfaces only need a small number of services from a TicTacToe game. They need:
- to know whose turn it is
- to see if a move a user wants to make is legal
- if so, they need to let the user make that move
- they need to be able to tell if someone has won the game.
And more or less, that's exactly what the methods in the TicTacToeGame Interface provide:
-
public char getTurn()
tells us whose turn it is -
public boolean isBlank(int i)
tells us if square i is occupied or not -
public char move(int i)
makes a move and returns the winner (if any) or 'D' if there is a draw. -
public String toString()
just gives us a nice text representation of the board (useful for Text user interfaces, or for debugging)
Of course an Interface is of no use unless we have at least one actual class that implements the interface. In our code, that class is TicTacToeGrid.
Meanwhile the code that implements the text based user-interface (in TextTicTacToe.java) relies on a TicTacToeGrid object, which to provide the "game services" we listed above, so that the TextTicTacToe class can concentrate on what its job is, which is the input/output involved in interacting with the user.
Here, we see code to create a TicTacToeGrid() object—notice, though, that we store it in a variable of type TicTacToeGame. The point here is this: if we had some other object that implemented the TicTacToe interface, we could swap it out for TicTacToeGrid(), and the program would still compile—and, if that other object implemented the TicTacToeGame interface correctly, the program would still work also.
// TicTacToeGrid implements TicTacToeGame TicTacToeGame g = new TicTacToeGrid();
Inside the TextTicTacToe.java program, we use g
to access the methods of TicTacToeGrid, but only those that are part of the TicTacToeGame interface, as in this excerpt:
// line is the input from the user num = Integer.parseInt(line); if (g.isBlank(num)) { winner = g.move(num); done = (winner!=' '); }
How this relates to Java Interfaces: the MessageDestination Interface
Meanwhile, we use another interface, MessageDestination to enable us to share code between the two GUI versions of the program. Our GUI versions are built around a JComponent object defined in TicTacToeComponent.java that is simply a Swing representation of a TicTacToe board:
public class TicTacToeComponent extends JComponent { private TicTacToeGame game; private MessageDestination md; private JButton [] buttons = new JButton[10]; public TicTacToeComponent(TicTacToeGame game, MessageDestination md) { super(); this.game = game; // the TicTacToe game this.md = md; // a place we can write messages to ...
The MessageDestination object is simply a place to send any messages that need to be communicated to the user. Making this separate allows a user of this components to decide to send those messages to the console, or to a variety of different swing Widgets, or in a later version, to a web page, as needed.
The MessageDestination Interface only has one method:
public void append(String msg);
This week's code contains two objects that implement the MessageDestination interface:
(1) SystemOutMessageDestination is the one that we use in TicTacToeGui01.java—it just sends output to System.out.println. Here's the implementation—it doesn't get much simpler than this. Note that we don't need to write a constructor; we can just use the default constructor that the compiler provides for us.
public interface MessageDestination { /** Get this string to the user @param msg String to send to the user */ public void append(String msg); }
(2) JTextAreaMessageDestination on the other hand, allows us to send message to a JTextArea—in fact it is a JTextArea. That's right—we use inheritance to create a special JTextArea that implements the MesssageDestination interface, like this:
public class JTextAreaMessageDestination extends JTextArea implements MessageDestination { /** Create a JTextArea that implements the MessageDestination interface. This is a direct pass-thru to the JTextArea constructor. @param rows (see documentation for javax.swing.JTextArea) @param cols (see documentation for javax.swing.JTextArea) @see javax.swing.JTextArea */ public JTextAreaMessageDestination(int rows, int cols) { super(rows, cols); } // there is already a public void append(String msg); method in JTextArea // so that's all we have to do. }
(An aside about that super
keyword—this is a good time to check HFJ page 250 (On Campus Off Campus) to 257 if you aren't sure what that does.)
Now, you may be wondering: "Wait a minute—you said that if you implement an interface, you have to implement every method in the interface. So where is the append() method of the JTextAreaMessageDestination?"
Think about it a minute. Did you figure it out?
That's right—since JTextAreaMessageDestination "is a" JTextArea, it inherits all of the methods of JTextArea. And it so happens that JTextArea already has an append method with exactly the signature (function prototype) that we need! So, that works. In general: its ok if some (or all) of the methods needed to complete the interface contract come from the parent class, that still counts. The methods just have to available for objects of that class.
The MessageDestination object is used in the TicTacToeComponent class anytime we need to provide some feedback to the user. Here's are two excerpts of some code from TicTacToeComponent.java. This except checks if the square num
is already occupied, and if so, uses a MessageDestination
object (md
) to
let the user know.
if (!game.isBlank(num)) { md.append("That square is already occupied!\n"); return; }
The second is where we check for a winner, and let the user know if the game is over:
char winner=game.move(num); // check for a winner if (winner=='D') md.append("Phooey. It's a draw.\n"); else if (winner!=' ') md.append(winner + " wins!\n");
You could imagine implementing other MessageDestination objects—for example, one that in addition to providing the message makes a sound whenever there is a message, or one that puts the messages in a JTextField (overwriting the old text). At least I hope you can imagine it, because later in this lab, you'll have to do exactly that.
Interfaces arise in one other area of this lab: the ActionListener. So that will be our next topic. But first, here are some pages from the HFJ textbook you may want to review about Interfaces now that we've seen some code dealing with Interfaces:
- Review page 224 (On Campus Off Campus) to page 227 in HFJ to review Interfaces.
Part 3: Making Mouse Clicks work for Xs and Os: ActionListeners
Look at the code inside TicTacToeComponent.java, and look at the inner class ButtonListener. See that the actionPerformed method is overridden—and what is inside that method is exactly what we want to do each time the user clicks one of the buttons.
Note then how the buttons are created (in the constructor of the TicTacToeComponent.)
One of the cool things about inner classes is that they have direct access to the private instance variables of the class in which they are contained. Notice all of the ways in which we take advantage of that here.
Also, find the code that links up each of the buttons to an individual instance of the ButtonListener.
Step-by-Step through the lab
Step 1: Preliminaries
Start by making a copy of your lab06 directory called lab07.
Then make the adjustments necessary so that the package for this week's code is
edu.ucsb.cs56.S11.yourusername.lab07
instead of edu.ucsb.cs56.S11.yourusername.lab06
, and the project name is lab07 instead of lab06.
This includes, at least:
(1) fixing the bottom of the directory path under src
(2) Deleting all the code you have in src/edu/ucsb/cs56/S11/${USER}/lab07/*
and replace it with the files from:
/cs/faculty/pconrad/public_html/cs56/11S/labs/lab07/*.java
(Also online at http://www.cs.ucsb.edu/~pconrad/cs56/11S/labs/lab07/ )
(3) After you copy the code, go in and change all the package names from:
package edu.ucsb.cs56.S11.pconrad.lab07;
to
package edu.ucsb.cs56.S11.yourusername.lab07;
Tip
If you use emacs, there is a nice trick here for doing a search/replace across multiple files in the same directory. It's a little technical, but if you take the time to learn it, it will, in the long run save you a HUGE amount of time and effort when making changes like this one, where you have to make the same small change in a dozen files:
(4) Adjust the project property in the build.xml file from lab06 to lab07
(5) Add a new property:
<property name="fullPkg" value="edu.ucsb.cs56.S11.yourusername.${projectName}" />
Tip
Remember that here, we don't use${env.USER}but we really hard code your username, because your username is hardcoded in the Java files. If someone downloads your code and runs your build.xml file, it needs to still have your username for the package name.
(6) Change the mainClass property to TextTicTacToe, and add two other properties:
<property name="mainClass" value="TextTicTacToe" /> <property name="gui1MainClass" value="TicTacToeGui01" /> <property name="gui2MainClass" value="TicTacToeGui02" />
(7) Replace the run target with this code:
<target name="run" depends="compile" description="runs the class ${mainClass}"> <echo> To run the text user interface, type this at the command line: java -cp build ${fullPkg}.${mainClass} To run the gui user interfaces, type these commands: ant gui1 ant gui2 </echo> </target>
(8) Add two more targets for running our gui interfaces:
<target name="gui1" depends="compile" description="runs the class ${gui1MainClass}"> <java fork="true" classname="${fullPkg}.${gui1MainClass}" classpath="build" /> </target> <target name="gui2" depends="compile" description="runs the class ${gui2MainClass}"> <java fork="true" classname="${fullPkg}.${gui2MainClass}" classpath="build" /> </target>
At this point, you should be able to try running ant gui1 and ant gui2 and see the Tic Tac Toe board—although the code won't work yet, because some of the methods are only stubs.
Step 2: No open source this week; comment out the code that publishes the source
We are not publishing our source this week, since everyone is working on the same assignment.
But we want to keep the ant publish
target because we are going to use JWS (which only publishes the executable classes to the web.
So in our build.xml we want to disable ONLY the part of the publish target that copies the download files to the web. And, just in case we might want to bring it back in the future, instead of deleting it, we can comment it out.
To comment out something in an XML file, you can use this syntax
So, find this code in the publish target of your build.xml—its the code that invokes the copy
task to put your download files on the web in the download and browse directories:
<copy todir="${webRoot}/${projectName}/download" > <fileset dir="download"/> <fileset dir="dist" /> </copy> <copy file="build.xml" todir="${webRoot}/${projectName}/browse"/> <copy todir="${webRoot}/${projectName}/browse/src" > <fileset dir="src"/> </copy>
Put a <!--
at the start of your publish target, and a -->
at the end, and that should take care of it.
<!-- <copy todir="${webRoot}/${projectName}/download" > <fileset dir="download"/> <fileset dir="dist" /> </copy> <copy file="build.xml" todir="${webRoot}/${projectName}/browse"/> <copy todir="${webRoot}/${projectName}/browse/src" > <fileset dir="src"/> </copy> -->
Then, run ant publish and make sure that on the web there is a web page, but NO downloadable or browseable source code.
Then, go into the html/index.html file and do the same "commenting out" of the download and browse links, like this:
<!-- <li><a href="download">download</a></li> <li><a href="browse">browse</a></li> -->
Run ant publish
again and check for this.
Don't forget to do it—we'll be checking when this lab is graded.
Step 3: Working in TicTacToeGrid.java to get the JUnit tests in TicTacToeGridTest.java to pass
Your next challenge is entirely within the TicTacToeGrid.java file, and involves fixing just two stub methods:
public char nonBlankMatch(int i, int j, int k) { return '?'; // stub }
public boolean isBlank(int i) { return false; // STUB!!! }
You can read the javadoc for each of these methods as well as looking at the test cases to determine what the methods are supposed to do.
Keep in mind that there is something new in this lab—not only do we have traditional JUnit tests where the method must return the correct value to pass the test, such as:
@Test public void testNonBlankMatch01() { TicTacToeGrid g = new TicTacToeGrid("XXX"+ "O O"+ " OX"); assertEquals('X',g.nonBlankMatch(1,2,3)); }
We also have tests where to pass the test, the method must throw a particular exception:
@Test(expected=IllegalArgumentException.class) public void testNonBlankMatchIllegalArg01() { TicTacToeGrid g = new TicTacToeGrid("XXX"+ "O O"+ " OX"); char result = g.nonBlankMatch(1,1,1); }
So, here is a suggestion for how to proceed:
- First, run
ant test
and see which tests are failing. Note that some of these tests may not be direct tests ofnonBlankMatch
andisBlank
, but might actually be tests of other methods that depend onnonBlankMatch
andisBlank
being correct. - So next, look at the methods that are invoked by the failing tests, and the way in which those methods are using
nonBlankMatch
and/orisBlank
, and determine how they are expected to operate. Then try to write correct code for those methods. - Once they are functioning correctly for the regular cases of "reasonable parameter values", turn your attention to the exception cases, and make sure they throw the right exceptions in cases of bad parameter values.
When all the JUnit tests pass, you are ready to move to the next step.
Important Note!
When all the test pass, you should be able to play TicTacToe! Try:
ant run ant gui1 ant gui2
and make sure they all work. (If not, see if you can figure out what is wrong. If you can't ask for help.)
Step 4: Adding a Third Gui
Our next challenge is to add a third GUI interface. This one is similar to TicTacToeGui02, but instead of a JTextArea at the bottom, it will have two JLabels at the top:
- The first one will indicate one of the following three messages:
- X's turn
- O's turn
- Game over
- The second one will be used as the MessageDestination when we create the TicTacToeComponent (i.e. we need a new JLabel object that implements the MessageDestination interface.)
How to proceed:
(1) Reuse the same TicTacToeComponent.java.
We will make some small modifications to this component in a way that is backwards compatible so that TextTicTacToe.java, TicTacToeGui01.java and TicTacToeGui02.java don't need to be changed:
- We will add a second MessageDestination variable called mdTurn (private), initialized to null
- We will add another constructor that takes two MessageDestination parameters, md and mdTurn.
- (To clarify: that's two MessageDestination parameters in addition to the game parameter---two md's as opposed to just one. I hope that wasn't too confusing.)
- We will add code to the ButtonListener actionPerformed() method so that each time the turn changes, we do this:
if (mdTurn != null) { String turnMessage = "..."; // X's turn, O's turn or Game Over mdTurn.append(turnMessage); }
(The String turnMessage = "...";
obviously needs to be replaced with some code that actually sets the message appropriately.
(2) Create a class called JLabelMessageDestination that extends JLabel and implements MessageDestination. Unlike JTextArea, JLabel doesn't have an append method, so you'll need to implement one that passes its argument to the method of JLabel that changes the text of the label.
You also need to think about what parameters you may need to pass through to the constructor, if any, and implement those. If there are no parameters you need to pass through to a constructor, you won't necessarily need to write one (note that SystemOutMessageDestination doesn't have one.)
http://download.oracle.com/javase/6/docs/api/javax/swing/JLabel.html
(3) Copy TicTacToeGui02.java to TicTacToeGui03.java, and use it as your base.
(4) Before modifying any other code, just change the name of the class (and associated Javadoc comments) and add a gui3 target to your build.xml file that runs the TicTacToeGui03 class. (For full credit, be sure to adjust ALL of the places in the build.xml file that refer to gui1, gui2 to also make reference to gui3.)
Try running your ant gui3 task: you should see an exact copy of TicTacToeGui02, but renamed to TicTacToeGui03.
(5) Now make the needed changes to TicTacToeGui03.java.
You'll need to remove the code that creates the JTextArea (along with its scroller) and replace it with code that creates the two JLabels. Each of them needs to be both a JLabel and a MessageDestination. You'll pass both of those and the game variable into the new constructor that you implemented for the TicTacToeComponent.
Think about which layout manager you want to use. If needed, review the section on Layout Managers in Chapter 13 (On Campus Off Campus). There are a couple of different ones that will work, but the results are definitely more visually pleasing if you choose the appropriate one.
When the gui works properly, and you can play TicTacToe on it, you are ready to move to the next step.
Step 5: Set up TicTacToeGui2 and TicTacToeGui3 with Java Web Start
Refer back to the instructions from lab06 about how to implement Java Web Start, and using that as your guide, implement Java Web Start for TicTacToeGui2 and TicTacToeGui3.
- Make sure you have a jws target in your build.xml file
- Add a jws link in your html/index.html (if it isn't already there), and in your jws/index.html file, have links to bring up TicTacToeGui2 and TicTacToeGui3.
- Don't forget the other things you have to do (.jnlp files, .png file, .htaccess file, etc.)
When you can run the two GUIs with Java Web Start, you are finished with lab07 and ready to do the turnin step.
Step 6: Checking over your code
Be sure that all of your classes have javadoc comments with the names of both pair partners in all your source code files, and javadoc comments for each of the methods
Then, run ant -p
and make sure that you see descriptions of all of the following targets:
- compile
- javadoc
- clean
- jws
- test
- jar
- publish
- run
- gui1
- gui2
- gui3
Make sure, then, that each of these targets works properly.
Also, visit the URL that comes up when you do ant publish and make sure that the javadoc and jws files look ok, and work properly.
Make sure that the main-class in the manifest of your Jar is set to TextTicTacToe
Finally, review the rubric (see below) and make sure that everything indicated there is in good shape.
If so, then you are ready to submit.
Step 7: turnin
Before you run the turnin command, cd into your ~/cs56/lab07 directory (if you are not already there) and do the command:
ant clean
This will clear out your directory of everything except the essentials.
Then, cd up one level to your ~/cs56
directory and use the command:
turnin lab07@cs56 lab07
Then, after you do the turnin, do the ant javadoc step one more time just to sure the javadoc is there.
Step 8: Special instructions for those working in a pair
Also, if you are working in a pair, take the following important next step:
- The 2nd pair partner should download either the tarball or zip file from the website of the 1st pair partner
- 2nd pair partner should untar or unzip the file in his/her ~/cs56 directory, creating the same ~/cs56/lab07 set of files
- Then, do ant publish ALSO so that now BOTH pair partners have the lab07 files on the web under http://www.cs.ucsb.edu/~username/cs56/lab07/
The second partner does not need to also do the turnin step (as long as both names are in the file turned in by the first pair partner), but she/he DOES need to also take this extra step of putting the javadoc files on the web—otherwise, both pair partners may lose some points.
And for this lab, that's a wrap!
Grading Rubric
300 pts distributed as follows:
20 pts for basic mechanics
For full credit:
- There is a turnin of a directory called
lab07
with files/directories named correctly as follows:- build.xml file in the main lab07 directory
-
html
subdirectory containsindex.html
-
jws
subdirectory contains.jnlp
files as appropriate,index.html
,.htaccess
,cs56.png
-
src
subdirectory has a pathedu/ucsb/cs56/S11/yourusername/lab07
, in which the correct source files appear
Deductions: 5-10 points per defect, up to 20 points (at the discretion of the grader.)
40 pts for JWS
For full credit:
- the html/index.html subdirectory has a link to the jws subdirectory
- jws/index.html has links to .jnlp files for TicTacToeGui02 and TicTacToeGui03
-
TicTacToeGui02
andTicTacToeGui03
links correctly brings up the these two applications when clicked on from a JWS enabled browser with Java Platform SE 6 or higher installed.- It may not work on every browser on every machine, but if it works in CSIL/Cooper at least, we'll count that as a win. So its a good idea to test it there at least once.
- the comments/text in the .jnlp files are appropriate (i.e. stuff left over from lab06 or "your name here" stuff has been replaced with appropriate values)
Deductions:
- 40 points if neither program can be launched with JWS
- 20 points if one can be launched, but the other not.
- 5-10 points if both can be launched but there are minor defects in links or .jnlp entries.
50 pts for build.xml
For full credit:
- adding the descriptions so that ant -p works
- ant clean task is fixed and works properly
- the new properties are present (fullPkg, mainClass, gui1MainClass, gui2MainClass, gui3MainClass and the new targets have been set up properly and function correctly (ant run, ant gui1, ant gui2, ant gui3)
- the parts of the publish target that put source code on line are commented out
- the javadoc now links properly to Oracle's javadocs for standard Java Platform SE 6 library classes.
(Deduct 20 pts if any of the above is not done, then 10 points for each additional missing part up to 50 points total.)
40 pts for Documentation
For full credit:
- html/index.html file is on the web at http://www.cs.ucsb.edu/~username/cs56/lab07 for both pair partners and contains reasonable content and links that work
- the link to
download
code is commented out- Actually the link to
browse
should probably be commented out too, but we won't count off if you didn't do it.
- Actually the link to
- javadoc is on the web at http://www.cs.ucsb.edu/~username/cs56/lab07/javadoc for both pair partners and is of reasonable quality.
- Note that you should look through it—you'll probably find lots of "copy/paste" errors where the documentation doesn't make a whole lot of sense, and where you really should go back and fix some of the comments. (Some of those errors are in the code that I provided to you, but you should still fix them anyway.)
Deductions:
- Deductions of 5-10 points each for defects in documentation, up to 30 points.
- Deduction of 40 points if javadoc is completely missing
50 pts for Java Programming in TicTacToeGrid.java
For full credit:
- all JUnit tests pass
- implementation of isBlank() uses reasonable coding style
- implementation of nonBlankMatch() uses reasonable coding style
Deductions:
- -50 if not all JUnit tests pass (zero on entire lab if JUnit tests were modified without explicit permission)
- If all tests pass, then deductions of up to 5 points per function (10 total) for programming style, at discretion of the grader.
100 pts for Java Programming in TicTacToeGui03 and associated classes
For Full Credit:
- TicTacToeGui3 presents a GUI with two JLabels
- There is a new JLabelMessageDestination class that extends JLabel and implements MessageDestination.
- The two JLabels are created and added to the JFrame in TicTacToeGui3.java (not in TicTacToeComponent.java)
- The layout of the JLabels together with the TicTacToe board is reasonable.
- The turn label changes from "X's turn" to "O's turn" appropriately, and to "Game Over" when the game is finished.
- The other messages appear in the other JLabel
- It is ok if the message stay around (inappropriately) after each turn—
- It is possible to fix with a "trick", but fixing it "the right way" that would require changing the interface, and potentially breaking lots more code.
- We'll talk about how to address this "the right way" after Midterm 2 is done, and perhaps revisit the issue in a future lab.
Deductions:
- Deductions for missing functionality, and/or coding style are at the discretion of the grader.
Due Date
You may find it helpful to try to complete this lab assignment before your 2nd midterm next Tuesday. Completing the lab is one of the best ways you can study for this exam!
If that is not possible, then you should complete the assignment and execute the turnin command no later than 5pm Friday 05/29.
This gives you one full week to seek help during office hours from both the instructor and the TAs, plus one additional lab period to ask the TAs for additional help.
Submissions turned in after that time are subject to receiving zero credit.