CS 261 Lab B - Card Flipper
Due Wed Jan 29 at 9:00am
Overview
In this lab you will complete a simple application that displays a graphical deck of cards, and allows the user to select and "flip" over particular cards. This toy application will give you a chance to review working with Graphical User Interfaces (GUIs), event-driving programs, and graphical drawing. It will also provide the start of a helpful interface we can use later in the semester.
This lab will be completed in pairs. Remember to review the pair programming guidelines before you get started!
Objectives
- To review GUI and event-driven programming techniques
- To practice reading and searching Java documentation
- To practice integrating a simple ADT within a larger program
- To continue practicing with Eclipse
Necessary Files
You will need to download the copy of the zipped
source files.
and import them into Eclipse (see previous lab for instructions). These files contain a Card
class to use as the basis for a playing card, part of the public interface for a DrawableCard
class, and a DrawableDeck
class to organize all the cards, and a basic CardFrame
class to display the deck.
Note that this zipped folder also contains an "assets
" folder that contains an image file you will need; you should move this asset folder into your Eclipse project; you can drag it into the file structure, drag into Eclipse, or import it as a folder.
Details
There are a number of components you need to implement in order to complete this application. Complete and test one piece at a time, and be sure to switch drivers after each step!
DrawableCard
You will need to complete the implementation of the DrawableCard
class.
-
You should start by making the class extend the provided
Card
class, calling the parent class' methods as necessary. - Because DrawableCards can be drawn face up or face down, you will need to add functionality to track which way the card is facing. I have included some method signatures in the public interface--you will likely need to add an instance variable to store the attribute so that these methods make sense.
-
You should also add a
toString
method that reports the DrawableCard's rank and suit as well as whether it is facing up or down (this will be helpful for debugging). Can you re-use the a method in the parent class in some way? -
The most significant part of your
DrawableCard
class will be implementing thedraw()
method. This method should draw the card (whether face up or face down) on the providedGraphics2D
object.-
If the card is face up, you should simply draw it by drawing the face image that was passed into the constructor. You can easily draw an image on a graphics context by using the
drawImage(Image, int, int, ImageObserver)
method of the Graphics object. Note that the last parameter of this method (the "ImageObserver") can just benull
. -
If the card is face down, you will need to draw some design to for the "back" of the card. For example, in the above screenshot I draw the back as blue with a white diamond.
-
Feel free to get creative with this drawing, though don't get bogged down since there is a lot more to do. You should use the various drawing methods of the Graphics2D class, such as
fillRect()
,fillOval()
, etc. You can change the color of the paintbrush with thesetColor()
method, or the thickness of lines you draw withsetStroke()
. Explore the Java documentation for more ideas and examples! You will receive credit as long as you've produced some form of design for the card backs! - No matter what your design, you should draw a black box (using
drawRect()
) around the card to help it stand out from cards next to it. Note theWIDTH
andHEIGHT
constants that give the card's dimensions in pixels.
-
Feel free to get creative with this drawing, though don't get bogged down since there is a lot more to do. You should use the various drawing methods of the Graphics2D class, such as
- You might consider refactoring this method into two separate helper methods: one to draw the front, and one to draw the back.
-
If the card is face up, you should simply draw it by drawing the face image that was passed into the constructor. You can easily draw an image on a graphics context by using the
The CardFrame
You will also need to complete the the graphical window (CardFrame
, which extends JFrame
) to display your drawn deck and controls for it. Once you have your cards' drawing method implemented, your deck should show up in this frame. However, you will need to refactor some parts of this class in order to add user controls to the deck.
- Your frame will need to include 3 controls (in addition to the drawn deck): a "Flip Selected" button which flips the currently selected card, a "Reset" button that resets all the cards to be face up, and a slider (see below) that allows the user to select a card.
- You should use
Layout
classes (such asBorderLayout
andFlowLayout
) to organize your frame. Remember that you can specifying these layouts with thesetLayout()
method of a JFrame or JPanel. -
Your buttons should, when pressed, call the appropriate methods on the
DrawnDeck
object (e.g.,flipCard()
andreset()
). Remember that you will need to implementActionListener
in order to have your program respond to buttons.- You can figure which card index is selected by asking the slider; see below.
The Selecting Slider
In order to allow the user to select a card to flip, you'll use a GUI component you may not have seen before: the
JSlider
(see also 'How to use Sliders' for a tutorial and examples).
You will need to look at the JavaDoc for this class in order to determine how to use it!
- JSliders are fairly straightforward: you instantiate the object with some parameters (e.g., make it range from 0 to 51, representing the possible indicies to choose from). You will likely also want to turn on
setSnapToTicks()
, so that the slider jumps between indices, rather than sliding continuously. There are many further appearance-adjusting methods in the documentation, such as:setOrientation()
,setMajorTickSpacing()
,setPaintTicks()
andsetPaintLabels()
---you may not need to use these for this assignment, but it is good to be aware of them -
A JSlider uses a
ChangeListener
in order to have the program react to the slider being moved. This is a Listener (just like an ActionListener or MouseListener) that you will need to implement. Remember toaddChangeListener()
to the JSlider object! When aChangeEvent
occurs, you can take the opportunity to ask the slider for its current value using thegetValue()
method. Once you have this value, you can use it as an index to tell the deck to select a different card. Be sure and callrepaint()
after you select a new card so that the display gets updated! - You can also have your flip button get the position of the slider to determine which card to flip.
Figuring out the slider will involve reading the documentation; being able to browse and understand JavaDoc is an important skill to practice!
Testing and Debugging
- I recommend using print statements (with your implemented toString() method!) to track what is going on. Try printing out whether buttons are pressed or not, which cards are selected or flipped, etc.
- Be sure and test your program thoroughly to make sure it works! I should be able to select any card and flip it front to back (and vice versa), and reset the deck.
Extensions
If you finish early, you might consider adding the following as practice:
- Can you also enable the user to select a card using the mouse (e.g., with a MouseListener)? Selecting a card should also move the slider position over, to avoid conflicts between selections.
- Can you add a button that pops up a
JOptionPane
dialog and prompts the user for a range of indices, so that the user can flip multiple cards at once? - Can you add an animated "flip them all" method that flips one card after another? This can make a neat kind of "wave" effect.
- Can you add a "shuffle" button that shuffles the order of the cards? Maybe a move Button that lets you move a selected card to another index?
- Or just make it so the design on the back of your cards is really spiffy!
Submission
Make sure both your names are on all the classes you've modified (DrawableCard
and CardFrame
), and upload the entire project directory to the LabB submission folder on hedwig (see the previous lab if you need help). Only one partner needs to upload the code. Make sure you upload your work to the correct folder! The lab is due at the start of class the morning after lab.
After you have submitted your solution, log onto Moodle and submit the Lab B Partner Evaluation. Both partners need to submit evaluations.
Grading
This assignment will be graded on approximately the following criteria:
-
DrawableCard
extends Card and adds flipping capabilities and an updated toString() [15%] - Your
DrawableCard
can be drawn front and back [30%] - Your
CardFrame
includes working "flip" and "reset" buttons [10%] - Your
CardFrame
includes a selecting slider [25%] - Your
CardFrame
class lays out GUI elements appropriately [10%] - Your program has sufficient comments, with your names on the class files [5%]
- You completed your lab partner evaluation [5%]