2 * Copyright (C) 2015 Roland Haeder
\r
4 * This program is free software: you can redistribute it and/or modify
\r
5 * it under the terms of the GNU General Public License as published by
\r
6 * the Free Software Foundation, either version 3 of the License, or
\r
7 * (at your option) any later version.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
14 * You should have received a copy of the GNU General Public License
\r
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
17 package org.mxchange.addressbook.client.console;
\r
19 import java.util.Arrays;
\r
20 import java.util.HashMap;
\r
21 import java.util.Map;
\r
22 import java.util.Scanner;
\r
23 import org.mxchange.addressbook.application.AddressbookApplication;
\r
24 import org.mxchange.addressbook.application.Application;
\r
25 import org.mxchange.addressbook.client.BaseClient;
\r
26 import org.mxchange.addressbook.client.Client;
\r
27 import org.mxchange.addressbook.menu.Menu;
\r
28 import org.mxchange.addressbook.menu.MenuTools;
\r
29 import org.mxchange.addressbook.menu.console.ConsoleMenu;
\r
30 import org.mxchange.addressbook.menu.item.SelectableMenuItem;
\r
31 import org.mxchange.addressbook.menu.item.console.ConsoleMenuItem;
\r
34 * A client for the console
\r
36 * @author Roland Haeder
\r
38 public class ConsoleClient extends BaseClient implements Client {
\r
42 private final Map<String, Menu> menus;
\r
45 * Scanner instance for reading data from console input
\r
47 private final Scanner scanner;
\r
50 * Parameterless constructor
\r
51 * @param application An instance of an Application class
\r
53 public ConsoleClient (final Application application) {
\r
56 // Set application instance
\r
57 this.setApplication(application);
\r
59 // Init contact manager here
\r
60 this.initContactManager(this);
\r
62 // Init scanner instance
\r
63 this.scanner = new Scanner(System.in);
\r
66 this.menus = new HashMap<>(10);
\r
69 this.fillConsoleMenuMap();
\r
73 * Displays textural message to the user
\r
77 public void displayMessage (final String message) {
\r
78 System.out.println(message);
\r
82 public void doUserChoice () throws Exception {
\r
83 // Get all access keys from menu
\r
84 char[] accessKeys = MenuTools.getAccessKeysFromMenuMap(this.menus, this.getCurrentMenu());
\r
86 // Output textural message and ask for a char as input
\r
87 char choice = this.enterChar(accessKeys, "Bitte Auswahl eingeben (0=Beenden/Zurück in's vorherhige Menü): ");
\r
89 // @TODO Rewrite this ugly switch() block
\r
91 case '1': // Enter/add own data
\r
92 this.getContactManager().enterOwnData();
\r
95 case '2': // Change own data
\r
96 this.getContactManager().changeOwnData();
\r
99 case '3': // Add new addess
\r
100 this.getContactManager().addOtherAddress();
\r
103 case '4': // Change other addess
\r
104 this.getContactManager().changeOtherAddress();
\r
107 case '5': // Delete other address
\r
108 this.getContactManager().deleteOtherAddress();
\r
111 case '0': // Program exit
\r
112 this.disableIsRunning();
\r
116 // @TODO throw on exception
\r
117 throw new Exception("choice " + choice + " invalid");
\r
122 * Asks the the user to enter a single character which must match validChars
\r
123 * @param validChars Valid chars that are accepted
\r
124 * @param message Message to user
\r
125 * @return Allowed character
\r
128 public char enterChar (final char[] validChars, final String message) {
\r
131 // Sort array, else binarySearch() won't work
\r
132 Arrays.sort(validChars);
\r
134 // Keep asking until valid char has been entered
\r
135 while (Arrays.binarySearch(validChars, input) < 0) {
\r
137 System.out.print(message);
\r
140 input = this.readChar();
\r
143 // Return read char
\r
148 * Reads a string of minimum and maximum length from the user
\r
149 * @param minLength Minimum length of the string to read
\r
150 * @param maxLength Maximum length of the string to read
\r
151 * @param message Message to user
\r
155 public String enterString (final int minLength, final int maxLength, final String message) {
\r
157 String input = null;
\r
159 // Check if it is to short or to long
\r
160 while ((input == null) || (input.length() < minLength) || (input.length() > maxLength)) {
\r
162 System.out.print(message);
\r
165 input = this.readString();
\r
173 * Returns a console menu item
\r
175 * @param accessKey Key to access the menu
\r
176 * @param text Text to show to user
\r
177 * @return A SelectableMenuItem
\r
178 * @todo Make sure the access key is unique
\r
181 public SelectableMenuItem getMenuItem (final char accessKey, final String text) {
\r
182 // Return a new console menu item
\r
183 return new ConsoleMenuItem(accessKey,text);
\r
187 * Shows textural menu on console
\r
190 public void showCurrentMenu () {
\r
191 this.showMenu(this.getCurrentMenu());
\r
195 public void showEntry (final SelectableMenuItem item) {
\r
196 // Access key then text
\r
197 this.displayMessage("[" + item.getAccessKey() + "] " + item.getText());
\r
201 * Shows a textural message to the user
\r
204 public void showWelcome () {
\r
205 this.displayMessage("Welcome to " + AddressbookApplication.APP_TITLE + " v" + AddressbookApplication.APP_VERSION);
\r
206 this.displayMessage("");
\r
207 this.displayMessage("Copyright(c) 2015 by Roland Haeder, this is free software");
\r
210 this.getLogger().debug("Intro shown to user");
\r
214 * Fills menu map with menu entries
\r
216 private void fillConsoleMenuMap () {
\r
217 // Initialize first (main) menu
\r
218 Menu menu = new ConsoleMenu("main", this);
\r
221 this.menus.put("main", menu);
\r
225 * "Getter" for given menu type
\r
227 * @param menuType Menu type instance to return
\r
228 * @return Menu or null if not found
\r
230 private Menu getMenu (final String menuType) {
\r
231 // Default is not found
\r
235 if (this.menus.containsKey(menuType)) {
\r
237 menu = this.menus.get(menuType);
\r
245 * Reads one character
\r
248 private char readChar () {
\r
250 String input = this.scanner.nextLine();
\r
252 // This must be only one character
\r
253 if (input.length() != 1) {
\r
258 // Get char from first (and only) position
\r
259 return input.charAt(0);
\r
263 * Reads a string from a scanner until RETURN is pressed
\r
265 * @return Read string from scanner
\r
267 private String readString () {
\r
268 return this.scanner.nextLine();
\r
274 * @param menuType Given menu to show
\r
276 private void showMenu (final String menuType) {
\r
277 Menu menu = this.getMenu(menuType);
\r
279 // Is the menu set?
\r
280 if (!(menu instanceof Menu)) {
\r
282 // @todo Own exception?
\r
283 throw new NullPointerException("Menu '" + menuType + "' not found.");
\r