Title: Chapter 7 : Building a Textbased user interface.
1Chapter 7 Building a Text-based user interface.
2Objectives
- After studying this chapter you should understand
the following - independence of servers from clients
- likeliness of the user interface to change
- i/o streams
- structure of a simple text-based user interface
- purpose and structure of a while loop
- how existing classes can be composed to define a
new class.
3Objectives
- Also, you should be able to
- use input/output objects to read and write data
- build a simple text-based user interface
- use and trace a basic while statement
- define classes whose implementations contain
other classes as components.
4Relating User-interface and Model
- Model objects that solve problem at hand.
- User interface interacts with user, getting
input from user, and giving output to user,
reporting on status of model.
- Flexibility in design identifying these as
separate subsystems.
5Stream-based I/O
- Data streams sequence of bytes.
- character stream sequence of characters
- input stream stream is a source of data for an
application. - output stream stream is application destination
(or sink).
6Standard Input and Output streams
standard output
characters to display
7Writing standard output
- System.out provides methods for writing to
standard output.
public void println (String s) Write specified
String to standard output and then terminate the
line. public void print (String s) Write the
specified String to standard output. public void
println () Terminate current line by writing line
terminator to standard output. public void flush
() Flush stream write buffered output to
standard output and flush that stream.
8Input java.util.Scanner
- Scanner
- reads characters from a character input stream.
- Input stream specified when Scanner is created.
public Scanner (InputSource source) Create a
Scanner to read from specified source.
- Input source
- Assume characters are keyed from keyboard.
- Use System.in
9Input java.util.Scanner
- To create a Scanner reading from System.in
- import java.util.Scanner
Scanner input new Scanner(System.in) Create a
Scanner to read from specified source.
- Scanner
- Sees input as a sequence of tokens separated by
white space. - White space spaces, tabs, line terminators,
- Skips all white space before a token.
10Input java.util.Scanner
- Scanner
- Sees input as a sequence of tokens separated by
white space. - White space spaces, tabs, line terminators,
- If user keys in ( ? means space)
???23 ?? -34 ?? 5ab ???c??
token
token
token
token
11Input java.util.Scanner
- Given the data input stream
- Tokens can be read in using the methods
public String next() public boolean
nextBoolean() public int nextInt() public double
nextDouble()
12Input java.util.Scanner
- Need 4 invocations of next() to read whole line
- Invoking next() will return tokens as strings
String one input.next() // one contains
23 String two input.next() // two contains
-34 String three input.next() // three
contains 5ab String four input.next() //
four contains c?
- next() is a query returns a String token.
- next() is a command changes state of Scanner
13Input java.util.Scanner
- If there are no tokens in the input stream, it
will wait until user keys in a line with
non-blank characters. - An input stream can be closed with the command
close(). - If an input stream is closed or terminated
attempting to read it will fail.
14Input java.util.Scanner
- The methods
- nextBoolean()
- nextInt()
- nextDouble()
- Have preconditions token of form specified by
method used, otherwise fails. - To verify these preconditions use
- hasNextBoolean()
- hasNextInt()
- hasNextDouble()
15Input java.util.Scanner
- After reading some input tokens, you can skip the
rest of the input tokens in the current line with
the method
public String nextLine() advances past the
current line and returns any input that was
skipped excluding the line terminator.
16Building an interface for Rectangle
- Build an interface that lets user specify
dimensions of the Rectangle and ask for property
to be displayed.
class RectangleTUI A simple text-based interface
for Rectangles. public RectangleTUI () Create
a new RectangleTUI instance. public void start
() Run the interface.
17Building an interface for Rectangle
- Application creates interface and executes start
public class RectangleExample public static
void main (String argv) (new
RectangleTUI()).start()
18Building an interface for Rectangle
private Rectangle rectangle // the
model private Scanner in //standard input
- Instance variables are initialized in constructor
public RectangleTUI () this.rectangle
null this.in new Scanner(System.in)
19Building an interface for Rectangle
private void createRectangle () Create a new
Rectangle with user-provided dimensions. Uses
readIntWithPrompt to get dimensions from user.
- To get Rectangle dimensions from user
private int readIntWithPrompt (String prompt)
System.out.print(prompt) System.out.flush()
int input in.nextInt() in.nextLine() return
input
20Building an interface for Rectangle
- private void createRectangle ()
- int length
- int width
- length readIntWithPrompt( "Rectangle length
(a non-negative integer) ") - width readIntWithPrompt( "Rectangle width (a
non-negative integer) ") - this.rectangle new Rectangle(length,width)
-
21Building an interface for Rectangle
- RectangleTUI is a client of Rectangle.
- Constructor creates an instance of Rectangle
using input values from user. - But, Rectangle has pre-conditions to keep
public Rectangle (int length, int width) Create a
new Rectangle with specified length and
width. require length gt 0 width gt 0
- User may enter negative values for length or
width.
22While statement
while ( condition ) statement
23Re-implementing createRectangle
private void createRectangle () //initialize
to insure at least one execution of loops int
length -1 int width -1 while (length lt
0) length readIntWithPrompt( "Rectangle
length (a non-negative integer) ") while
(width lt 0) width readIntWithPrompt(
"Rectangle width (a non-negative integer) ")
// assert length gt0 width gt 0
this.rectangle new Rectangle(length,width)
24Building an interface for Rectangle
- private void displayMenu ()
- Display the menu to the user.
- private void executeChoice (int choice)
- Perform the indicated action, and display results
to the user.
25Building an interface for Rectangle
- Name operation choices with identifiers
private static final int LENGTH 1 private
static final int WIDTH 2 private static final
int AREA 3 private static final int PERIMETER
4 private static final int NEW 5 private
static final int EXIT 0 private static final
int NO_CHOICE -1
26Building an interface for Rectangle
- public void start ()
- createRectangle()
- int choice NO_CHOICE
- while (choice! EXIT)
- displayMenu()
- choice readIntWithPrompt("Enter choice ")
- executeChoice(choice)
-
27Building an interface for Rectangle
- private void displayMenu ()
- System.out.println()
- System.out.println("Enter number denoting action
to perform") - System.out.println("Display length............."
LENGTH) - System.out.println("Display width.............."
WIDTH) - System.out.println("Display area..............."
AREA) - System.out.println("Display perimeter.........."
PERIMETER) - System.out.println("Create new rectangle......."
NEW) - System.out.println("Exit......................."
EXIT)
28Building an interface for Rectangle
- private void executeChoice (int choice)
- System.out.println()
- if (choice LENGTH)
- System.out.println("Length is "
rectangle.length()) - else if (choice WIDTH)
- System.out.println("Width is "
rectangle.width()) - else if (choice AREA)
- System.out.println("Area is "
rectangle.area()) - else if (choice PERIMETER)
- System.out.println("Perimeter is "
rectangle.perimeter()) - else if (choice NEW)
- createRectangle()
- else if (choice EXIT)
- System.out.println("Goodbye.")
- else
- System.out.println(choice " is not valid.")
29Using composition
- Build an application that lets a user access a
locked oracle. - user can get a fortune from oracle only by
providing correct key. - Use classes CombinationLock and Oracle.
- Create two new classes,
- one modeling a locked oracle, and
- other defining user interface.
30Using composition
- public class Oracle
- A dispenser of fortunes. An Oracle gives a
fortune only if it is awake normal sequence of
actions is wake Oracle get fortune put the
Oracle back to sleep. - public Oracle () Create new Oracle. This
Oracle is initially asleep. ensure
!this.isAwake() - public boolean isAwake () This Oracle is
awake. - public String fortune ()
- The prophecy currently seen by this Oracle.
require this.isAwake() - public void awaken () Wake this Oracle.
Oracle will divine a fortune when it wakes. - public void sleep () Put this Oracle to sleep.
31Using composition
- public class LockedOracle
- A keyed dispenser of fortunes. A LockedOracle
will give a fortune only if the correct key is
provided. A LockedOracle must be told to conjure
a fortune before the fortune can be retrieved. - public static final String NO_FORTUNE
- String indicating no fortune has been conjured.
- public LockedOracle (int key)
- Create new LockedOracle with the specified
key.require 0 lt key key lt 999 - public String fortune ()
- The prophecy currently seen by this
LockedOracle. If a fortune has not been
conjured, the String NO_FORTUNE is returned. - public void conjureFortune (int keyToTry)
- Prophesy. This LockedOracle will make a prophecy
only if the correct key is presented.require 0
lt keyToTry keyToTry lt 999
32Using composition
- Composition process of defining a new class by
putting together existing classes. - An instance of the new class, the composite,
references instances of the existing classes, its
components.
33Implementing LockedOracle
- LockedOracle class defined to be a composite,
with CombinationLock and Oracle components.
34Implementing LockedOracle
private CombinationLock lock private Oracle
oracle private String fortune //current
prophesy public static final String NO_FORTUNE
"Sorry, no fortune for you."
- Instance variables are initialized in constructor
public LockedOracle (int key) lock new
CombinationLock(key) lock.close() oracle
new Oracle() fortune NO_FORTUNE
35Implementing LockedOracle
public String fortune () return this.fortune
- Command conjureFortune first attempts to open
lock, and wakes oracle only if it succeeds
public void conjureFortune (int keyToTry)
lock.open(keyToTry) if (lock.isOpen())
oracle.awaken() fortune
oracle.fortune() oracle.sleep() lock.close()
else fortune NO_FORTUNE
36Implementing the User interface
- class LockedOracleTUI
- A simple text-based interface for a LockedOracle.
- public LockedOracleTUI (LockedOracle oracle)
- Create a new interface for the specified
LockedOracle. - public void start ()
- Run the interface.
37Implementing the User interface
- Application creates an oracle and an interface,
and executes interfaces start method
public class OracleExample public static void
main (String argv) LockedOracle oracle
new LockedOracle(123) LockedOracleTUI ui
new LockedOracleTUI(oracle) ui.start()
38Implementing the User interface
- Instance variables and constructor.
private LockedOracle oracle private Scanner
in public LockedOracleTUI (LockedOracle oracle)
this.oracle oracle this.in new
Scanner(System.in)
39Implementing the User interface
- Specify private helper methods
private boolean readYes (String prompt) Read a
yes or no response from the user. Return true if
user keys yes. private int readKey (String
prompt) Read and return a legal key. ensure 0
lt this.readKey() this.readKey() lt 999
40Implementing the User interface
- public void start ()
- String fortune
- boolean goOn true
- while (goOn)
- goOn readYes("Fortune? (Key yes or no) ")
- if (goOn)
- int key readKey("Enter key (0-999) ")
- oracle.conjureFortune(key)
- fortune oracle.fortune()
- System.out.println(fortune)
- System.out.println()
-
-
- System.out.println("Good-bye.")
41Summary
- Built a simple text-based user interface.
- We reviewed the relationship between client and
server - a client is dependent on its server,
- a server is independent of its client.
42Summary
- In designing a system, it is preferable to make
stable components independent of those likely to
require change. - Since user interface is considerably less stable
than model, we favor designs in which the user
interface acts as client to the model. - In cases where model must collaborate with the
user interface, need to minimize interface for
this collaboration.
43Summary
- Introduced i/o streams.
- A stream is a sequence of bytes, sometimes viewed
as characters, to which an application can append
data (an output stream) or from which an
application can read data (an input stream). - Java has an extensive library of classes to deal
with streams. - Use only basic functionality
- from the predefined object System.out for output,
- Scanner class from java.util package for input.
44Summary
- Presented two simple applications with their
text-based user interfaces. - Introduced while statement or while-loop a Java
construct that specifies a sequence of actions to
be repeated until a condition fails to hold.
45Summary
- In design of LockedOracle composed existing
classes to construct a new class. - The relation between a composite class and its
component classes is called the has-a relation. - LockedOracle class wraps Oracle, adapting its
specification to that required by the system the
adapter pattern.