package MusicLandscape.util;
import java.util.Scanner;
import java.util.function.Function;
import java.util.function.Predicate;package MusicLandscape.util;
import java.util.Scanner;
import java.util.function.Function;
import java.util.function.Predicate;The process of asking the user for a single value. Optionally unskippable,
meaning we re-prompt the user in a while loop until they provide a valid
value.
This class is a generic class: it has a type parameter T, which
is used as the return type of the method scan().
/**
* Generic console function for getting a new value for an entity field from the user.
*
* <p>
* Example:
*
* <pre>
* Integer num = new ConsoleFieldScanner(Integer::parseInt, (Integer i) -> i > 0, null)
* .scan("Give me a number")
* </pre>
*
* Produces this output:
*
* <pre>
* Give me a number: <user inputs 123 and presses Enter>
* </pre>
*
* Leading to the variable <kbd>num</kbd> having the value <kbd>123</kbd>.
*
* @param <T> The type of the value being read
* @author Jonas Altrock (ew20b126@technikum-wien.at)
* @version 1
* @since ExerciseSheet04
*/
public class ConsoleFieldScanner<T> {
/**
* constant to allow readable indication of a skippable input
*/
public static final boolean SKIPPABLE = true;
/**
* constant to allow readable indication of a non-skippable input
*/
public static final boolean NOT_SKIPPABLE = false;
/**
* The default input scanner. Uses System.in if not set from outside.
*/
public static Scanner defaultScanner;
/**
* Whether the input can be skipped (by pressing Enter for example).
*/
public boolean skippable = SKIPPABLE;
/**
* The input to value transformer function.
*/
public Function<String, T> transformer;
/**
* The input value validator function.
*/
public Predicate<T> validator;
/**
* The scanner object in use.
*/
public Scanner scanner;We need a function that transforms the String input from the user into a value of the correct type (for example int), a function that validates if the value is allowed (in range), and a scanner which provides a way to ask the user for input.
/**
* Create a scanner for a single value. Skippable by default.
*
* @param transformer a function that transforms the input string to a value
* @param validator a function that validates the given value
* @param scanner optional Scanner to use, pass null to use the default scanner (System.in)
*/
public ConsoleFieldScanner(
Function<String, T> transformer,
Predicate<T> validator,
Scanner scanner
) {
this.transformer = transformer;
this.validator = validator;
if (scanner != null) {
this.scanner = scanner;
} else {
this.scanner = getDefaultScanner();
}
}
/**
* Create a scanner for a single value.
*
* @param transformer a function that transforms the input string to a value
* @param validator a function that validates the given value
* @param scanner optional Scanner to use, pass null to use the default scanner (System.in)
* @param skippable whether the user is allowed to skip entry by just pressing Enter
*/
public ConsoleFieldScanner(
Function<String, T> transformer,
Predicate<T> validator,
Scanner scanner,
boolean skippable
) {
this(transformer, validator, scanner);
this.skippable = skippable;
}
/**
* Initialise the default scanner object.
*
* @return the default scanner
*/
protected Scanner getDefaultScanner() {
if (defaultScanner == null) {
defaultScanner = new Scanner(System.in);
}
return defaultScanner;
}This is the generic method which asks the user for input, then
transforms the input into a value of type T, and then returns
this value if it is validated successfully.
/**
* Prompt the user for an input value.
*
* @param message string to print before prompt input
* @return a value or null, if no value was given
*/
public T scan(String message) {
T value;
do {
System.out.print(message + ": ");
try {
String in = scanner.nextLine();
if (skippable && in.isEmpty()) {
return null;
}
value = transformer.apply(in);
} catch (Exception e) {
value = null;
}
if (value == null) {
System.out.println("Invalid input, try again?");
continue;
}
if (!validator.test(value)) {
System.out.println("Value not allowed, try again?");
value = null;
}
} while (value == null);
return value;
}
}