Backing Beans

A Sample Application

After all these rather abstract rules and regulations, it is time for a concrete example. The application presents a series of quiz questions. Each question displays a sequence of numbers and asks the participant to guess the next number of the sequence.

For example, Figure 2-3 asks for the next number in the sequence

  3 1 4 1 5

Figure 2-3. The number quiz


You often find puzzles of this kind in tests that purport to measure intelligence. To solve the puzzle, you need to find the pattern. In this case, we have the first digits of .

Type in the next number in the sequence (9), and the score goes up by one.

Note

There is a Java-compatible mnemonic for the digits of : "Can I have a small container of coffee?" Count the letters in each word, and you get 3 1 4 1 5 9 2 6. See http://dir.yahoo.com/Science/Mathematics/Numerical_Analysis/Numbers/Specific_Numbers/Pi/Mnemonics/ for more elaborate memorization aids.


In this example, we place the quiz questions in the QuizBean class. Of course, in a real application, you would be more likely to store this information in a database. But the purpose of the example is to demonstrate how to use beans that have complex structure.

We start out with a ProblemBean class. A ProblemBean has two properties: solution, of type int, and sequence, of type ArrayList (see Listing 2-1).

Listing 2-1. numberquiz/src/java/com/corejsf/ProblemBean.java

  1. package com.corejsf;   2. import java.util.ArrayList;   3.   4. public class ProblemBean {   5.    private ArrayList<Integer> sequence;   6.    private int solution;   7.   8.    public ProblemBean() {}   9.  10.    public ProblemBean(int[] values, int solution) {  11.       sequence = new ArrayList<Integer>();  12.       for (int i = 0; i < values.length; i++)  13.          sequence.add(values[i]);  14.       this.solution = solution;  15.    }  16.  17.    // PROPERTY: sequence  18.    public ArrayList<Integer> getSequence() { return sequence; }  19.    public void setSequence(ArrayList<Integer> newValue) { sequence = newValue; }  20.  21.    // PROPERTY: solution  22.    public int getSolution() { return solution; }  23.    public void setSolution(int newValue) { solution = newValue; }  24. }

Next, we define a bean for the quiz with the following properties:

  • problems: a write-only property to set the quiz problems

  • score: a read-only property to get the current score

  • current: a read-only property to get the current quiz problem

  • answer: a property to get and set the answer that the user provides

The problems property is unused in this sample program we initialize the problem set in the QuizBean constructor. However, under "Chaining Bean Definitions" on page 61, you will see how to set up the problem set inside faces-config.xml, without having to write any code.

The current property is used to display the current problem. However, the value of the current property is a ProblemBean object, and we cannot directly display that object in a text field. We make a second property access to get the number sequence:

  <h:outputText value="#{quiz.current.sequence}"/>

The value of the sequence property is an ArrayList. When it is displayed, it is converted to a string by a call to the toString method. The result is a string of the form

  [3, 1, 4, 1, 5]

Finally, we do a bit of dirty work with the answer property. We tie the answer property to the input field:

  <h:inputText value="#{quiz.answer}"/>

When the input field is displayed, the getter is called, and we define the getAnswer method to return an empty string.

When the form is submitted, the setter is called with the value that the user typed into the input field. We define setAnswer to check the answer, update the score for a correct answer, and advance to the next problem.

  public void setAnswer(String newValue) {      try {         int answer = Integer.parseInt(newValue.trim());         if (getCurrent().getSolution() == answer) score++;         currentIndex = (currentIndex + 1) % problems.size();      }      catch (NumberFormatException ex) {      }   }

Strictly speaking, it is a bad idea to put code into a property setter that is unrelated to the task of setting the property. Updating the score and advancing to the next problem should really be contained in a handler for the button action. However, we have not yet discussed how to react to button actions, so we use the flexibility of the setter method to our advantage.

Another weakness of our sample application is that we have not yet covered how to stop at the end of the quiz. Instead, we just wrap around to the beginning, letting the user rack up a higher score. You will learn in the next chapter how to do a better job. Remember the point of this application is to show you how to configure and use beans.

Finally, note that we use message bundles for internationalization. Try switching your browser language to German, and the program will appear as in Figure 2-4.

Figure 2-4. Viel Spa mit dem Zahlenquiz!


This finishes our sample application. Figure 2-5 shows the directory structure. The remaining code is in Listings 2-2 through 2-6.Example 2-3

Figure 2-5. The directory structure of the number quiz example


Listing 2-2. numberquiz/web/index.jsp

  1. <html>   2.    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>   3.    <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>   4.   5.    <f:view>   6.       <head>   7.          <title><h:outputText value="#{msgs.title}"/></title>   8.       </head>   9.       <body>  10.          <h:form>  11.             <h3>  12.                <h:outputText value="#{msgs.heading}"/>  13.             </h3>  14.             <p>  15.                <h:outputFormat value="#{msgs.currentScore}">  16.                   <f:param value="#{quiz.score}"/>  17.                </h:outputFormat>  18.             </p>  19.             <p>  20.                <h:outputText value="#{msgs.guessNext}"/>  21.             </p>  22.             <p>  23.                <h:outputText value="#{quiz.current.sequence}"/>  24.             </p>  25.             <p>  26.                <h:outputText value="#{msgs.answer}"/>   27.                <h:inputText value="#{quiz.answer}"/></p>  28.             <p>  29.                <h:commandButton value="#{msgs.next}" action="next"/>  30.             </p>  31.          </h:form>  32.       </body>  33.    </f:view>  34. </html>     

Listing 2-3. numberquiz/src/java/com/corejsf/QuizBean.java

  1. package com.corejsf;   2. import java.util.ArrayList;   3.   4. public class QuizBean {   5.    private ArrayList<ProblemBean> problems = new ArrayList<ProblemBean>();   6.    private int currentIndex;   7.    private int score;   8.   9.    public QuizBean() {  10.       problems.add(  11.          new ProblemBean(new int[] { 3, 1, 4, 1, 5 }, 9)); // pi  12.       problems.add(  13.          new ProblemBean(new int[] { 1, 1, 2, 3, 5 }, 8)); // fibonacci  14.       problems.add(  15.          new ProblemBean(new int[] { 1, 4, 9, 16, 25 }, 36)); // squares  16.       problems.add(  17.          new ProblemBean(new int[] { 2, 3, 5, 7, 11 }, 13)); // primes  18.       problems.add(  19.          new ProblemBean(new int[] { 1, 2, 4, 8, 16 }, 32)); // powers of 2  20.    }  21.  22.    // PROPERTY: problems  23.    public void setProblems(ArrayList<ProblemBean> newValue) {   24.       problems = newValue;  25.       currentIndex = 0;  26.       score = 0;  27.    }  28.  29.    // PROPERTY: score  30.    public int getScore() { return score; }  31.  32.    // PROPERTY: current  33.    public ProblemBean getCurrent() {  34.       return problems.get(currentIndex);  35.    }  36.  37.    // PROPERTY: answer  38.    public String getAnswer() { return ""; }  39.    public void setAnswer(String newValue) {   40.       try {  41.          int answer = Integer.parseInt(newValue.trim());  42.          if (getCurrent().getSolution() == answer) score++;  43.          currentIndex = (currentIndex + 1) % problems.size();  44.       }  45.       catch (NumberFormatException ex) {  46.       }  47.    }  48. }     

Listing 2-4. numberquiz/web/WEB-INF/faces-config.xml

  1. <?xml version="1.0"?>   2. <faces-config xmlns="http://java.sun.com/xml/ns/javaee"   3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   4.    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    5.         http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"   6.    version="1.2">   7.    <application>   8.       <locale-config>   9.          <default-locale>en</default-locale>  10.          <supported-locale>de</supported-locale>  11.       </locale-config>  12.    </application>  13.  14.    <navigation-rule>  15.       <from-view-id>/index.jsp</from-view-id>  16.       <navigation-case>  17.          <from-outcome>next</from-outcome>  18.          <to-view-id>/index.jsp</to-view-id>  19.       </navigation-case>  20.    </navigation-rule>  21.  22.     <managed-bean>  23.        <managed-bean-name>quiz</managed-bean-name>  24.        <managed-bean-class>com.corejsf.QuizBean</managed-bean-class>  25.        <managed-bean-scope>session</managed-bean-scope>  26.     </managed-bean>  27.  28.     <application>  29.        <resource-bundle>  30.           <base-name>com.corejsf.messages</base-name>  31.           <var>msgs</var>  32.        </resource-bundle>  33.     </application>  34. </faces-config>     

Listing 2-5. numberquiz/src/java/com/corejsf/messages.properties

  1. title=NumberQuiz   2. heading=Have fun with NumberQuiz!   3. currentScore=Your current score is {0}.   4. guessNext=Guess the next number in the sequence!   5. answer=Your answer:   6. next=Next

Listing 2-6. numberquiz/src/java/com/corejsf/messsages_de.properties

  1. title=Zahlenquiz   2. heading=Viel Spa\u00df mit dem Zahlenquiz!   3. currentScore=Sie haben {0,choice,0#0 Punkte|1#einen Punkt|2#{0} Punkte}.   4. guessNext=Raten Sie die n\u00e4chste Zahl in der Folge!   5. answer=Ihre Antwort:   6. next=Weiter



Core JavaServerT Faces
Core JavaServer(TM) Faces (2nd Edition)
ISBN: 0131738860
EAN: 2147483647
Year: 2004
Pages: 84

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net