Sorry for the poor title, i didn't know a better paraphrase..
Sooo i am currently writing a Grocery List program and i am stuck on my addItemsToList method. Basically i want it to have to 'exit' points. One of which will bring you back to the main menu of the application and one of which will bring you back to the context menu of that addItemsToList method.
Unfortunately i am completely stuck.
Here is my code for the method:
private static void addItemsToList(){
System.out.println("To which category do you want to add? ");
categoryInstructions();
int choice2 = scan.nextInt();
if(choice2 == 5){ // i am "getting out" here just fine
interact(); // this is the method that instructs everything to happen in the main method
}else {
System.out.println("What do you want to add? Type 'exit' for menu");
i = scan.next(); // this is where the second "exit" point is supposed to be if someone types "exit"
if (i.compareTo(exit) != 0) {
System.out.println("Please enter the quantity ");
int quant = scan.nextInt();
if (choice2 == 1) {
GrocerieList.foodstuffsList.add(i);
GrocerieList.foodstuffsAmount.add(quant);
} else if (choice2 == 2) {
GrocerieList.hygeneList.add(i);
GrocerieList.hygeneAmount.add(quant);
} else if (choice2 == 3) {
GrocerieList.drinkList.add(i);
GrocerieList.drinkAmount.add(quant);
} else if (choice2 == 4) {
GrocerieList.otherList.add(i);
GrocerieList.otherAmount.add(quant);
}
} else {
addItemsToList();
}
}
}
Just for a better understanding here is categoryInstructions():
public static void categoryInstructions(){
System.out.println("Press");
System.out.println(" ");
System.out.println("\t\t" + "(1)" + "\t--\t" + "for foodstuffs");
System.out.println("\t\t" + "(2)" + "\t--\t" + "for hygene");
System.out.println("\t\t" + "(3)" + "\t--\t" + "for drinks");
System.out.println("\t\t" + "(4)" + "\t--\t" + "for others");
System.out.println(" ");
System.out.println("\t\t" + "(5)" + "\t--\t" + "to get back main menu");
}
Now whats happening is that i can exit addItemsToList perfectly fine if choice2 == 5 but i cannot seem to find the logical solution fo exiting if i is equal to "exit". I got it to work quick and dirty with the application first asking for the quantity and then exiting but that isn't quite what i want.
Since i am (obviously) a beginner any other comments on my style or else would also be greatly appreciated!!
You could use a switch case for this purpose, a flag to know when to execute an elegant exit and a while loop to help you stay in the menu until a user provides the correct input.
For instance:
public class Controller {
private GroceriesController groceriesController;
private boolean isRunning; // our flag that will help us to quit the menu
public Controller(GroceriesController groceriesController) {
this.groceriesController = groceriesController;
}
public void run() {
isRunning = true;
while (isRunning) {
clearScreen();
displayLogo();
displayMainMenu();
handleMainMenu(); // method that will do all the job;
}
}
private void handleMainMenu() {
int userChoice = scanner.nextInt();
switch (userChoice) {
case 1:
groceriesController.handleGroceriesMenu();
break;
case 2:
returnItems();
break;
case 0:
isRunning = false; // exit from the menu
break;
default:
System.out.println("Invalid input");
break;
}
}
private void displayMainMenu() {
System.out.println("\n Grocery store:\n"
+ "[1] Buy stuff\n"
+ "[2] Return stuff\n"
+ "[0] Leave store");
}
}
public class GroceriesController {
private boolean isRunning; // same strategy as before
public void handleGroceriesMenu() {
isRunning = true;
while (isRunning) {
clearScreen();
displayLogo();
displayMenu();
handleMenu();
}
}
private void handleMenu() {
int userChoice = scanner.nextInt();
switch (userChoice) {
case 1:
addItemToCart(item);
System.out.println("The item: " + item + "has been added.");
break;
case 2:
removeItemFromCart(item);
System.out.println("The item: " + item + "has been removed.");
break;
case 0:
isRunning = false; // exit from the menu
break;
default:
System.out.println("Invalid input");
break;
}
}
private void displayMenu() {
System.out.println("\n Select:\n"
+ "[1] Buy item\n"
+ "[2] Put back\n"
+ "[0] Leave");
}
}
In this way, you can have multiple menus that are calling each other and at the end, the program finishes on its own, without wild return; or System.exit(0);
Edit: Added one more class for better insight.
Related
Instead of making it blank each time the user is finished with a case, I've added a println("Next command?>") in the runCommandLoop method as a cheap solution to my problem. But that also means when case "0" or "exit" is choosen, "Next command?>" is printed out one last time BEFORE shutting down.
Simply put I want it to prompt after every case except "0 shutdown".
Calling the startup method is another option as well I guess but that doesn't make much difference either.
private void startup() {
System.out.println("\nCommand?>\n" + "1: register new dog\n" + "2: increase age\n" + "3: list dogs\n"
+ "4: remove dog\n" + "0: exit\n");
}
private void runCommandLoop() {
boolean done;
do {
String command = readCommand();
done = handleCommand(command);
System.out.println("\nNext command?>");
} while (!done);
}
private String readCommand() {
String command = input.registerString();
return command;
}
private boolean handleCommand(String command) {
switch (command) {
case "1":
case "register new dog":
dogList.registerDog();
break;
case "2":
case "increase age":
dogList.increaseAge();
break;
case "3":
case "list dogs":
dogList.listDogs();
break;
case "4":
case "remove dog":
dogList.removeDog();
break;
case "0":
case "exit":
return true;
default:
printMenu();
}
return false;
}
private void printMenu() {
System.out.println("Error: wrong command\n" + "The available commands are:\n" + "1: register new dog\n"
+ "2: increase age\n" + "3: list dogs\n" + "4: remove dog\n" + "0: exit");
return;
}
private void closeDown() {
System.out.println("Shutting down...");
input.closeInput();
}
private void run() {
startup();
runCommandLoop();
closeDown();
}
public static void main(String[] args) {
Interface startup = new Interface();
startup.run();
}
In case you need to see what the dogList methods do (the arraylist variable name is just temporary):
public void registerDog() {
String name = input.registerStringLoop("Name");
String breed = input.registerStringLoop("Breed");
int weight = input.registerIntPrompt("Weight");
int age = input.registerIntPrompt("Age");
Dog dog = new Dog(name, breed, age, weight);
doggoList.add(dog);
System.out.println(dog.getName() + " has been added to the register.\n" + dog.toString());
}
public void listDogs() {
if (doggoList.size() == 0) {
System.out.println("Error: no dogs found");
} else {
System.out.print("Smallest tail length to display?>");
int smallestTailLength = input.registerInt();
sortDogs();
if (smallestTailLength == 0) {
System.out.println(doggoList);
} else
for (Dog s : doggoList) {
if (s.getTailLength() >= smallestTailLength)
System.out.println(s);
}
}
}
public void increaseAge() {
System.out.print("Enter the name of the dog?>");
String dogName = input.registerString();
for (Dog s : doggoList) {
if (s.getName().equalsIgnoreCase(dogName)) {
s.increaseAge();
sortDogs();
System.out.println(s.getName() + " is now " + s.getAge() + " years old.");
return;
}
}
Thanks in advance.
It should be as simple as
if (!done){
System.out.println("\nNext command?>");
}
My issue is that I can't seem to call the "RustySword" block from a "switch" in my main class. See below.
import java.util.Scanner;
public class Heart {
static int playerGold = 100;
static int oldHatPrice = 25;
static int canOfBeansPrice = 250;
static int rustySwordPrice = 125;
public static Scanner Economy = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Hi, Welcome to my store.\nWould you like to see my wares?");
String c = Economy.next();
switch (c) {
case "yes":
System.out.println("old hat: " + oldHatPrice +" gold\nRusty Sword: " + rustySwordPrice + " gold\nCan of beans: " + canOfBeansPrice + " gold");
String e =Economy.next();
switch (e) {
case "Rusty sword":
RustySword();
break;
default: System.out.println("I don't think you need that!");
}
}
}
public static void RustySword() {
System.out.println("Would you like to buy this rusty sword?\n Rusty sword: " + rustySwordPrice + "\n Your gold: " + playerGold);
String a = Economy.nextLine();
switch (a) {
case "yes":
if (playerGold >= rustySwordPrice) {
System.out.println("Here you go");
playerGold = playerGold - rustySwordPrice;
System.out.println("-Rusty Sword- added to inventory\n Gold remaining: " + playerGold);
}
else {
System.out.println("Sorry, you don't have enough gold!\ncome back when you have more.");}
break;
case "no":
System.out.println("Is there anything else I can do for you?");
String d = Economy.nextLine();
switch (d) {
case "no":
System.out.println("Thanks for shopping");
break;
}
break;
default: System.out.println("i'm not sure what your talking about!");
}
}
}
You are using next() to read the input that is reading only till space then the cursor is being placed in the same line after reading the input.
So the cursor will be at the end of the line \n if your input is only a single word e.g., yes in your case.
The end of the line will be consumed by following next() method. Hence your condition is not matching.
Use nextLine() to read the complete line and use it. You can look into this question
for more info.
Here is the method that performs the switch(Note The switch statement works correctly and according to the requirements)
public void performChecks() {
priceInput = priceReader.nextDouble();
loop: while(true){
nameInput = nameReader.nextLine();
switch(nameInput){
case "A1": Cola colaItem = new Cola();
if(colaItem.checkPrice(priceInput)){
System.out.println("You ordered " + colaItem.getName()+ ", here is it");
} else {
System.out.println("Sorry, the amount is not enough for this purchase. Please add more money and try again");
}
break loop;
case "B2": Chips chipsItem = new Chips();
if(chipsItem.checkPrice(priceInput)){
System.out.println("You ordered " + chipsItem.getName()+ ", here is it");
} else {
System.out.println("Sorry, the amount is not enough for this purchase. Please add more money and try again");
}
break loop;
case "C3": Crackers crackerItem = new Crackers();
if(crackerItem.checkPrice(priceInput)){
System.out.println("You ordered " + crackerItem.getName()+ ", here is it");
} else {
System.out.println("Sorry, the amount is not enough for this purchase. Please add more money and try again");
}
break loop;
default:
System.out.println("Sorry, we don't have item with such a code");
}
}
}
Now I started doing some refactoring and put the method in the super class of the items(Cola, Chips and Crackers) and it looks like this:
public void performChecks(){
inputPrice = priceReader.nextDouble();
inputCode = codeReader.nextLine();
initializeItems();
for(int i = 0; i < items.length; i++){
if(items[i].checkCode(inputCode)){
if(items[i].checkPrice(inputPrice)){
System.out.println("You ordered " + items[i].getName() + " here it is");
break;
} else {
System.out.println("Sorry, the amount is not enough for this purchase. Please add more money and try again");
break;
}
} else if(!items[i].checkCode(inputCode)){
continue;
} else {
System.out.println("Sorry, we don't have item with such a code");
inputCode = codeReader.nextLine();
}
}
}
The issue is the following: When I enter correct/incorrect price and incorrect item code, I should be getting the "Sorry, we don't have an item with such a code" message and the option to enter the item code again. I've ran out of ideas on how to implement this option inside the
else if(!items[i].checkCode(inputCode)){
continue;
Since I'm pretty sure, it just gets stuck there and returns nothing(for incorrect item code).
What you are trying to achieve can be solved with a simple "found" boolean. Like this:
boolean found = false;
for(Item item : items) {
if(item.checkCode(inputCode)){
found = true;
[...] // Here you found the item and you can check the price and other stuff
}
}
if(!found) {
[...] // Here you can handle the case of the incorrect code
}
I'm not absolutely sure, but I guess you can do sth like this:
inputCode = codeReader.nextLine();
do{
if(items[i].checkCode(inputCode)){
if(items[i].checkPrice(inputPrice)){
System.out.println("You ordered " + items[i].getName() + " here it is");
break;
} else {
System.out.println("Sorry, the amount is not enough for this purchase. Please add more money and try again");
break;
}
} else {
inputCode = codeReader.nextLine();
}
} while(!items[i].checkCode(inputCode));
I tried making a menu system to make a user select between four options. To distinguish between the selections I check the int entered. It works but somehow I feel it is not very elegant. Especially when I set the initial value of selectedMenu to 1902475424 to check for when the user entered a mismatcing value. I assumed the user wont accidentally type 1902475424.
Is there a way more simple way to make a menu system or will this do? Is this major flawed?
Yes im a beginner to Java :-)
import java.util.Scanner;
import java.util.InputMismatchException;
public class Menu {
public void printMenu() {
System.out.println(
"1. Start new game\n" +
"2. Load game\n" +
"3. Settings\n" +
"4. Exit\n"
);
}
public void selectMenu() throws InputMismatchException {
int selectedMenu = 1902475424;
Scanner aScanner = new Scanner(System.in);
do {
selectedMenu = 1902475424;
try {
System.out.println("Try block begin.");
selectedMenu = aScanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("Catch blok begin.");
System.out
.println("Invalid input, please input a number between 1-4.");
aScanner.nextLine();
}
if ((selectedMenu < 1 || selectedMenu > 4)
&& (selectedMenu != 1902475424)) {
System.out.println("Input out of range \"" + selectedMenu
+ "\". Input a number between 1-4.");
}
} while (selectedMenu == 1902475424
|| (selectedMenu < 1 || selectedMenu > 4));
if (selectedMenu >= 1 && selectedMenu <= 4) {
System.out.println("A new game will now start.");
}
}
}
Your method is leaning into the overkill category :]You can do away with your random value of 1902475424 like so:
public void selectMenu() throws InputMismatchException {
int selectedMenu;
Scanner aScanner = new Scanner(System.in);
do {
try {
System.out.println("Try block begin.");
selectedMenu = aScanner.nextInt();
if(selectedMenu < 1 || selectedMenu > 4) {
System.out.println("Input out of range \"" + selectedMenu + "\". Input..");
}
} catch(InputMismatchException e) {
System.out.println("Catch blok begin.");
System.out.println("Invalid input, please input a number between 1-4.");
aScanner.nextLine();
selectedMenu = 0;
}
} while(selectedMenu < 1 || selectedMenu > 4);
System.out.println("A new game will now start.");
}
Consider the following alternative (pseudocode):
int getMenuOption() {
print(message)
read(input)
if input is valid then return input
else then return getMenuOption()
}
This is recursive, so if the user sits there and enters bad numbers long enough, you could overflow the stack. You could easily augment this to give the user a fixed number of tries:
int getMenuOption(int triesRemaining) {
if (triesRemaining == 0) throw new RetriesExceededException();
print(message)
read(input)
if input is valid then return input
else then return getMenuOption(triesRemaining - 1)
}
Try something like that (I haven't tested it)
import java.util.Scanner;
import java.util.InputMismatchException;
public class Menu {
public void printMenu() {
System.out.println("1. Start new game\n" + "2. Load game\n"
+ "3. Settings\n" + "4. Exit\n");
}
public void selectMenu() throws InputMismatchException {
int selectedMenu;
boolean validSelection = false;
Scanner aScanner = new Scanner(System.in);
while(!validSelection) {
selectedMenu = aScanner.nextInt();
validSelection = true;
switch (selectedMenu) {
case 1:
// doWhen1();
break;
case 2:
// doWhen2();
break;
case 3:
// doWhen3();
break;
case 4:
// doWhen4();
break;
default:
System.out.println("Input out of range \"" + selectedMenu
+ "\". Input a number between 1-4.");
validSelection = false;
}
}
}
}
Here is a revision to the selectMenu() method you provided that should get the job done! I tested it out and it seems to work as expected. :)
public void selectMenu() {
int selectedMenuItem = 0;
Scanner aScanner = new Scanner(System.in);
while(selectedMenuItem == 0){
String userInputMenuItemString = aScanner.nextLine();
try {
int userInputMenuItem = Integer.parseInt(userInputMenuItemString);
if(userInputMenuItem > 0 && userInputMenuItem <= 4){
selectedMenuItem = userInputMenuItem;
}else{
System.out.println("No option #" + Integer.toString(userInputMenuItem) + " exists!\nTry again:");
}
} catch(NumberFormatException ex) {
System.out.println("Please input a number!");
}
}
switch(selectedMenuItem){
case 1:
System.out.println("You chose to start a new game!");
break;
case 2:
System.out.println("You chose to load a game!");
break;
case 3:
System.out.println("You chose to access settings!");
break;
case 4:
System.out.println("You chose to exit. Bye!");
System.exit(0);
break;
}
}
I'm using try on my code and it says illegal start of type. I'm using switch statements but default: continue; do not agree with each other I keep getting continue outside of loop. With the else statement it says illegal start type. So what can I do about try, continue, and the else statement.
public class Menu {
private Inventory database;
private char menuItem;
private Scanner input;
private char mode;
int code;
public Menu(Inventory database)
{
this.database = database;
menuItem = 'N';
input = new Scanner(System.in);
}
public Menu(MyArrayList database)
{
this.database = database;
menuItem = 'A';
input = new Scanner(System.in);
}
private void showMenu()
{
if(code == 'A'){
System.out.println();
System.out.println("------------------");
System.out.println("Display Movies : D");
System.out.println("Add Movie : A");
System.out.println("Delete Movie : X");
System.out.println("Select Mode : M");
System.out.println("Exit : E");
System.out.println("------------------");
System.out.println();
System.out.print("Please make your selection: ");
}
else
{
System.out.println();
System.out.println("------------------");
System.out.println("Display Movies : D");
System.out.println("Rent a Movie : R");
System.out.println("Reserve a Movie: S");
System.out.println("Select Mode : M");
System.out.println("Exit : E");
System.out.println("------------------");
System.out.println();
System.out.print("Please make your selection: ");
}
}
private void rentMovie(int productID)
{
int index = database.getIndex(productID);
if( index == -1)
{
System.out.println("There is not such a code.");
}
else
{
if( database.getMovie(index).getIsRented())
{
System.out.println("You cannot rent " + database.getMovie(index).getTitle() + ". It is already rented.");
}
else
{
database.getMovie(index).setIsRented(true);
System.out.println("Please take your movie.");
}
}
}
private void reserveMovie(int productID)
{
int index = database.getIndex(productID);
if( index == -1)
{
System.out.println("There is not such a code.");
}
else
{
if( database.getMovie(index).getIsReserved() )
{
System.out.println("You cannot reserve " + database.getMovie(index).getTitle() + ". It is already reserved.");
}
else
{
if( database.getMovie(index).getIsRented())
{
database.getMovie(index).setIsReserved(true);
System.out.println( database.getMovie(index).getTitle() + " is reserved for you." );
}
else
{
System.out.println( database.getMovie(index).getTitle() + " is available. You can rent it if you like.");
}
}
}
}
try{
if(mode == 'A'){
switch(menuItem){
case 'N':
break;
case 'D':
database.print();
showMenu();
menuItem = input.next().charAt(0);
break;
case 'A':
String title;
System.out.println("Enter movie title, then press enter");//movie title,
title= input.nextLine();
System.out.println("Enter movie code, then press enter");//enter movie code,then press enter
code = Integer.parseInt(input.nextLine());
addMovie(title,code);
menuItem ='N';
break;
case 'X':
System.out.println("");
deleteMovie(code);
menuItem ='N';
break;
case 'M':
selectMode();
menuItem = 'N';
case 'E':
System.out.print("Program terminated.");
System.exit(0);
break;
default:
continue;
}
}
}
else
{
public void run(){
int code;
while(true)
{
switch(menuItem)
{
case 'N':
break;
case 'D':
database.print();
showMenu();
menuItem = input.next().charAt(0);
break;
case 'R':
System.out.print("Please enter product code:");
rentMovie( input.nextInt() );
showMenu();
menuItem = input.next().charAt(0);
break;
case 'S':
System.out.print("Please enter product code:");
reserveMovie( input.nextInt() );
showMenu();
menuItem = input.next().charAt(0);
break;
case 'E':
System.out.print("Program terminated.");
System.exit(0);
break;
default :
showMenu();
menuItem = input.next().charAt(0);
}
}
}
}
You've got else following your try block, and that makes no sense. no, just bad indentation.
Where's your catch block, or finally block? It makes no sense to just have try. Also, you can't just declare a function in the middle of that else block.
Basically, I recommend you re-study the "Java Syntax" chapter of whatever guide you're using, because this code is just all kinds of wrong.
A.. Few pointers..
First of all, your Try doesn't have a catch.
Your case statements lack {} blocks.
And you can't create a method within an else block.
Further to answer your Question: Illegal start of type means you haven't initiated the variable. For example "menuItem"
Edit: To further that, default should be break; not continue;
Edit2: And further your second switch contains a boolean as argument...
With your edit, now showing the issue.
Your Try starts outside of a method body.
reserveMovie is closed just before try starts, and as such is not valid.