001: /*
002: * This file is part of the Echo Web Application Framework (hereinafter "Echo").
003: * Copyright (C) 2002-2005 NextApp, Inc.
004: *
005: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
006: *
007: * The contents of this file are subject to the Mozilla Public License Version
008: * 1.1 (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: * http://www.mozilla.org/MPL/
011: *
012: * Software distributed under the License is distributed on an "AS IS" basis,
013: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
014: * for the specific language governing rights and limitations under the
015: * License.
016: *
017: * Alternatively, the contents of this file may be used under the terms of
018: * either the GNU General Public License Version 2 or later (the "GPL"), or
019: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
020: * in which case the provisions of the GPL or the LGPL are applicable instead
021: * of those above. If you wish to allow use of your version of this file only
022: * under the terms of either the GPL or the LGPL, and not to allow others to
023: * use your version of this file under the terms of the MPL, indicate your
024: * decision by deleting the provisions above and replace them with the notice
025: * and other provisions required by the GPL or the LGPL. If you do not delete
026: * the provisions above, a recipient may use your version of this file under
027: * the terms of any one of the MPL, the GPL or the LGPL.
028: */
029:
030: package echo2tutorial.numberguess;
031:
032: import nextapp.echo2.app.ApplicationInstance;
033: import nextapp.echo2.app.Button;
034: import nextapp.echo2.app.Color;
035: import nextapp.echo2.app.ContentPane;
036: import nextapp.echo2.app.Extent;
037: import nextapp.echo2.app.Insets;
038: import nextapp.echo2.app.Label;
039: import nextapp.echo2.app.ResourceImageReference;
040: import nextapp.echo2.app.Column;
041: import nextapp.echo2.app.TextField;
042: import nextapp.echo2.app.Window;
043: import nextapp.echo2.app.event.ActionEvent;
044: import nextapp.echo2.app.event.ActionListener;
045: import nextapp.echo2.app.layout.ColumnLayoutData;
046:
047: /**
048: * Guess-a-number Tutorial Application.
049: */
050: public class NumberGuessApp extends ApplicationInstance {
051:
052: private Window window;
053:
054: /**
055: * Displays a congratulatory message to the user when s/he has guessed
056: * the correct number.
057: *
058: * @param numberOfTries the number of tries it took the user to guess the
059: * correct answer.
060: */
061: void congratulate(int numberOfTries) {
062: window.setContent(new CongratulationsPane(numberOfTries));
063: }
064:
065: /**
066: * @see nextapp.echo2.app.ApplicationInstance#init()
067: */
068: public Window init() {
069: window = new Window();
070: window.setTitle("Echo2 Guess-A-Number");
071: startNewGame();
072: return window;
073: }
074:
075: /**
076: * Starts a new game:
077: * Sets content of Window to a new <code>GamePane</code>.
078: */
079: void startNewGame() {
080: // Set the content to be a new GamePane, so the
081: window.setContent(new GamePane());
082: }
083: }
084:
085: /**
086: * A <code>ContentPane</code> which generates a random number and provides the
087: * user opportunities to guess it.
088: */
089: class GamePane extends ContentPane implements ActionListener {
090:
091: /** Randomly generated number between 1 and 100 inclusive. */
092: private int randomNumber = ((int) Math.floor(Math.random() * 100)) + 1;
093:
094: /** The current lowest sensible guess, based on previous guesses. */
095: private int lowerBound = 1;
096:
097: /** The current highest sensible guess, based on previous guesses. */
098: private int upperBound = 100;
099:
100: /** The number of guesses made in the current game. */
101: private int numberOfTries = 0;
102:
103: /** <code>TextField</code> into which guesses are entered. */
104: private TextField guessEntryField;
105:
106: /**
107: * <code>Label</code> displaying the current "status". Initially blank,
108: * this label will inform the user whether his/her last guess was too
109: * high, too low, or simply invalid.
110: */
111: private Label statusLabel = new Label();
112:
113: /**
114: * <code>Label</code> indicating the total number of guesses made so far.
115: */
116: private Label countLabel = new Label("You have made no guesses.");
117:
118: /**
119: * <code>Label</code> prompting the user to enter a new guess. The text of
120: * this label will change as the user makes guesses to reflect the updated
121: * "sensible" range of possible guesses.
122: */
123: private Label promptLabel = new Label(
124: "Guess a number between 1 and 100: ");
125:
126: /**
127: * Creates a new <code>GamePane</code>.
128: */
129: GamePane() {
130: super ();
131:
132: Column layoutColumn = new Column();
133: layoutColumn.setInsets(new Insets(30));
134: layoutColumn.setCellSpacing(new Extent(10));
135: add(layoutColumn);
136:
137: layoutColumn.add(new Label(new ResourceImageReference(
138: "/echo2tutorial/numberguess/TitleBanner.png")));
139: layoutColumn.add(statusLabel);
140: layoutColumn.add(countLabel);
141: layoutColumn.add(promptLabel);
142:
143: guessEntryField = new TextField();
144:
145: guessEntryField.setForeground(Color.WHITE);
146: guessEntryField.setBackground(Color.BLUE);
147: ColumnLayoutData columnLayoutData = new ColumnLayoutData();
148: columnLayoutData.setInsets(new Insets(20, 0));
149: guessEntryField.setLayoutData(columnLayoutData);
150: layoutColumn.add(guessEntryField);
151:
152: Button submitButton = new Button("Submit Your Guess");
153: submitButton.setActionCommand("submit guess");
154: submitButton.setForeground(Color.BLACK);
155: submitButton.setBackground(Color.GREEN);
156: submitButton.setWidth(new Extent(200));
157: submitButton.addActionListener(this );
158: layoutColumn.add(submitButton);
159:
160: Button newGameButton = new Button("Start a New Game");
161: newGameButton.setActionCommand("new game");
162: newGameButton.setForeground(Color.WHITE);
163: newGameButton.setBackground(Color.RED);
164: newGameButton.setWidth(new Extent(200));
165: newGameButton.addActionListener(this );
166: layoutColumn.add(newGameButton);
167: }
168:
169: /**
170: * @see nextapp.echo2.app.event.ActionListener#actionPerformed(nextapp.echo2.app.event.ActionEvent)
171: */
172: public void actionPerformed(ActionEvent e) {
173: if (e.getActionCommand().equals("new game")) {
174: ((NumberGuessApp) ApplicationInstance.getActive())
175: .startNewGame();
176: } else if (e.getActionCommand().equals("submit guess")) {
177: processGuess();
178: }
179: }
180:
181: /**
182: * Processes a user's guess.
183: */
184: private void processGuess() {
185:
186: int guess;
187: try {
188: guess = Integer.parseInt(guessEntryField.getDocument()
189: .getText());
190: } catch (NumberFormatException ex) {
191: statusLabel.setText("Your guess was not valid.");
192: return;
193: }
194:
195: ++numberOfTries;
196:
197: if (guess == randomNumber) {
198: ((NumberGuessApp) ApplicationInstance.getActive())
199: .congratulate(numberOfTries);
200: return;
201: }
202:
203: if (guess < 1 || guess > 100) {
204: statusLabel.setText("Your guess, " + guess
205: + " was not between 1 and 100.");
206: } else if (guess < randomNumber) {
207: if (guess >= lowerBound) {
208: lowerBound = guess + 1;
209: }
210: statusLabel.setText("Your guess, " + guess
211: + " was too low. Try again:");
212: } else if (guess > randomNumber) {
213: statusLabel.setText("Your guess, " + guess
214: + " was too high. Try again:");
215: if (guess <= upperBound) {
216: upperBound = guess - 1;
217: }
218: }
219:
220: // Update number of tries label.
221: if (numberOfTries == 1) {
222: countLabel.setText("You have made 1 guess.");
223: } else {
224: countLabel.setText("You have made " + numberOfTries
225: + " guesses.");
226: }
227:
228: // Update the prompt label to reflect the new sensible range of numbers.
229: promptLabel.setText("Guess a number between " + lowerBound
230: + " and " + upperBound + ": ");
231: }
232: }
233:
234: /**
235: * A <code>ContentPane</code> which presents a congratulatory message to the
236: * player when the correct number has been guessed.
237: */
238: class CongratulationsPane extends ContentPane implements ActionListener {
239:
240: /**
241: * Creates a new <code>CongratulationsPane</code>.
242: *
243: * @param numberOfTries the number of tries it took the user to guess the
244: * correct answer.
245: */
246: CongratulationsPane(int numberOfTries) {
247: Column layoutColumn = new Column();
248: layoutColumn.setInsets(new Insets(30));
249: layoutColumn.setCellSpacing(new Extent(30));
250: add(layoutColumn);
251:
252: layoutColumn
253: .add(new Label(
254: new ResourceImageReference(
255: "/echo2tutorial/numberguess/CongratulationsBanner.png")));
256: layoutColumn.add(new Label("You got the correct answer in "
257: + numberOfTries
258: + (numberOfTries == 1 ? " try." : " tries.")));
259:
260: Button button = new Button("Play Again");
261: button.setForeground(Color.WHITE);
262: button.setBackground(Color.RED);
263: button.setWidth(new Extent(200));
264: button.addActionListener(this );
265: layoutColumn.add(button);
266: }
267:
268: /**
269: * @see nextapp.echo2.app.event.ActionListener#actionPerformed(nextapp.echo2.app.event.ActionEvent)
270: */
271: public void actionPerformed(ActionEvent e) {
272: ((NumberGuessApp) ApplicationInstance.getActive())
273: .startNewGame();
274: }
275: }
|