Carleton University
Department of Systems and Computer Engineering
SYSC 1101 - Object-Oriented Software Development - Winter 2006

Lab 12

Attendance

To receive credit for attending this lab, you must email a jar file containing the project that you worked on during the lab session, by no later than 4:45 p.m., April 4, 2006. 

Before submitting your project, please review the Assignment and Lab Exercise Submission Instructions, which are posted on the course Web site.

Package your project in a jar file called lab12_abcdefghi.jar (where abcdefghi is your 9 digit Carleton student number). Use your Carleton Connect account or your Engsoc account to email this file to bailey@sce.carleton.ca. In the subject line, type:

SYSC 1101 Lab 12 yourfirstname yourlastname

Follow the above format exactly: a single space separating SYSC and 1101, a single space separating 1101 from the word Lab (with an uppercase L followed by 2 letters), etc.  Even if you don't finish the exercise before the end of the lab, make sure you email the jar file before the deadline; i.e., submit the project before 4:45 p.m. even if it is incomplete.

Objective

This lab is intended to provide you with some hands-on experience building a simple graphical user interface using classes from Java's AWT and Swing libraries.

Download the following files for the course Web site: NimGame.java, NimView.java, and NimModel.java. Create a new BlueJ project called nim-gui, and add the classes from these three files to the project. Use the editor to look at the source code for the three classes.

NimModel should be familiar to you - you used an earlier version of this class at the start of term. The major change is that the class now extends Java's Observable class. Notice that the methods that change the number of sticks in the pile now invoke setChanged() and notifyObservers(), both of which are inherited from Observable (more about this later). Also, instances of this class now throw exceptions. During this lab, you should not have to make any changes to NimModel.

NimGame is responsible for setting up the game and displaying the user interface. During this lab, you should not have to make any changes to NimGame.

NimView is the class that represents the view (the components that appear on the screen). It also has a nested class, NimController, that contains the controller methods (the methods that respond to button clicks, etc.) You will be making several changes to this class.

  1. Compile the project. Create an instance of NimGame and invoke it's play() method. You may have to move or shrink some windows in order to see the dialog boxes that are displayed as the game starts up. Clearly, some work needs to be done to finish the game.
  2. Read the code in NimView()that creates the JButton, takeOneButton, and adds it to the JPanel, buttonPanel. Create three more JButton objects, store the references in fields takeTwoButton, takeThreeButton, and resetButton - notice that the fields have already been declared - and add these buttons to buttonPanel. The labels on the three buttons should be "Take 2", "Take 3", and "New Game", respectively. Compile and run the project, and verify that four buttons appear in the GUI.
  3. The actionPerformed() method in class TakeOneButtonListener is currently empty. Edit the method so that it outputs "Take 1 button pressed" to the console. Compile and run the project, and verify that console output appears when you press the "Take 1" button. Try pressing the other buttons - nothing should happen.
  4. No actions happen when buttons other than the "Take 1" button are pressed because (1) listener objects for those buttons have not been created and registered with the buttons, and (2) the actionPerformed() methods for those objects have not been written. Read the code in NimController() that creates an instance of TakeOneButtonListener and registers that object as the listener for takeOneButton. Write code that creates one instance each of TakeTwoButtonListener, TakeThreeButtonListener, and ResetButtonListener. Register each of these listener objects with the associated button.
  5. Implement the actionPerformed() methods in the TakeTwoButtonListener, TakeThreeButtonListener, and ResetButtonListener classes. These methods should print the strings "Take 2 button pressed", "Take 3 button pressed", and "New Game button pressed" on the console. Compile and run the project, and verify that console output appears when you click all 4 buttons.
  6. Change the actionPerformed() methods so that, instead of invoking System.out.println(), it will now invoke the appropriate method in NimModel. Notice that the NimController constructor initializes field model with a reference to the NimModel object. For example, press the "Take 1" button will cause 1 stick to be removed from the pile. Compile the project. Because the view doesn't get updated as the model changes (that's next!), the appearance of the GUI won't change when you click the buttons.
  7. Notice that NimView implements the Observable interface. Observable has an abstract method called update(). An incomplete implementation of update() is defined in NimView. Whenever a method in NimModel invokes notifyObservers()update() is invoked. (update() is never called directly.) Notice how update() invokes model.sticksRemaining() to determine how many sticks are in the pile.
  1. The game still has a flaw - it is possible to remove more sticks than there are in the pile. JButton provides a setEnabled() method that has a single boolean argument, which determines if the button is enabled (can be clicked) or disabled (clicking has no effect). Add code to the statement if (sticks >= 3) so that:
        Compile and run the project, and verify that the buttons are enabled and disabled correctly.
Version 1.00, April 4, 2006