August 12, 2020
Hot Topics:


  • By David Thurmond
  • Send Email »
  • More Articles »

So, how does defining the navigation rules help you? Remember your <h:commandButton> tag from showPuzzle.jsp:

<h:commandButton id="guess"

The key here is the action attribute. It specifies that a business logic function on the GameBean object called guessLetter() is to be invoked whenever the user clicks the Guess button. It is up to guessLetter() to return one of the outcomes listed in the navigation rules above. In this case, guessLetter() must return "guess_again" if the user still hasn't solved the puzzle and has guesses left. If the user solves the puzzle, "success" should be returned. If the user has guessed too many times, "game_over" should be returned.

This concept should be familiar to Struts developers, because the navigation framework for JSF is very similar. From this example, you can see how the flow of the application is controlled by the invokation of business logic methods, without those methods needing to be involved in the mechanics of directing the user to a JSP page.

You also define rules for youWin.jsp and youLose.jsp, so that the command links on those pages can navigate back to newGame.jsp. A complete listing of faces-config.xml is available here.

Writing the Business Logic

Now, examine the business logic behind the application. As you've seen from earlier code samples, the application will consist mainly of a GameBean object that will encapsulate the various functions and properties that the UI will need to invoke or access. To prevent a long discussion of the details of the GameBean's inner workings, the relevant methods and a description of their functions are shown in the following table. A complete listing of GameBean.java is available here for those inclined to look through it, but for the purposes of understanding how the GameBean interacts with JSF, the 10,000-foot view below should do.

Table 1: GameBean.java

Method Name Description
startGame() This method randomly selects a puzzle for the user to solve based on the difficulty level selected.
guessLetter() This method takes the user's input and either guesses a letter in the puzzle or guesses the puzzle. If the puzzle is solved, success is returned; if the letter is not in the puzzle, "guess_again" is returned, and if the user has guessed too many times, "game_over" is returned.
getPlayerName()/setPlayerName() Getter/setter methods for player name property
getDifficultyLevel()/setDifficultyLevel() Getter/setter methods for the puzzle difficulty level
getEasyDifficultyLevel(), getIntermediateDifficultyLevel(), getDifficultDifficultyLevel() Return the constants for the various possible difficulty levels.
getNumberOfGuesses() Returns the number of guesses so far.
getGuessedLetter()/setGuessedLetter() Getter/setter methods for the letter or puzzle answer theuser guesses.
getPuzzle() Returns the current text of the puzzle, including _ characters for unguessed letters.
getAnswer() Returns the answer to the puzzle.
getResourceBundle() Returns the resource bundle for all internationalized strings.

As you have already seen, startGame() and guessLetter() are invoked to control game play and manage navigation in the application. The various properties are displayed in the UI as either static text or part of internationalized strings. Now, all that's left is to tell JSF that the GameBean is available, what its scope is, and what its class name is. To do this, you must add an entry in faces-config, as shown below:

      The backing bean for the Hangman game application

Now, the application knows how to instantiate the GameBean and how to manage the bean. It is possible to define page-scope and application-scope beans as well. However, in this case, the GameBean is only needed as long as the player's session lasts, but must last longer than one page request to keep track of the state of the game, so session scope is used.

Page 5 of 8

This article was originally published on March 31, 2008

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.
