Concepts / Text-Based Card Game with Deck, Hand, and Card Classes

Text-Based Card Game with Deck, Hand, and Card Classes

The main panel of the card game uses a BorderLayout, with the drawing surface in CENTER and the subpanel of three buttons in SOUTH.

  • Programming

Laying Out the Card Game Window

Imagine a card game where you look at one playing card and must guess whether the next card will be higher or lower in value. Aces count as the lowest card in this game. Three correct guesses win the round, and a single wrong guess ends it. The text-based version of this game only needed the console. A graphical version needs a window that shows the cards, displays a message to the player, and offers buttons for making predictions and starting a new game.

Building that window is a design problem before it is a coding problem. You have to decide what goes where, which object owns the drawing, and which object reacts when the player presses a button. This article works through those decisions in order, starting with the layout of the main window.

What do you think happens?

The main panel has a large area that shows the cards and a message, and a row of three buttons. Which region of the layout should the large area occupy?

Reveal answer
Answer:

CENTER

The drawing surface, which shows the cards and message, occupies the CENTER region. The subpanel holding the three buttons occupies SOUTH. Keep this pairing in mind, because the rest of the design builds on it.

Five Regions of a BorderLayout

The main panel of the card game is the container that holds everything else, and it uses a layout called BorderLayout to place its parts. A BorderLayout has five regions, named NORTH, SOUTH, EAST, WEST, and CENTER. You place a component into one of these regions, and the layout positions it accordingly.

Definition

BorderLayout: a layout that divides a container into five named regions, NORTH, SOUTH, EAST, WEST, and CENTER. Each region can hold one component, and any region you leave unused simply contributes no visible content.

Main panelHighLowGUI, a JPanelsubclassNORTHemptyThree buttonsinside the subpanelWESTemptyCENTERCardPanel drawing surfaceEASTemptySOUTHButton subpanelregionregionregionregionregioncontains
Which of the five BorderLayout regions hold components in the card game, and which are left empty? The CardPanel drawing surface goes in CENTER and the button subpanel goes in SOUTH.

Tracing the Window Layout

Worked example

Placing the Card Game Components

The main panel must hold a drawing surface that shows the cards and message, and a subpanel with three buttons. Decide which BorderLayout region each component goes into, and state what happens to the regions you do not use.

  1. 1
    Identify the large area

    The drawing surface shows the cards and the message. It is the largest visible part of the window, so it belongs in CENTER.

  2. 2
    Identify the button row

    The three buttons are grouped into a subpanel. A row of buttons along the bottom of the window fits the SOUTH region.

  3. 3
    Assign the components

    Put the drawing surface into CENTER and the button subpanel into SOUTH.

  4. 4
    Account for the remaining regions

    NORTH, EAST, and WEST receive no components. They contribute no visible content, which is why the design does not need anything in them.

Result

CENTER holds the CardPanel drawing surface, SOUTH holds the button subpanel, and NORTH, EAST, and WEST stay empty.

Why the Drawing Surface Is Its Own Class

The card game is built from two JPanel classes that play different roles. The outer panel is the class HighLowGUI, which is itself a subclass of JPanel. Its constructor creates the other components, sets up event handling, and lays out the components in the BorderLayout. The inner panel is a nested class named CardPanel, also a subclass of JPanel, and it is the drawing surface.

Definition

Custom JPanel subclass: a class that extends JPanel so that the panel carries extra behavior the standard JPanel does not provide. In this game, CardPanel is that subclass.

Why make the drawing surface a subclass instead of using ready-made components? The source explains that the cards and the message are not built from standard components. Instead, they are drawn with the graphics context inside the panel's paintComponent() method. A custom subclass is the natural home for that code, because the drawing logic belongs to the same object that is responsible for the display. Keeping the painting code inside CardPanel means the object that shows the cards also knows how to draw them.

HighLowGUImain panel, builds layoutButton subpanelthree buttons, SOUTHpaintComponent()draws cards and messageCardPaneldrawing surface, CENTERlays out in SOUTHlays out in CENTERbutton presses reach listenerdraws with
How do the main panel, the button subpanel, and the CardPanel drawing surface relate to each other, and which object is responsible for painting the cards?

Notice the split of responsibilities in the diagram. HighLowGUI arranges the window. The button subpanel groups the controls. CardPanel does the drawing, and it is also the object that listens for events from the buttons. The buttons do not paint anything themselves, and they do not decide what the game does next.

Tracing a Button Click

Event handling is the link between a user action and the code that responds to it. In this design the player clicks a button, and the event has to reach the object that knows what to do. The source states that the drawing surface listens for events from the three buttons. The buttons are therefore not the ones deciding the outcome. They only report that they were pressed.

  1. 1
    The player clicks one of the three buttons in the SOUTH subpanel.
  2. 2
    The button reports that it was pressed. It does not choose the result of the guess.
  3. 3
    The event reaches CardPanel, which is the object listening for events from the buttons.
  4. 4
    CardPanel handles the event, and the next state of the game is decided from there.
  5. 5
    The cards and message are shown again through the drawing code in paintComponent().
Playerclicks a buttonButtonreports the pressCardPanel listenerreceives the eventCards and messagedrawn in paintComponent()1. click2. reports press3. handled, display updated
When a player clicks a button, which objects receive the event in order, and which object handles it so the game can move on?

Mistakes When Designing the Card Window

  • Common mistake

    Believing the button decides the outcome of the guess

    What it looks like

    A learner assumes that clicking the higher button itself checks whether the next card is higher.

    Why it fails

    The source says the buttons only report that they were pressed. The drawing surface listens for those events and handles them.

    Do this instead

    Trace the click to the listening object, which is CardPanel, before deciding where the reaction happens.

  • Common mistake

    Putting the drawing code in the button subpanel

    What it looks like

    A learner paints the cards inside the class that builds the buttons.

    Why it fails

    The drawing logic belongs to the object responsible for the display. In this design, that object is the CardPanel drawing surface.

    Do this instead

    Place the cards and message drawing inside the CardPanel subclass, in its paintComponent() method.

  • Common mistake

    Filling every BorderLayout region

    What it looks like

    A learner feels the window looks incomplete and adds a component to NORTH, EAST, and WEST.

    Why it fails

    The design uses only CENTER and SOUTH. An unused region contributes no visible content and the design does not need a component there.

    Do this instead

    Leave unused regions empty unless the design calls for a component in them.

  • Common mistake

    Confusing the outer HighLowGUI panel with the inner CardPanel drawing surface

Practice: Trace a Click and Place a Component

MEDIUM

A teammate proposes adding a new status label that should appear along the top of the window above the drawing surface. Using only the design described in this article, decide which BorderLayout region the label should go into, then trace what happens when the player clicks one of the three buttons. Name each object the event passes through, and say which one reacts to it.

Hints
  • Think about which regions are already used and which are still empty.
  • The top of a window corresponds to one of the five named regions.
  • Remember that the buttons only report presses, and the listening object responds.

Key Takeaways

  • A BorderLayout divides a container into five regions named NORTH, SOUTH, EAST, WEST, and CENTER, and unused regions can stay empty.
  • The card game's main panel puts the CardPanel drawing surface in CENTER and the three-button subpanel in SOUTH.
  • CardPanel is a nested JPanel subclass because it carries the custom painting code in paintComponent() and the event listening for the buttons.
  • Button presses are reported by the buttons and handled by the listening drawing surface, so tracing a click means following the event to that object.