[webbeans-commits] Webbeans SVN: r2513 - doc/trunk/reference/en-US.

webbeans-commits at lists.jboss.org webbeans-commits at lists.jboss.org
Sun Apr 19 05:55:51 EDT 2009


Author: peteroyle
Date: 2009-04-19 05:55:50 -0400 (Sun, 19 Apr 2009)
New Revision: 2513

Modified:
   doc/trunk/reference/en-US/environments.xml
Log:
added documentation for Swing Number Guess SE example

Modified: doc/trunk/reference/en-US/environments.xml
===================================================================
--- doc/trunk/reference/en-US/environments.xml	2009-04-19 09:50:29 UTC (rev 2512)
+++ doc/trunk/reference/en-US/environments.xml	2009-04-19 09:55:50 UTC (rev 2513)
@@ -276,12 +276,399 @@
                 <literal>StartMain</literal>.
              </para>
           </note>
-          
-          
 
       </section>
 
+      <section>
+            <title>Swing Example: Number Guess</title>
 
+            <para>Here's an example of a Swing application, Number Guess, similar to the example in
+              chapter 3.4. In the Number Guess application you get given 10 attempts
+                to guess a number between 1 and 100. After each attempt,
+                you will be told whether you are too high, or too low. This example can be found in the
+                <literal>examples/se/numberguess</literal> folder of the Web Beans distribution.
+            </para>
+
+            <para>There is an empty <literal>beans.xml</literal> file in the root package
+              (<literal>src/main/resources/beans.xml</literal>), which marks this application as a Web Beans
+              application.
+            </para>
+
+            <para>The game's main logic is located in <literal>Game.java</literal>. Here is the code for
+            that class, excluding that which is identical to the JSF version: </para>
+
+          <programlistingco>
+                <areaspec>
+                    <area id="scope" coords="1" />
+                    <area id="name" coords="1" />
+                    <area id="messages" coords="26" />
+                    <area id="validation" coords="39" />
+                    <area id="reset" coords="68" />
+                </areaspec>
+           <programlisting role="JAVA"><![CDATA[@ApplicationScoped
+public class Game implements Serializable
+{
+
+    private int number;
+    private int guess;
+    private int smallest;
+
+    @MaxNumber
+    private int maxNumber;
+
+    private int biggest;
+    private int remainingGuesses;
+    private boolean validNumberRange = true;
+
+    @Current Generator rndGenerator;
+
+    ...
+
+    public boolean isValidNumberRange()
+    {
+        return validNumberRange;
+    }
+
+    public boolean isGameWon()
+    {
+        return guess == number;
+    }
+
+    public boolean isGameLost()
+    {
+        return guess != number && remainingGuesses <= 0;
+    }
+
+    public boolean check()
+    {
+        boolean result = false;
+
+        if ( checkNewNumberRangeIsValid() )
+        {
+            if ( guess > number )
+            {
+                biggest = guess - 1;
+            }
+
+            if ( guess < number )
+            {
+                smallest = guess + 1;
+            }
+
+            if ( guess == number )
+            {
+                result = true;
+            }
+
+            remainingGuesses--;
+        }
+
+        return result;
+    }
+
+    private boolean checkNewNumberRangeIsValid()
+    {
+        return validNumberRange = ( ( guess >= smallest ) && ( guess <= biggest ) );
+    }
+
+    @PostConstruct
+    public void reset()
+    {
+        this.smallest = 0;
+        ...
+        this.number = rndGenerator.next();
+    }
+}]]></programlisting>
+            <calloutlist>
+                <callout arearefs="scope">
+                    <para>
+                              The bean is application scoped instead of session scoped, since an instance of the
+                              application represents a single 'session'.
+                    </para>
+                </callout>
+                <callout arearefs="name">
+                    <para>
+                              The bean is not named, since it doesn't need to be accessed via EL
+                    </para>
+                </callout>
+                <callout arearefs="messages">
+                    <para>There is no JSF <literal>FacesContext</literal> to add messages to. Instead the <literal>Game</literal> class provides
+                                       additional information about the state  of the current game including:
+                    </para>
+
+
+                    <itemizedlist>
+                        <listitem>
+                            <para>If the game has been won or lost</para>
+                        </listitem>
+                        <listitem>
+                            <para>If the most recent guess was invalid</para>
+                        </listitem>
+                    </itemizedlist>
+
+                    <para>This allows the Swing UI to query the state of the game, which it does
+                                   indirectly via a class called <literal>MessageGenerator,</literal> in order to determine the appropriate
+                                   messages to display to the user during the game.
+                    </para>
+                </callout>
+                <callout arearefs="validation">
+                    <para>
+                              Validation of user input is performed during the <literal>check()</literal> method, since there is
+                              no dedicated validation phase
+                    </para>
+                </callout>
+                <callout arearefs="reset">
+                    <para>
+                              The <literal>reset()</literal> method makes a call to the injected <literal>rndGenerator</literal> in order to get the
+                               random number at the start of each game. It cannot use
+                               <literal>manager.getInstanceByType(Integer.class, new AnnotationLiteral&lt;Random&gt;(){})</literal>
+                               as the JSF example does because there will not be any active contexts like
+                               there is during a JSF request.
+                    </para>
+                </callout>
+            </calloutlist>
+       </programlistingco>
+
+       <para>The <literal>MessageGenerator</literal> class depends on the current instance of <literal>Game</literal>, and queries
+                its state in order to determine the appropriate messages to provide as the
+                prompt for the user's next guess and the response to the previous guess.
+                The code for <literal>MessageGenerator</literal> is as follows:
+       </para>
+
+          <programlistingco>
+                <areaspec>
+                    <area id="game" coords="3" />
+                    <area id="challenge" coords="5" />
+                    <area id="result" coords="16" />
+                </areaspec>
+           <programlisting role="JAVA"><![CDATA[public class MessageGenerator
+{
+    @Current Game game;
+
+    public String getChallengeMessage()
+    {
+        StringBuilder challengeMsg = new StringBuilder( "I'm thinking of a number between " );
+        challengeMsg.append( game.getSmallest() );
+        challengeMsg.append( " and " );
+        challengeMsg.append( game.getBiggest() );
+        challengeMsg.append( ". Can you guess what it is?" );
+
+        return challengeMsg.toString();
+    }
+
+    public String getResultMessage()
+    {
+        if ( game.isGameWon() )
+        {
+            return "You guess it! The number was " + game.getNumber();
+        } else if ( game.isGameLost() )
+        {
+            return "You are fail! The number was " + game.getNumber();
+        } else if ( ! game.isValidNumberRange() )
+        {
+            return "Invalid number range!";
+        } else if ( game.getRemainingGuesses() == Game.MAX_NUM_GUESSES )
+        {
+            return "What is your first guess?";
+        } else
+        {
+            String direction = null;
+
+            if ( game.getGuess() < game.getNumber() )
+            {
+                direction = "Higher";
+            } else
+            {
+                direction = "Lower";
+            }
+
+            return direction + "! You have " + game.getRemainingGuesses() + " guesses left.";
+        }
+    }
+}]]></programlisting>
+            <calloutlist>
+                <callout arearefs="game">
+                    <para>
+                              The instance of <literal>Game</literal> for the application is injected here.
+                    </para>
+                </callout>
+                <callout arearefs="challenge">
+                    <para>
+                              The <literal>Game</literal>'s state is interrogated to determine the appropriate
+                              challenge message.
+                    </para>
+                </callout>
+                <callout arearefs="result">
+                    <para>
+                              And again to determine whether to congratulate, console or
+                              encourage the user to continue.
+                    </para>
+                </callout>
+            </calloutlist>
+       </programlistingco>
+
+       <para>Finally we come to the <literal>NumberGuessFrame</literal> class which provides the Swing
+       front end to our guessing game. </para>
+
+         <programlistingco>
+                <areaspec>
+                    <area id="gameIn" coords="3" />
+                    <area id="messagesIn" coords="4" />
+                    <area id="start" coords="6" />
+                    <area id="init" coords="18" />
+                    <area id="guess" coords="34" />
+                    <area id="replay" coords="44" />
+                    <area id="refresh" coords="50" />
+                </areaspec>
+           <programlisting role="JAVA"><![CDATA[public class NumberGuessFrame  extends javax.swing.JFrame
+{
+    private @Current Game game;
+    private @Current MessageGenerator msgGenerator;
+
+    public void start( @Observes @Deployed Manager manager )
+    {
+        java.awt.EventQueue.invokeLater( new Runnable()
+            {
+                public void run()
+                {
+                    initComponents();
+                    setVisible( true );
+                }
+            } );
+    }
+
+    private void initComponents() {
+
+        buttonPanel = new javax.swing.JPanel();
+        mainMsgPanel = new javax.swing.JPanel();
+        mainLabel = new javax.swing.JLabel();
+        messageLabel = new javax.swing.JLabel();
+        guessText = new javax.swing.JTextField();
+        ...
+        mainLabel.setText(msgGenerator.getChallengeMessage());
+        mainMsgPanel.add(mainLabel);
+
+        messageLabel.setText(msgGenerator.getResultMessage());
+        mainMsgPanel.add(messageLabel);
+        ...
+    }
+
+    private void guessButtonActionPerformed( java.awt.event.ActionEvent evt )
+    {
+        int guess =  Integer.parseInt(guessText.getText());
+
+        game.setGuess( guess );
+        game.check();
+        refreshUI();
+
+    }
+
+    private void replayBtnActionPerformed( java.awt.event.ActionEvent evt )
+    {
+       game.reset();
+       refreshUI();
+    }
+
+    private void refreshUI()
+    {
+        mainLabel.setText( msgGenerator.getChallengeMessage() );
+        messageLabel.setText( msgGenerator.getResultMessage() );
+        guessText.setText( "" );
+        guessesLeftBar.setValue( game.getRemainingGuesses() );
+        guessText.requestFocus();
+    }
+
+    // swing components
+    private javax.swing.JPanel borderPanel;
+    ...
+    private javax.swing.JButton replayBtn;
+
+}]]></programlisting>
+            <calloutlist>
+                <callout arearefs="gameIn">
+                    <para>
+                            The injected instance of the game (logic and state).
+                    </para>
+                </callout>
+                <callout arearefs="messagesIn">
+                    <para>
+                            The injected message generator for UI messages.
+                    </para>
+                </callout>
+                <callout arearefs="start">
+                    <para>
+                            This application is started in the usual Web Beans SE way, by observing the
+                            <literal>@Deployed Manager</literal> event.
+                    </para>
+                </callout>
+                <callout arearefs="init">
+                    <para>
+                            This method initialises all of the Swing components. Note the use
+                            of the <literal>msgGenerator</literal>.
+                    </para>
+                </callout>
+                <callout arearefs="guess">
+                    <para>
+                           <literal>guessButtonActionPerformed</literal> is called when the 'Guess' button is clicked, and
+                           it does the following:
+                    </para>
+
+                    <itemizedlist>
+                        <listitem>
+                            <para>Gets the guess entered by the user and sets it as the current guess in the <literal>Game</literal></para>
+                        </listitem>
+                        <listitem>
+                            <para>Calls <literal>game.check()</literal> to validate and perform one 'turn' of the game</para>
+                        </listitem>
+                        <listitem>
+                            <para> Calls <literal>refreshUI</literal>. If there were validation errors with the input, this
+                               will have been captured during <literal>game.check()</literal> and as such will be reflected
+                               in the messeges returned by <literal>MessageGenerator</literal> and subsequently presented
+                               to the user. If there are no validation errors then the user will be told
+                               to guess again (higher or lower) or that the game has ended either in a
+                               win (correct guess) or a loss (ran out of guesses).
+                            </para>
+                        </listitem>
+                    </itemizedlist>
+                </callout>
+                <callout arearefs="replay">
+                    <para>
+                            <literal>replayBtnActionPerformed</literal> simply calls <literal>game.reset()</literal> to start a new game
+                           and refreshes the messages in the UI.
+                    </para>
+                </callout>
+                <callout arearefs="refresh">
+                    <para>
+                        <literal>refreshUI</literal> uses the <literal>MessageGenerator</literal> to update the messages to the user based
+                            on the current state of the Game.
+                    </para>
+                </callout>
+            </calloutlist>
+       </programlistingco>
+
+       <para>
+           To run this example simply
+                <itemizedlist>
+                    <listitem>
+                        <para>Open a command line/terminal window in the
+                                    <literal>examples/se/numberguess</literal> directory</para>
+                    </listitem>
+                    <listitem>
+                        <para>Ensure that Maven 2 is installed and in your PATH</para>
+                    </listitem>
+                    <listitem>
+                        <para>Ensure that the <literal>JAVA_HOME</literal> environment variable is pointing to your JDK installation</para>
+                    </listitem>
+                    <listitem>
+                        <para>execute the following command</para>
+                    </listitem>
+                </itemizedlist>
+       </para>
+
+       <programlisting>mvn -Drun</programlisting>
+
+      </section>
+
    </section>
 
 </chapter>
\ No newline at end of file




More information about the weld-commits mailing list