Skip to content

Instantly share code, notes, and snippets.

@Superpat
Last active July 22, 2023 13:20
Show Gist options
  • Save Superpat/619aa7033e416796876e to your computer and use it in GitHub Desktop.
Save Superpat/619aa7033e416796876e to your computer and use it in GitHub Desktop.
A small java command line api to generate a menu that can return a generic
import java.util.List;
import java.util.Optional;
import java.util.Scanner;
/** Menu api for the command line
* <p>
* Takes a list of options containing a value and a menu title, when called, the menu returns an optional type containing the option.
* </p>
* @author Patrick Marchand <mail@patrickmarchand.com>
* @version 0.2
* @since 2015-11-18
*/
public class Menu<T> {
/** Title of the menu */
private final String title;
/** Optional description of the menu */
private final Optional<String> description;
/** Collection containing all possible actions */
private final List<Option<T>> options;
/**
* @param title Title of the menu
* @param options A list of all possible options
*/
public Menu(
final String title,
final List<Option<T>> options
) {
this.title = title;
this.description = Optional.empty();
this.options = options;
}
/**
* @param title Title of the menu
* @param description Description of the menu
* @param options A list of all possible options
*/
public Menu (
final String title,
final String description,
final List<Option<T>> options
) {
this.title = title;
this.description = Optional.of(description);
this.options = options;
}
/** @return Title of the menu */
public String getTitle() {
return this.title;
}
/** @return Description of the menu */
public Optional<String> getDescription() {
return this.description;
}
/** @return List of the options */
public List<Option<T>> getOptions() {
return this.options;
}
/** Prints the menu to standard output and captures the users choice
* @return A callable action
*/
public T spawnMenu() {
final Scanner sc = new Scanner(System.in);
int choice = 0;
System.out.println('\n' + this.title);
this.description.ifPresent(s -> System.out.println(s));
do {
for (int i = 0; i < this.options.size(); i++) {
System.out.println((i + 1) + " - " + this.options.get(i).getText());
}
if (sc.hasNextInt())
choice = sc.nextInt();
if (choice > 0 && (choice - 1) < this.options.size())
return this.options.get(choice - 1).getOption();
else
System.out.println("Ce choix n'est pas valide");
} while (true);
}
/** Prints the menu to standard output and captures the users choice
* @param exitOption The string used for the exit menu item
* @return A callable action
*/
public Optional<T> spawnMenuWithExit(String exitOption) {
final Scanner sc = new Scanner(System.in);
int choice = 0;
System.out.println('\n' + this.title);
this.description.ifPresent(s -> System.out.println(s));
System.out.println();
do {
System.out.println("0 - " + exitOption);
for (int i = 0; i < this.options.size(); i++) {
System.out.println((i + 1) + " - " + this.options.get(i).getText());
}
if (sc.hasNextInt())
choice = sc.nextInt();
if (choice > 0 && (choice - 1) < this.options.size())
return Optional.of(this.options.get(choice - 1).getOption());
else if (choice != 0)
System.out.println("Ce choix n'est pas valide");
else
return Optional.empty();
} while (true);
}
/** A prompt that takes input from standard input
* @param question A question presented to the user
* @return A string answer
*/
public static String prompt(String question) {
final Scanner sc = new Scanner(System.in);
String input = "";
do {
System.out.println();
System.out.println(question);
input = sc.nextLine();
} while (input == "");
return input;
}
/** A prompt that takes input from standard input
* @param question A question presented to the user
* @return An integer answer
*/
public static int promptInt(String question, int min, int max) {
final Scanner sc = new Scanner(System.in);
int input = 0;
do {
System.out.println();
System.out.println(question);
if (sc.hasNextInt())
input = sc.nextInt();
} while (input < min || input > max);
return input;
}
/** A prompt that takes input from standard input
* @param question A question presented to the user
* @return A double
*/
public static double promptDouble(String question, double min, double max) {
final Scanner sc = new Scanner(System.in);
double input = 0;
do {
System.out.println();
System.out.println(question);
if (sc.hasNextDouble())
input = sc.nextDouble();
} while (input < min || input > max);
return input;
}
}
@maxbechtold
Copy link

Only works for me if I move the scanner forward in case of invalid characters:

if (!scanner.hasNextInt()) {
    scanner.next()
    continue
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment