0

I am writing a simple 'shopping basket' program in Java, having not used it much at all in the last 10 years, I'm just trying to get familiar with it again...

My program currently has 3 classes: Program.java, Basket.java & Item.java.

Program.java is defined with:

public class Program {

    public static int menuSelection = 0;
    public static Scanner kb = new Scanner(System.in);
    public static Basket basket = new Basket();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //Program p = new Program();
        menu();
    }

    public static void menu() {
        System.out.println("Press 1 to add an item to the basket. ");
        System.out.println("Press 2 to remove an item from the basket. ");
        System.out.println("Press 3 to display the basket contents. ");
        System.out.println("Press 9 to proceed to checkout. ");
        System.out.println("Press 0 to exit program");
        menuSelection = kb.nextInt();
    
        if(menuSelection == 1) {
            basket.addItemToBasket();
        } else if(menuSelection == 2) {
            basket.removeItemFromBasket();
        } else if (menuSelection == 3) {
            basket.displayBasket();
        } else if(menuSelection == 9) {
            System.out.println("Proceed to checkout");
        } else if(menuSelection == 0) {
            System.exit(0);
        }
    }

}

Basket.java is defined with:

public class Basket {

    public ArrayList<Item> basket = new ArrayList<Item>();
    public Scanner kb = new Scanner(System.in);
    public Item item = new Item();
    public Program prog = new Program();

    public void addItemToBasket() {
        System.out.println("Enter the name of the item: ");
        item.name = kb.nextLine();
        System.out.println("Enter the price of the item: ");
        item.price = kb.nextDouble();
        basket.add(item);
        item.name = null;
        item.price = 0;
        Program.menu();
    }

    public void removeItemFromBasket() {
        System.out.println("Which item would you like to remove? ");
        item.name = kb.nextLine();
        if(basket.contains(item.name) ) {
            basket.remove(item);
        } else {
            System.out.printf("There is no %s currently in the basket! ", item.name);
        }
    }

    public String displayBasket() {
        return basket.toString();
    }



}

At the moment, if I run the program, the menu is displayed in the console, and when I select '1', the addItemToBasket() method is called, I enter the name at the first prompt & price at the second prompt, and the menu is then displayed again.

However, at this point, if I then select '1' again, to add another item to the basket, the first & second prompts are displayed together... i.e. instead of:

Enter the name of the item:

// Wait for user input

Enter the price of the item:

// Wait for user input

it shows:

Enter the name of the item:

Enter the price of the item:

and if I try to type anything other than numbers, the program crashes because it's expecting a double value...

What am I doing wrong? Why does the addItemToBasket() method skip the item.name = kb.nextLine(); line the second & subsequent times it's called?

Community
  • 1
  • 1
Noble-Surfer
  • 2,542
  • 9
  • 59
  • 103
  • see http://stackoverflow.com/questions/13102045/scanner-is-skipping-nextline-after-using-next-nextint-or-other-nextfoo – Scary Wombat Jul 03 '18 at 07:45
  • 1
    Don't create a `new Program` is Basket class it has not a real sense, but make a loop in Program class – azro Jul 03 '18 at 07:45
  • Perhaps something to do with https://stackoverflow.com/questions/13102045/scanner-is-skipping-nextline-after-using-next-or-nextfoo – achAmháin Jul 03 '18 at 07:45

2 Answers2

4

I've seen this before from a student of mine. The problem is you are creating two different scanners from the same input. This means each scanner is reading the same set of input. Try passing around just one scanner for reading and I bet your program will start behaving again.

Here's a more detailed explanation. Program creates Scanner called kb and reads in the next integer for which you input 1. Then Basket's instance of kb reads the entire line. It feels like it skips this read, but its actually reading from the start of the stream. If you printed item.name you'd see a 1. Now it asks you for a price. You enter a number which is read just fine and return to the main menu. However, the main menu which last read 1 still has all the other input you entered for Basket to read through. This is why it gets mad about expecting a double and receiving invalid characters.

Spidy
  • 38,131
  • 15
  • 59
  • 77
0

As @Spidy pined point, it has to do with your input stream. Look at this, 2 scanners share the same input stream:

new Scanner(System.in);

So when you do nextLine(), it is expecting for a new line input. Quick fix will be instead of nextLine(), use next() only.

P/S: Check comment from @azro, you have unused code in Basket class.

Xitrum
  • 6,893
  • 21
  • 78
  • 115