Java menu in console

Console application menu

But I believe that it is not the best choice. I believe that I should use any pattern to improve my code. By description — the state pattern is applicable for my situation but I have no idea how I can use this in this situation. The menu should show the respective menu according to the internal state.

2 Answers 2

First of all, there are at least three buggy things:

  • select variable is declared inside the do. while loop, so the condition in while is checked against another one (probably, a field in the class?). So, the loop won’t work as expected!
  • copy-paste is evil. The calls fileHolder.create(«image»); are repeated in two different conditionals. The «txt» option is not used. Please pay more attention to the things you write and do not copy-paste such elementary things.
  • the Scanner is not closed after its usage, which is desirable, as for any other items that use I/O.

For the rest, the code seems quite straightforward, rigid and repetitive, hence difficult to maintain. It contains many if — else if clauses that smell bad.

Of course, the whole story may be refactored with patterns usage. But I don’t think that the state pattern suits well here. It’d be better refactored with the command pattern.

All the menu actions (create, remove, rename and their dependent ones) may be wrapped into separate objects, which associate the expected keys (1,2,3..), the text and other necessary stuff and sugar.

For example, a (very short) version of Menu class could be like this:

class Menu < private final String action; private final Consumerconsumer; Menu(String action, Consumer consumer) < this.action = action; this.consumer = consumer; >void execute() < this.consumer.accept(action); >> 

And it would be initialized and used:

Menu create = new Menu("create", (a) -> fileHolder.create(a)); // to trigger the execution: create.execute(); 

But for this very concrete and short example of code I would consider decomposing it into patterns as a sort of overkill.

There is some job to do about the original straightforward approach, so let’s just try to improve it.

The input numbers are read several times using the Scanner object. They should also be validated, so a dedicated method would be very useful:

// int minValue may also be defined if necessary private static int askUserForNumberInput(Scanner scanner, String prompt, int maxValue) < System.out.println("please select menu item"); System.out.println(prompt); int value = scanner.nextInt(); while (value < 1 || value >maxValue) < System.out.println("invalid menu item, please try again"); // java.util.InputMismatchException should also be caught // to intercept non-numeric input value = scanner.nextInt(); >return value; > 

The frame for the main logic would look like this:

try (Scanner scanner = new Scanner(System.in)) < final int mainMenuSelection = askUserForNumberInput(scanner, "1-create, 2-remove, 3 - rename", 3); switch (mainMenuSelection) < // cases >> 

And there is not a single if — if else in the cases any more:

case 1: < String[] createActions = < "image", "txt" >; // to be extracted to constants int createOption = askUserForNumberInput(scanner, "1-image, 2-txt", 2); fileHolder.create(createActions[createOption - 1]); break; > case 2: < int removeIndex = askUserForNumberInput(scanner, "1-file from pc1, 2-file from pc2, 3-file from pc3", 3); fileHolder.removeFile("pc" + removeIndex); break; >case 3:

There is a lot of repetition in your code which is always a sure sign that some methods or classes should be introduced. It seems that you did understand that already.

I like your idea of using the state pattern. I made an implementation below where the state (the active menu) is kept in the variable menu of App . There can be a tree of sub-menus.

import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Scanner; public class Menu < private final String name; private final String text; private LinkedHashMapactionsMap = new LinkedHashMap<>(); public Menu(String name, String text) < this.name = name; this.text = text; >public void putAction(String name, Runnable action) < actionsMap.put(name, action); >public String generateText() < StringBuilder sb = new StringBuilder(); sb.append(name).append(": "); sb.append(text).append(":\n"); ListactionNames = new ArrayList<>(actionsMap.keySet()); for (int i = 0; i < actionNames.size(); i++) < sb.append(String.format(" %d: %s%n", i + 1, actionNames.get(i))); >return sb.toString(); > public void executeAction(int actionNumber) < int effectiveActionNumber = actionNumber - 1; if (effectiveActionNumber < 0 || effectiveActionNumber >= actionsMap.size()) < System.out.println("Ignoring menu choice: " + actionNumber); >else < Listactions = new ArrayList<>(actionsMap.values()); actions.get(effectiveActionNumber).run(); > > public static class App < private Menu menu; private String password = "blahblah"; public App() < Menu mainMenu = new Menu("Main", "main menu"); Menu subMenuGetPassword = new Menu("Password", "get passwords"); Menu subMenuSetPassword = new Menu("Set Password", "set password"); mainMenu.putAction("get password menu", () ->activateMenu(subMenuGetPassword)); mainMenu.putAction("quit", () -> System.exit(0)); subMenuGetPassword.putAction("get password", () -> System.out.println(password)); subMenuGetPassword.putAction("set password menu", () -> activateMenu(subMenuSetPassword)); subMenuGetPassword.putAction("main menu", () -> activateMenu(mainMenu)); subMenuGetPassword.putAction("quit", () -> System.exit(0)); subMenuSetPassword.putAction("get password", this::setPassword); subMenuSetPassword.putAction("step back menu", () -> activateMenu(subMenuGetPassword)); subMenuSetPassword.putAction("main menu", () -> activateMenu(mainMenu)); subMenuSetPassword.putAction("quit", () -> System.exit(0)); activateMenu(mainMenu); > private void activateMenu(Menu newMenu) < menu = newMenu; System.out.println(newMenu.generateText()); Scanner scanner = new Scanner(System.in); while (true) < // TODO some error checking. int actionNumber = scanner.nextInt(); menu.executeAction(actionNumber); >> private void setPassword() < // TODO ask for password on command lin eand set it password = "p2"; >> public static void main(String[] args) < new App(); >> 

Источник

Читайте также:  Java jcombobox add items

Технические заметки

Часто во время разработки нужно сделать консольное меню. Это может быть утилита для пользы проекта, проверка какого-нибудь концепта или свой небольшой проект по ознакомлению с новой технологией. И вот когда я в 10-ый раз начал писать меню, я остановился и задумался: а может просто вынести это всё в библиотеку, да и пусть валяется в локальном репозитории maven’а? Сказано — сделано.

Реализация

Основа меню — это абстрактный класс MenuEntry. У него есть единственное поле title, а также абстрактный метод run.

public abstract class MenuEntry < private String title; public MenuEntry(String title) < this.title = title; >public abstract void run(); >

Это позволит нам описать, что должно произойти при выборе этого пункта меню, не заморачиваясь на создании новых классов, как это происходит при разработке с паттерном Команда (Command). Например, вот так:

Теперь нужен только какой-нибудь контейнер, который будет в хранить все пункты меню и выводить их в бесконечном цикле. Этим будет заниматься класс Menu. В качестве дополнения, он будет автоматически создавать пункт меню Exit и добавлять его в конец списка.

public class Menu < private Listentries = new ArrayList(); private boolean isExit = false; public Menu() < // Добавляем пункт меню Exit entries.add(new MenuEntry("Exit") < @Override public void run() < isExit = true; >>); > public void run() < // Бесконечный цикл, пока не нажали кнопку выход BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); while (!isExit) < printMenu(); try < String line = reader.readLine(); int choice = Integer.parseInt(line); // Выбираем нажатый пункт меню и выполняем его код MenuEntry entry = entries.get(choice - 1); entry.run(); >catch (IOException e) < e.printStackTrace(); >> > > 
Menu menu = new Menu(); menu.addEntry(new MenuEntry("test1") < @Override public void run() < System.out.println("test1 run"); >>); menu.addEntry(new MenuEntry("test2") < @Override public void run() < System.out.println("test2 run"); >>); menu.run();

Источник

How to create a Java Console Menu Application?

A Java Console Menu Application is a great way to start learning programming. With a menu console application, you can easily test your code and see results after giving certain inputs.

In this post, I’ll show how to create a Java console menu application.

To create a menu for a Java console application, I recommend you the following:

  • show the menu options within an infinite loop
  • get input from the user on what option he/she wants to execute
  • use conditional statements to perform an action depending on the user input.

Table of Contents

Printing the menu in the Java console app

The first step for us to create a menu is to print the options on the screen.

To do that, we need to know what are the options that are available on our menu.

One can do this in several ways. In this case, I will use a string array to store all the options. Notice that each string has a respective number at the beginning.

We will use this number later to know what action to execute.

public class Main < public static void printMenu(String[] options)< for (String option : options)< System.out.println(option); >System.out.print("Choose your option : "); > public static void main(String[] args) < String[] options = ; Scanner scanner = new Scanner(System.in); int option; while (true) < printMenu(options); option = scanner.nextInt(); >> >
  • the array of options, to store the options we want to print on the screen.
  • a method that prints all the options.
  • an infinity loop that prints the menu at the beginning of the console app execution, and after the user choose an option and the respective action is carried on.
Читайте также:  Https php как использовать

This design model the way the menu console application works. A user enters an option using the keyboard, an action is executed according to the option and the user is asked for another option. If the option is to exit, then the computer finishes the execution of the console application.

Add exception handling

A simple Java console menu is not the “exception” when it comes to creating robust software.

By robust software we mean an application that can recover from errors and that won’t crash.

To create a robust java console menu we should use exception handling. If you want to read more about exception handling in Java, you can read this post. The post offers a wide view of exception handling and has several examples.

public class Main < public static void printMenu(String[] options)< for (String option : options)< System.out.println(option); >System.out.print("Choose your option : "); > public static void main(String[] args) < String[] options = ; Scanner scanner = new Scanner(System.in); int option = 1; while (option!=4) < printMenu(options); try < option = scanner.nextInt(); >catch (InputMismatchException ex) < System.out.println("Please enter an integer value between 1 and " + options.length); scanner.next(); >catch (Exception ex) < System.out.println("An unexpected error happened. Please try again"); scanner.next(); >> > >

Implementing actions for each option of the console menu

After printing the menu, asking the user for an option, and handling possible errors, it is time to act depending on the user input.

package com.RP; import java.util.Scanner; import static java.lang.System.exit; public class Main < public static void printMenu(String[] options)< for (String option : options)< System.out.println(option); >System.out.print("Choose your option : "); > public static void main(String[] args) < String[] options = ; Scanner scanner = new Scanner(System.in); int option = 1; while (option!=4) < printMenu(options); try < option = scanner.nextInt(); switch (option)< case 1: option1(); break; case 2: option2(); break; case 3: option3(); break; case 4: exit(0); >> catch (Exception ex) < System.out.println("Please enter an integer value between 1 and " + options.length); scanner.next(); >> > // Options private static void option1() < System.out.println("Thanks for choosing option 1"); >private static void option2() < System.out.println("Thanks for choosing option 2"); >private static void option3() < System.out.println("Thanks for choosing option 3"); >>

From the code above, you will see the use of a switch statement (a conditional statement). You can also use an if statement if you prefer. It will work just in the same way.

Also, we implemented one new method per each option. Within this method, you can write the code you want to execute when the user chooses a specific option.

If you add more options to your menu, just add more cases to the switch statement (case 5, case 5 and so on) and implement one method per each option.

Example of Java console menu for simple calculations

In this example, we want to give the possibility to the user to enter two numbers and then decide what to do with them from two options, sum or multiply them.

package com.RP; import java.util.Scanner; import static java.lang.System.exit; public class JavaConsoleMenuExample < public static void printMenu(String[] options)< for (String option : options)< System.out.println(option); >System.out.print("Choose your option : "); > private static String[] options = ; public static void main(String[] args) < Scanner scanner = new Scanner(System.in); System.out.print("Enter the first numnber: "); int number1 = scanner.nextInt(); System.out.print("Enter the second numnber: "); int number2 = scanner.nextInt(); int option = 1; while (option!=4)< printMenu(options); try < option = scanner.nextInt(); switch (option)< case 1: sum(number1, number2); break; case 2: multiply(number1, number2); break; case 3: exit(0); >> catch (Exception ex) < System.out.println("Please enter an integer value between 1 and " + options.length); scanner.next(); >> > // Options private static void sum(int number1, int number2) < int result = number1 + number2; System.out.println("The sum is " + result); >private static void multiply(int number1, int number2) < int result = number1 * number2; System.out.println("The result is " + result); >>

For you to keep practising, you can add exception handling to the input of the two numbers. If the user enters a string instead of a number, the app will crash.

See below an output example of the previous code.

Java console menu application output example

Java console menu application output example

Summary

To create a Java Console Menu, we use the following:

  • String array to store the options available
  • Infinite loop to print the menu until the user chooses to exit the console application
  • A switch statement to identify the option the user wants to execute
  • A method per option so our code is cleaner and easier to maintain
Читайте также:  Php find var in array

Leave a comment below.

Источник

how to create a simple console menu java tut

when you first learn java you start with console applications, outputting text and getting simple user input. alot of java console based applications have a text menu where the user can chose options.

in this tutorial you will learn how to make a reusable console menu class.

if you really want to learn java take this course(the first part is free):

if you would like heres a video version of this lesson:

in this tutorial i will show you how to create a simple java console menu.

for this tut we will use the eclipse ide, i assume that that is the ide you are using.

this is how the final product will look like in the java console:

first thing in eclipse create a new java project and call it somthing like console menu (the name dosnt matter).

after that create a package and call it helper(right click project src):

right click on the helpers package and add a new class called S:

copy this code to the S class :

package helpers; public class S < public static void o(Object s) < System.out.println(s); >>

this is the code from this tutorial.

create a package called main and create a main class:

create a package called console and create a class called console_menu .

this is the code for console_menu :

package console; import java.util.Scanner; import helpers.S; public class console_menu < public boolean is_running; public String[] menu_items; public console_menu() < is_running = true; menu_items = new String[]; >//end constructor public void run() < while(is_running) < menu_show() ; menu_user_input(); >> public void menu_show() < int i=1;//iterator //foreach menu_items for(String item :menu_items) < S.o(i+") "+item); i++; >>//end menu_show public void menu_user_input() < //get user input Scanner user_input = new Scanner( System.in ); String next = user_input.next(); //if user entered 1 if(next.equals("1")) < S.o("you chose show all \n"); >//if user entered 2 etc etc if(next.equals("2")) < S.o("you chose add \n"); >if(next.equals("3")) < S.o("you chose edit \n"); >//exit program if user writes exit if(next.equals("exit")) < S.o("program ended"); is_running = false; >>//end menu_user_input >

at the top of the class we declare two attributes a boolean and a string array:

public class console_menu < public boolean is_running; public String[] menu_items;

the string array will hold all the menu items and the is running boolean will determine if the program will keep on running.

in the class constructor we set is running to true and instantiate the menu_items array and give it some elements:

public console_menu() < is_running = true; menu_items = new String[]; >//end constructor

the run method is what runs the console menu program:

basically what it dose is while is_runing is true show the menu and wait for user input.

what menu show method dose is to loop the menu item array and show them numbered:

public void menu_show() < int i=1;//iterator //foreach menu_items for(String item :menu_items) < S.o(i+") "+item); i++; >>//end menu_show

the loop is a foreach loop. for each menu items it outputs the current i value and the current string item.after that it increments i .

the menu_user_input method uses a scanner object to get the user input and after that it determines using ifs what to output to the user:

public void menu_user_input() < //get user input Scanner user_input = new Scanner( System.in ); String next = user_input.next(); //if user entered 1 if(next.equals("1")) < S.o("you chose show all \n"); >//if user entered 2 etc etc if(next.equals("2")) < S.o("you chose add \n"); >if(next.equals("3")) < S.o("you chose edit \n"); >//exit program if user writes exit if(next.equals("exit")) < S.o("program ended"); is_running = false; >>//end menu_user_input

if the user writes exit the is_running boolean is set to false and the loop inside run stops.

finally we go to the main class in main package and create a console menu object and run it using the run method we created:

package main; import console.console_menu; import helpers.S; public class ymain < public static void main(String[] args) < //S.o("test"); console_menu cm = new console_menu(); cm.run(); >>

Источник

Оцените статью