I'm trying to create a console based Menu class. I want the class to contain an array (named options) of MenuOption objects which each have a label (String), text (String), and code (TBD) property. The idea is that I want users to input a string and the menu will execute the relevant code with something close to the following:
for (MenuOption option: options)
{
if (input.equals(option.label)) execute option.code;
}
I feel like theres probably a way to do this using lambda functions, but I've been hitting dead ends for the last couple of hours. Any suggestions are appreciated.
CodePudding user response:
This is the classic Java 8 version, fully implemented.
package stackoverflow;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Objects;
public class ConsoleMenu {
static public class MenuOption {
public final String label;
public final String text;
public final Runnable code;
public MenuOption(final String pLabel, final String pText, final Runnable pLambda) {
label = pLabel;
text = pText;
code = pLambda;
}
}
public static void main(final String[] args) throws IOException {
final ArrayList<MenuOption> options = new ArrayList<>();
options.add(new MenuOption("Option A", "A", () -> System.out.println("Hello this is A")));
options.add(new MenuOption("Option B", "B", () -> {
System.out.print("Hello this is B");
System.out.println(" in multiple lines Lambda");
}));
System.out.println(" - - - Menu - - - ");
for (final MenuOption mo : options) {
System.out.println("\t" mo.label "\t" mo.text);
}
System.out.println("Enter your choice:");
try (final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));) {
final String line = br.readLine().toLowerCase();
for (final MenuOption mo : options) {
if (Objects.equals(line, mo.text.toLowerCase())) {
System.out.println("You chose " mo.label);
mo.code.run();
break;
}
}
}
System.out.println("All done.");
}
}
CodePudding user response:
You’re on the right track. Try something like:
public record MenuOption(String label,
String text,
Runnable action) {
// Deliberately empty.
}
You can, as you suspected, construct them with lambdas:
MenuOption printOption = new MenuOption(
"Print",
"Send formatted data to a printer",
() -> printData());
MenuOption exitOption = new MenuOption(
"Exit",
"Close application",
() -> System.exit(0));
If you’re stuck with an older version of Java, you can just make a regular class which is equivalent to a record:
public class MenuOption {
private String label;
private String text;
private Runnable action;
public MenuOption(String label,
String text,
Runnable action) {
this.label = label;
this.text = text;
this.action = action;
}
public String getLabel() {
return label;
}
public String getText() {
return text;
}
public Runnable getAction() {
return action;
}
}