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

graphics/02fig03.jpg


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 p.

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

NOTE

graphics/note_icon.gif

There is a Java-compatible mnemonic for the digits of p: "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 faces-config.xml file. 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 configure 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/WEB-INF/classes/com/corejsf/ProblemBean.java
  1. package com.corejsf;  2. import java.util.ArrayList;  3.  4. public class ProblemBean {  5.    private ArrayList sequence;  6.    private int solution;  7.  8.    public ProblemBean() {}  9. 10.    public ProblemBean(int[] values, int solution) { 11.       sequence = new ArrayList(); 12.       for (int i = 0; i < values.length; i++) 13.          sequence.add(new Integer(values[i])); 14.       this.solution = solution; 15.    } 16. 17.    // PROPERTY: sequence 18.    public ArrayList getSequence() { return sequence; } 19.    public void setSequence(ArrayList 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, on page 59, 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, 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 haven't 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!

graphics/02fig04.jpg


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

Listing 2-2. numberquiz/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.       <f:loadBundle basename="com.corejsf.messages" var="msgs"/>  7.       <head>  8.          <title><h:outputText value="#{msgs.title}"/></title>  9.       </head> 10.      <body> 11.         <h:form> 12.            <h3> 13.               <h:outputText value="#{msgs.heading}"/> 14.            </h3> 15.            <p> 16.               <h:outputText value="#{msgs.currentScore}"/> 17.               <h:outputText value="#{quiz.score}"/> 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/WEB-INF/classes/com/corejsf/QuizBean.java
  1. package com.corejsf;  2. import java.util.ArrayList;  3.  4. public class QuizBean {  5.    private ArrayList problems = new ArrayList();  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 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 (ProblemBean) 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. quizbean/WEB-INF/faces-config.xml
  1. <?xml version="1.0"?>  2.  3. <!DOCTYPE faces-config PUBLIC  4.   "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"  5.   "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">  6.  7. <faces-config>  8.    <application>  9.       <locale-config> 10.          <default-locale>en</default-locale> 11.          <supported-locale>de</supported-locale> 12.       </locale-config> 13.    </application> 14. 15.    <navigation-rule> 16.       <from-view-id>/index.faces</from-view-id> 17.       <navigation-case> 18.          <from-outcome>next</from-outcome> 19.          <to-view-id>/index.faces</to-view-id> 20.       </navigation-case> 21.    </navigation-rule> 22. 23.    <managed-bean> 24.       <managed-bean-name>quiz</managed-bean-name> 25.       <managed-bean-class>com.corejsf.QuizBean</managed-bean-class> 26.       <managed-bean-scope>session</managed-bean-scope> 27.    </managed-bean> 28. </faces-config> 

Listing 2-5. quizbean/WEB-INF/classes/com/corejsf/messages.properties
 1. title=NumberQuiz 2. heading=Have fun with NumberQuiz! 3. currentScore=Your current score is: 4. guessNext=Guess the next number in the sequence! 5. answer=Your answer: 6. next=Next 

Listing 2-6. quizbean/WEB-INF/classes/com/corejsf/messsages_de.properties
 1. title=Zahlenquiz 2. heading=Viel Spa\u00df mit dem Zahlenquiz! 3. currentScore=Ihre Punktzahl: 4. guessNext=Raten Sie die n\u00e4chste Zahl in der Folge! 5. answer=Ihre Antwort: 6. next=Weiter 

Figure 2-5. The Directory Structure of the Number Quiz Example

graphics/02fig05.jpg




core JavaServer Faces
Core JavaServer Faces
ISBN: 0131463055
EAN: 2147483647
Year: 2003
Pages: 121

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