The Guess Page

This is the page where uses make letter guesses. The page has four sections:

Let's start with the HTML template this time:

Figure 7.9. Guess.html (excerpt)

<h1>Make a Guess</h1>

<font size=+3>
  <jwc id="insertGuess"/>
</font>

<p>

You have made <jwc id="insertMissed"/> bad guesses,
out of a maximum of <jwc id="insertMaxMisses"/>.

<jwc id="ifError">
<p>
<font size=+3 color=red><jwc id="insertError"/></font>
</jwc>

<p>Guess:
<font size=+1>
<jwc id="e">
<jwc id="guess"><jwc id="insertLetter"/></jwc>
</jwc>
</font>

<p><jwc id="giveUp">Give up?</jwc>

Most of these components should be fairly obvious by now; let's focus on the components that allow the user to guess a letter. This could have been implemented in a number of ways using more radio buttons, a drop down list or a text field the user could type into. In this example, we chose to simply create a series of links, one for each letter the user may still guess.

Let's look at the specification for those three components (e, guess and insertLetter).

Figure 7.10. Guess.jwc (excerpt)

<component id="e" type="Foreach">
  <binding name="source" property-path="unused"/>
</component>

<component id="guess" type="Direct">
  <binding name="listener" property-path="guessListener"/>
  <binding name="context" property-path="components.e.value"/>
</component>

<component id="insertLetter" type="Insert">
  <binding name="value" property-path="components.e.value"/>
</component>

Component e is simply a Foreach, the source is the unused property of the page (we'll see in a moment how the page gets this list of unused letters from the game object).

Component insertLetter inserts the current letter from the list of unused letters. It gets this current letter directly from the e component. On successive iterations, a Foreach component's value property is the value for the iteration.

Component guess is type Direct, which creates a hyperlink on the page and notifies its listener when the user clicks the link. Just knowing that the component was clicked isn't very helpful though; the application needs to know which letter was actually clicked.

Passing that kind of information along is accomplished by setting the context parameter for the component. The context parameter is a String, or array of Strings, that will be encoded into the URL for the hyperlink. When the component's listener is notified, it is passed the same Strings.

The context is often used to encode primary keys of objects, names of columns or other information specific to the application.

In this case, the context is simply the letter to be guessed.

All of this comes together in the Java code for the Guess page.

Figure 7.11. Guess.java (excerpt)

public IDirectListener getGuessListener()
{
  return new IDirectListener()
  {
    public void directTriggered(IDirect direct,
                String[] context, IRequestCycle cycle)
    throws RequestCycleException
    {
      makeGuess(context[0], cycle);
    }
  };
}

private void makeGuess(String guess, IRequestCycle cycle)
throws RequestCycleException
{
  HangmanGame game = getGame();
  char letter = guess.charAt(0);

  try
  {
    game.guess(letter);
  }
  catch (GameException ex)
  {
    error = ex.getMessage();

    if (game.getFailed())
    cycle.setPage("Failed");

    return;
  }

  // A good guess.

  if (game.getDone())
    cycle.setPage("Success");
  }
}

So the listener for the guess component gets the first String in the context and invokes the makeGuess() method. We pass the guessed letter to the game object which throws a GameException if the guess is invalid.

The method HangmanGame.getFailed() returns true when all the missed guesses are used up, at which point we go to the Failed page to tell the user what the word was.

On the other hand, if an exception isn't thrown, then the guess was good. getDone() returns true if all letters have been guessed, in which go to the Success page.

If all letters weren't guessed, we stay on the Guess page, which will display the word with the guessed letter filled in, and with fewer options in the list of possible guesses.