// ConsoleInput.java
// Copyright (c) 2000, 2005 Dorothy L. Nixon. All rights reserved.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
/**
* Contains static utility methods
* for simplifed text input and
* semi-automated program testing.
*
* @author D. Nixon
*/
public class ConsoleInput {
private static BufferedReader br =
new BufferedReader(
new InputStreamReader(System.in), 1);
private static boolean echoWanted;
/**
* Reads a line of text from command-line input.
* Input is echoed or not depending on value
* set by method <code>setEchoWanted</code>.
* (By default, input is not echoed, to avoid
* redundancy with normal echoing of command-line
* input.) Intended for use in all kinds of
* programs requiring command-line input.
*
* @exception RuntimeException if an IOException
* is thrown when reading the line.
*/
public static String readLine()
{
try {
String input = br.readLine();
if ( echoWanted )
System.out.println(input);
return input;
} catch (IOException ioe) {
throw new RuntimeException(ioe);
} // catch
} // method readLine()
/**
* Causes input to be echoed or not, depending on
* value of parameter. Should be true for redirected
* command-line input from a file, false for normal
* command line input, for which echoing would be redundant.
*
* @param wanted - If true, causes input
* to be echoed. If false, causes
* input not to be echoed.
*/
public static void setEchoWanted(boolean echoWanted)
{
ConsoleInput.echoWanted = echoWanted;
} // method setEchoWanted
/**
* Prompte user for input and returns
* one-line user reply.
*
* @param prompt the prompt, to which
* this method will append '>'
* @return the String typed by the user
* until pressing ENTER.
*/
public static String ask(String prompt)
{
System.out.print(prompt + ">");
return readLine();
} // method ask(String)
/**
* Pauses the command-line display, prompting the user
* to press ENTER to continue. Blank lines are printed
* before the prompt and after the user presses ENTER.
*/
public static void pause()
{
System.out.println();
System.out.print("Press ENTER to continue....");
readLine();
System.out.println();
} // method pause()
/**
* Prompts the user and ensures that the returned String
* is one of the specified options. Nags the user until
* a valid response is obtained. The initial prompt will
* consist of the specified question, followed by a
* parenthetical list of the options, followed by ">".
*
* @param question the main text of the prompt
* @param options array of permitted replies
*
* @return the user's reply, once the user enters
* a reply which contains the same sequence
* of characters (ignoring case for letters)
* as one of the specified options.
* @exception NullPointerException if no options are
* provided, or if no question is provided.
*/
public static String askSelection(String question,
String[] options)
{
if ( options == null || options.length == 0 ) {
throw new NullPointerException(
"No options provided for \"" +
question + "\"");
} else {
String optionString = options[0];
for ( int i = 1; i < options.length; i++ )
optionString += ", " + options[i];
String initialPrompt = question + " (" +
optionString + ")";
String nagPrompt = "Please enter one of: {" +
optionString + "}";
String answer = ask(initialPrompt);
while ( !isOneOf(answer, options) )
answer = ask(nagPrompt);
return answer.toUpperCase();
} // else
} // askSelection
/**
* Tests whether the specified character is equal,
* ignoring case, to one of the specified options.
*
* @param toBeChecked the character to be tested.
* @param options a set of characters
* @return true if <code>toBeChecked</code> is
* equal, ignoring case, to one of the
* <code>options</code>, false otherwise.
*/
public static boolean isOneOf(char toBeChecked,
char[] options)
{
boolean oneOf = false;
for ( int i = 0; i < options.length && !oneOf; i++ )
if ( Character.toUpperCase(toBeChecked)
== Character.toUpperCase(options[i]) )
oneOf = true;
return oneOf;
} // method isOneOf(char, char[])
/**
* Tests whether the specified string is one of the
* specified options. Checks whether the string
* contains the same sequence of characters (ignoring
* case) as one of the specified options.
*
* @param toBeChecked the String to be tested
* @param options a set of Strings
* @return true if <code>toBeChecked</code>
* contains the same sequence of
* characters, ignoring case, as one of the
* <code>options</code>, false otherwise.
*/
public static boolean isOneOf(String toBeChecked,
String[] options)
{
boolean oneOf = false;
for ( int i = 0; i < options.length && !oneOf; i++ )
if ( toBeChecked.equalsIgnoreCase(options[i]) )
oneOf = true;
return oneOf;
} // method isOneOf(String, String[])
/**
* Prompts the user for a yes/no answer to the
* specified question. Nags the user until a valid
* valid response ("Y", "N", "y", or "n") is obtained.
*
* @param question the question for which a
* yes/no answer is desired.
* @return true if the user answers "Y" or "y".
* false if the user answers "N" or "n".
*/
public static boolean askYesNo(String question)
{
String[] options = {"Y", "N"};
String answer = askSelection(question, options);
return answer.equalsIgnoreCase("Y");
} // method askUserYesNo
} // class ConsoleInput